2

One thing I struggle with in learning Drupal is managing the output. There's such an abstraction from the templating. All the output -- all the templating, really -- is meant to be done from the interface. You don't code markup, you place blocks and create views. And you have to have the correct block or view for the specific output you want.

Contrast this to most other CMS, where you have some templating library and you're embedding tokens (or code -- actual or template-specific) in HTML markup. There doesn't seem to be any of that in Drupal.

Example:

I want a certain menu to appear for a certain content type. Instead of having a template file for that type in which I just insert this menu, I'm instead finding a block that might output what I want, configuring the hell out of it (and hoping it configures how I want it), placing it in a spot globally, then limiting it to just display for certain content types.

This is a pretty huge departure from most other CMS. As I said before, there really is no...templating. It's all configuration, and as a developer, I find this really, really cumbersome. I'm navigating through all these admin screens, and trying to minutely configure a block, and all the time I'm thinking, "If I could just get at the markup, I could solve this problem in 30 seconds..."

What's the solution to this alienation? Do I just need to bite the bullet and embrace the philosophy? Do I start writing my own themes -- would this take me back to a more familiar environment? How do other developers coming from more "traditonal" templating environments handle this?

I'm just trying to get the big picture here.

Deane
  • 8,269
  • 12
  • 58
  • 108

1 Answers1

2

I think there's a bit of a disconnect here -- at least, enough of a terminology disconnect to make it tough to parse a lot of the existing public documentation about Drupal's theming system.

Technically, all of Drupal's output is templated. With a few exceptions (say, the link to a user's username) every bit of markup sits in a foo-bar.tpl.php style template file provided by a module or the current theme. Drupal modules build up data, then pass it into the templates to produce HMTL. In practice, the output from each template is nested inside of the next like a set of Matryoshka dolls. For example:

html.tpl.php                 (the HTML wrapper)
  page.tpl.php               (everything inside the body tag)
    region.tpl.php           (the 'main content' portion of the page)
      node.tpl.php           (post in the main content)
        field.tpl.php        (the post's "related links" field)

The field.tpl.php gets rendered, and concatenated with all the other fields, then that aggregate HTML becomes a variable that's passed into the node.tpl.php template and wrapped in other markup, which is then passed as dumb HTML into the region.tpl.php and... well, you get it. The good news is that you can drill down and pick out a tiny bit of markup, modifying it consistently site-wide. The bad news is that there are thousands of small templates for the individual bits of markup that make up a page.

The nesting of the objects themselves is specified by Drupal's configuration systems, but the templates themselves still control the actual HTML output. If a theme developer wants to, they can dump a traditional PHP application into html.tpl.php and it will execute -- executing Drupal's code when pages are requested by its menu routing system but completely ignoring the output that it's generating when it comes time to print the page.

In essence, the whole system works like a Play-Do Fun Factory. Data is shoved into the Fun Factory, and the theme system squeezes it through the templates to produce fun shapes.

To make a long story short, it is possible to jam things like nav menus and so on into individual templates. But it's important to remember the nesting system -- the node.tpl.php template only controls the snippet of markup containing an individual post, not the wrapper around it or the page that contains it. And without writing custom code, the page.tpl.php template doesn't know what's inside its various regions; it only knows how to wrap them in the right container divs.

The whole approach makes it very, very easy to drop in various plugin modules that add extra bits to the page, conditionally respond to what's being displayed, and so on without every touching the templates themselves -- since they simply control how each tiny element is rendered, and how the concatenated aggregates are wrapped in containing markup. On the other hand, this approach can also be maddening for someone who's used to building a complete template and pulling useful bits from the CMS to populate it. Drupal's "build stuff, then push it through the templates" approach just doesn't match the "build templates and pull stuff into them" approach many other systems use.

There are various modules like Panels that allow site builders to take a more holistic approach to the page, its layout, and so on, but it still uses the same nested-templates approach that can make starting with the HTML tough.

Eaton
  • 7,405
  • 2
  • 26
  • 24
  • Also, in Drupal 8, the templates themselves are being turned into twig templates rather than our homegrown PHPTemplate system. The basic concept -- pushing data through "dumb" templates that are deeply nested within each other -- should still be there, though. – Eaton May 27 '13 at 02:51