JavaScript submit()
332 days ago
Sometimes I find that the JavaScript submit() function simply won't work. It turns out to have a very simple explanation (99% of the time). If you have named your submit button "submit", then you have a conflict, because "submit" now refers to the button, not to the function. You get the JavaScript error "Submit is not a function."
To fix, simply change the name attribute of your submit button to something other than submit.
Templating Engines in PHP
439 days ago
Let me state clearly, up front, that this is a rant. I have had to use a number of different templating engines on various projects. Smarty, the de facto templating language for PHP, was being used on a couple of the projects. And currently I’m using SilverStripe which has it’s own templating language built in. These two are perfect examples to reference in this rant as they are polar opposites. Smarty follows the “everything but the kitchen sink” approach, and SilverStripe’s is about as bare-bones as you can get. Neither extreme presents a useful solution for end users, as I’ll explain below.
To get right to the point, PHP is a templating language. Yes, there is much more t it than that, but it comes with the ability to mix useful code right into your HTML. So, adding a templating engine on top of that is completely redundant. If you already know how to write PHP, then you already know a templating language. If you don’t know how to write PHP, then is it any more of a stretch to learn a smattering of PHP, something you could apply in many coding circumstances, than to learn the syntax of the templating language? Additionally, you have the overhead of double parsing everything. The templating language has to parse the markup you wrote and turn it into PHP, which in turn is sent to the PHP engine (Zend) to, you guessed it, re-parse. Why not just parse it once and be done with it?
My friend John pointed out that a templating engine is a tool that you can have in your tool box, not right for every situation, but not wrong by default. I have to agree with that. I haven’t come across a good situation personally, but I can imagine a situation where the language you are using is too obscure for designers to make sense of, so it simply wouldn’t make sense to work in it directly alongside the HTML. In which case, an intermediate layer allowing the designer to work with something simple and focused, which gets translated for them into the more obscure language, would be helpful. Or, if you needed a template which could be designed once and parsed by several different languages for presentation (not a real-life situation that I’m aware of), then a generic template language would make sense.
However, this rant specifically concerns coding in PHP, a very approachable language that works alongside HTML just fine. In that specific case, I have found no good use for a templating language.
Let’s get into some code. We’ll take a basic example of iterating over a set of data to print out a list in HTML. Starting with a PHP template (using PHP’s alternate syntax) we have:
<ul>
<? foreach($mylist as $list_item): ?>
<li><?= $list_item ?></li>
<? endforeach; ?>
</ul>
$mylist has to be generated somewhere first. You could do that a few lines above this code (probably not the right approach), or generate that list elsewhere and pass it in (probably the right way to go). This code block is pretty straight forward. We’re looping over an array and printing out an HTML list.
Okay, now let’s see how we do it in SilverStripe’s bare-bones templating language:
<ul>
<% control mylist %>
<li>$list_item</li>
<% end_control %>
</ul>
Wow, that’s so obvious that our designer wouldn’t have to learn anything new! They would just intuitively know to us a “control” structure. They would also have to write a method in the controller called “mylist” that returns an object set, and that each object in the set will have a property called “list_item”. Dead simple!
Okay, on to Smarty:
<ul>
{foreach from=$mylist item=list_item}
<li>{$list_item}</li>
{/foreach}
</ul>
Well, I think that’s a little more intuitive because Smarty sticks with a known loop structure, foreach, rather than introducing something new. You will have to load $mylist into the Smarty template with $smarty->assign('mylist', $array_data);, but that’s all part of separating design from logic.
So, my argument here is that coding using a template language makes the code more obscure, not more accessible. Of these three choices, PHP is the most straight forward. The reality of the situation is that either you have a developer and a designer on the project, or the developer is doing the whole thing. If the developer is doing the whole thing then switching to some alternate syntax just for displaying data to the user doesn’t buy them anything. They just have to learn something new, when PHP already has everything they need. If you have a designer (who doesn’t code) and a developer both on the project, then the developer is going to have to write one of the above loops and explain to the designer what it’s doing, which parts they can touch, and what they shouldn’t. In that case, none of the three choices offers the designer any benefits in terms of understanding what’s going on, or limiting what they can break. So, we’re back to what’s the easiest for the developer. PHP, end of story.
However, some people say that regardless of the cost of a little more obscurity, there are other benefits of using a templating engine. Let’s address some of those.
1. Separating design from logic:
This is, I think, the biggest selling point, and the biggest misnomer when it comes to templating engines. Just because you are using a template doesn’t mean you managed to separate your design and your logic. To actually separate the two takes discipline on the part of the developer. If you want to be a naughty developer, you can. In Smarty you can use PHP directly: {php}...evil code...{/php}. SilverStripe, on the other hand, forces you to behave yourself… Not! I wrote a blog posting on how to hack their templating language just the other day.
So, if you want to put logic into the design, you can. There is nothing stopping you but yourself. This is an important point. When you have a templating language, especially in a system like SilverStripe, which has the stated goal of blocking you from doing something they perceive you shouldn’t, you are going to find yourself stymied and frustrated (just read their Forum for some examples). In that situation I think you are less likely to be a well behaved developer.
Personally, I believe that a good development tool will make it easy for you to do the right thing, but not actively try to block you from doing the “wrong” thing, because the developers of the development tool can’t foresee every situation. Separating design from logic is (usually) expressed by using the MVC design pattern. MVC stands for Model-View-Controller, and is the industry standard for how to develop a project in a way that splits your code up into logical, maintainable units. Simply bolting a templating engine onto the front of your project doesn’t mean you are using an MVC design pattern. The template engine would be used for the View, but you can still hide View level code elsewhere, and you can put Model and Controller level code into the View. It still requires discipline on the part of the developer.
An MVC Framework can help. This is a set of code that helps you develop following the MVC pattern. CodeIgniter is the best that I’ve come across for PHP. There are lots of them out there, and I certainly haven’t tested them all, so there are probably some other good one. However, two other developers and I evaluated dozens of PHP frameworks before settling on CodeIgniter as the right tool to use on a major enterprise web site (Symbol Technologies – later purchased by Motorola, so all our good coding went away). I’ve used CodeIgniter on many subsequent projects with no regret.
SilverStripe has it’s own MVC framework built in, so that certainly helps. But the inadequacy of their View can lead developers to simply move the View level code up to the Controller in order to have access to the methods and properties they need to get the job done. That’s just as bad as pushing Model and Controller code down to the View, which is what SilverStripe tries to block you from doing.
2. Caching:
Many templating engines employ a caching strategy in order to keep the server from having to continually double parse all of the scripts. This can help get performance close to the level of not using a templating engine, but it simply can’t be quite as fast because at some point the template must be parsed to turn it into PHP. Many templating engines seem to list off caching as a selling point, by which they imply will actually improve performance of your site, rather than only degrading it a little bit. Obviously, taking this approach is somewhat dishonest.
Caching strategies are also often employed by MVC frameworks as a way to aid performance. Caching doesn’t require a templating engine to pull off, it can be done in conjunction with any tool set, or you can code it directly.
You can also use a PHP accelerator, like APC, to improve the performance of your site. This compiles your PHP into it’s executable form, and saves that until the source PHP file changes. This can provide quite a boost to your PHP’s execution speed. In fact, many templating engines recommend doing this as a way to aid performance even more.
3. Speed up development:
This, to me, is the biggest joke of all. How can having to learn a completely new syntax save you time? The Smarty “you’ve got to experience it to understand” statement is ridiculous. I have experienced it, and it’s crap. Either there is solid evidence for speeding up development, or there is not. If there was such evidence it would be presented, rather than vaguely alluded to.
Honestly what speeds up development is separation of design from logic. Specifically breaking up the project into the three components of MVC allows developers to break up the work logically among a team, or at least to focus in on one aspect at a time, rather than the old school style of munging it all together. A templating engine may be part of the solution for separating the design from the logic, but it is not, itself, the solution. However, as suggested before, adding a foreign syntax for your development team to have to learn is just going to slow things down.
So, there are three arguments often presented for templating engines that I have hopefully demonstrated are bogus.
The last comment I want to make is regarding the impossible paradox that is a templating engine. As I said at the outset, Smarty and SilverStripe’s templating engines are polar opposites and make for good examples of the problems.
SilverStripe’s template engine is very bare-bones. It supports only a few constructs and is, by design, missing anything that might make it useful. Why? So that you have to use their Model and Controller to do all the heavy lifting. Again, frustrating the developer like this isn’t very productive. You can’t foresee every situation, so you can’t see precisely when it’s a good idea to enable the user, and when it’s a good idea to block them. Sooner or later the developer will encounter a situation that the templating engine isn’t prepared to handle, and they will either have to come up with hacks, like I have, or simply move the view code up to the Controller or Model. Neither situation is good.
The opposite situation is Smarty. They have recoded so much PHP into their templating language, that you could just about build an entire web app using only Smarty templates. This is not effectively blocking the user from bad development, and gives them the opportunity to do whatever they want. So, all arguments for using templates fly out the window.
My point? You can’t win with either situation. If you deny the users something they will get frustrated and find out how to get it anyway, often by violating good coding practices. If you give them everything then they might as well be using PHP in the first place.
So, the best solution, as I think I’ve covered, is to skip the template engine all together. Go straight for the MVC framework and you’ll be a much happier camper.
Hacking SilverStripe Templates
445 days ago
SilverStripe is a Content Management System from a company in New Zealand called SilverStripe. As far as CMS's go, it's a pretty good one. It makes it very easy for authors to add and edit content.
Unfortunately, from a development perspective, it has some problems. Specifically, it's built on it's own MVC framework called Sapphire. And Sapphire feels like someone took the code base and ran it through a blender. The inheritance model is so deep that it can take 10 minutes or more of tracing through the code to find what function is actually being called in a given context.
And their templating language, which is what this article is really about, sucks. Now, technically, all templating languages suck. This just happens to be one of the worse ones. For instance, you can do:
<% if Foo %>
...
<% end_if %>
But not:
<% if !Foo %>
...
<% end_if %>
... because the "not" operator isn't supported. Also this won't work:
<% if Foo == "" %>
...
<% end_if %>
... because quotes aren't supported!?!
Supposedly this limitation is by design so that you have to move more of your work to the controller or model (take your pick because both seem to be in the same namespace as the view...?!?). However, that doesn't really work consistently either because there are some contexts where the properties or methods you are trying to access simply aren't available. And that is where this hack was born.
The initial goal was to come up with a way to do print_r() on a variable to try to find out why I wasn't able to see a property in the view. And I couldn't put it in the controller or model because methods that I had added weren't available to me either. To give more context, I was trying to access properties and methods of an object's parent. SilverStripe gives a utility for this:
<% control Parent %>
...access parent data here...
<% end_control %>
I should have been able to call the parent's methods or access it's properties in the middle there, but I was coming up empty.
Here is a hack to get around that. The .ss template files are processed by "/sapphire/core/SSViewer.php". The method "parseTemplateContent()" does a bunch of str_replace and ereg_replace on the template code to turn it into PHP code. You can add the following near the end of the function:
// PHP Hack
$content = str_replace('<**',"\nSSVIEWER;\n", $content);
$content = str_replace('**>',";\n \$val .= <<<SSVIEWER\n", $content);
This goes on our about line 523, and adds some additional processing to the $content variable, immediately before the $output variable is created.
What this now gives you is the ability to to add PHP blocks... sort of... to the template code. Inside your .ss file, you would do something like:
<**
... PHP here ...
**>
Inside your new code block, you can do some PHP. You can't use the dollar sign directly, but you can use "{dlr}" which will get parsed into a dollar sign for you. You'll also need to keep doing ?showtemplate=1&flush=1 to show you the template you are generating and flush the previous cached template file so you can see your changes. Showing the template will show you how the code you are writing is getting turned into PHP code. This is immensely helpful in figuring out what is going on.
My previous example of wanting to do a print_r on the parent variable would look like this:
<% control Parent %>
<**
print_r({dlr}item);
**>
<% end_control %>
"{dlr}item" gets turned into "$item" which is what is actually sent to print_r(). $item is what SilverStripe is internally using at that point to call the object that represents the Parent. This is where you'll need to do a lot of ?showtemplates to see what's really going on under the hood.
Doing a print_r or echo in the code will cause whatever variable you are looking at to print out at the top of the page. This is because SilverStripe is actually collecting all the output from the various PHP blocks it is constructing into a variable called $val. To keep with this paradigm, you might do something like this:
<title>
<**
if(strlen(trim({dlr}item->Title))) {
{dlr}val .= {dlr}item->Title;
} else if(strlen(trim({dlr}item->MenuTitle))) {
{dlr}val .= {dlr}item->MenuTitle;
} else if(strlen(trim({dlr}item->MetaTitle))) {
{dlr}val .= {dlr}item->MetaTitle;
}
**>
</title>
This is from a literal case I had where the usual SilverStripe methodology was printing out an empty title, and not moving on to check for MenuTitle or MetaTitle. Because I was limited to "<% if Title %>", and couldn't do '<% if Title == '' %>", I was unable to solve this problem with the tool set provided by SilverStripe. I even tried creating a special method called "RssTitle()" in both the controller and the model to do this work outside of the view (as the view isn't ideally where it should go), but for some reason the view didn't have access to this method.
This is a lot more hoops than one should have to jump through in order to get access to one's data, but there it is. Hopefully I'm just missing some nuance of SilverStripe, and can write a follow-up article explaining the right way to do this. But, until then, I'll be using this hack to do an end-run around SilverStripe's apparent limitations.
autocomplete="off"
588 days ago
I've been searching for something for the last 45 minutes and finally found it. It's something I need about once every 3 years, and so never remember it at the time. This time, I think I'll be smart and blog about it. Maybe I'll still have my blog up 3 years from now when I need it again.
The something is a non-standard HTML text input form field attribute:
autocomplete="off"
It seems that most browsers recognize it, even though it's not W3C approved code. Basically, it tells the browser not to use any saved form field data that you have previously entered and just use what's in the field's "value" attribute.
This is good in situations where you have a bunch of similar fields on the page (like an editable user list) and you need to know that what you are seeing is what's coming from the database, not what your browser might remember from previous sessions.
Letter to my Representative (Bail Out Plan)
701 days ago
To The Honorable Michael T. McCaul:
Regarding the bail out plan (HR 3997), I notice that you stood up to the President and Wall Street and voted NO. I wanted to thank you for your courage and conviction on this issue. You recognize that it's not the tax payers job to bail out the fat cats on Wall Street from this mess they have created.
The Senate has recently passed a bail out package, and I know you, along with many who voted against the original bill, may be under a great deal of pressure to reconsider your vote. Please don't. The bill as it now stands is not substantively different from the original bill, and still represents an enormous transfer of wealth from the American people to the morally bankrupt Wall Street elite.
There are people who might be hurt if no action is taken, but that's how a free market works - it's a risk. Besides Paulson's and Bernanke's chants about economic doom causing market jitters, I don't see any compelling evidence of an eminent economic collapse if the action taken isn't rash and immediate.
I DO think something should be done. Clearly there are victims of predatory lending practices that need help. Clearly the market needs more regulation than it's had recently. But this isn't the time to rush to judgment and gamble $700 billion of the tax payer's money. This is the time to take a deep breath, really analyze the situation, and take a serious, measured approach to solving the crisis. I think in the long run the market is going to be much better off if congress makes the right decision, rather than making a rushed decision.
Thank you for standing up for what is right. I hope you will continue to do so, even in the face of great pressure from your colleagues on the hill.
Sincerely,
Arthur McLean
Follow up:
Michael McCaul did the right thing in the second vote on the bail out plan and voted NO. I salute his conviction. And now it will be slightly harder to vote for his Democratic opponent during the next election. Not a whole lot harder, but slightly harder.