On Thu, 05 Apr 2007 17:06:01 +0100, J-P Stacey jp.stacey@torchbox.com wrote:
Hi,
I'm fairly new to Drupal. I've downloaded and installed Drupal 5.1, and we've got it working with multiple sites and modules very quickly. A lot of things *just*work*, which is great.
Yay!
One aspect I've found quite confusing is the principles behind templating (I can manage the PHP nitty-gritty reasonably well). There seems to be a number of different ways of doing templates - PHPTemplate, XTemplate, a .theme file
- which I appreciate may be for historical reasons. I've also seen
conflicting advice on the Drupal site for how to override default templates and functions.
XTemplate is dead, long live PHPTemplate. :-) .theme files are there for legacy reasons. I don't know of anyone that actually uses them in production sites. Really, just use PHPTemplate.
Our Drupal themes would end up quite large owing to specific client requirements, so I really want to start as I mean to go on! So what's the best practice for templating?
A few examples of stuff I want to do might help illustrate the problems I've been having:
- If I wanted to hook into the code that creates e.g. $sidebar_left, how
would I do that? It seems to be created by theme('blocks' , 'left') in the phptemplate engine. Should I just discard $sidebar_left, or is there some hierarchy of function names that theme() calls? Can I put any such functions into some file in my theme directory and they'll always get recognized?
Should I call such functions e.g. theme_block_left, or phptemplate_block_left, or THEMENAME_block_left ? Or should I instead use .tpl.php files exclusively e.g. block-left.tpl.php?
PHPtemplate in a nutshell:
In Drupal, there are theme_foo() functions. In your theme's template.php file, you can override them with a function named phptemplate_foo(). That, in turn, will get overridden by themename_foo(). Calling theme('foo') will call themename_foo(), phptemplate_foo(), or theme_foo(), whichever it finds first in that order. So if you wanted to override the "blocks" theme, you'd use phptemplate_blocks($region). Generally the easiest way is to just find theme_blocks(), copy and paste it to your template.php file, and rename it.
As a general rule, you should use phptemplate_foo() instead of themename_foo() in most cases. The exception is when the PHPTemplate engine itself already has a phptemplate_foo() function in the phptemplate.engine file.
OPTIONALLY, in the phptemplate_foo() function you can "stub out" the function to a template file. Any override function may do that, but in many cases you don't have to. The PHPTemplate engine itself already has override functions that "stub out" common theme functions (page, node, etc.), so you don't need to most of the time. Have a look in phptemplate.engine to see how it works for the standard overrides, and follow that pattern for your own when you need them.
- For different node types, I just can't seem to get the system described
at http://drupal.org/node/104316 working properly. It works fine for the node-content sub-templates e.g. node-video.tpl.php will get called over node.tpl.php, but e.g. page-video-edit.tpl.php just doesn't get called.
Check phptemplate.engine in the phptemplate_page() function to see how it builds the "suggestions" list. I don't think you can do page-video-edit.tpl.php, but I'm not certain. This may be a case where you do want to override phptemplate_page() with themename_page() to change the suggestion list to your liking. :-)
Is there something I'm missing? Would this hack here http://drupal.org/node/117491 be worth looking into?
- A bit of a random one, but say I wanted to change the content of an
admin page. We'd be using Drupal for very heterogeneous sites (so e.g. events nodes, news nodes, courses, content, press releases etc. etc.) so the "Create content" page would start to look very cluttered. Any way of overriding that at the theme level? Also, we could have many user roles, so we would want to change the look of the permissions pages too.
You can add your own menu callbacks in a custom module that point to the node add form (see node.module's hook_menu()) for the types you want, then hide the default create content menu. Then you can style or link to your own pages however you want and build your very own admin area. :-)
Cheers!
--Larry Garfield