We have a few pages like the following on my site, everpurse.com: https://everpurse.com/home

They contain moderately complex markup and CSS. My approach to creating these pages is to create a module that uses hook_menu() to create a menu callback. The callback itself returns a render array containing something like:

return array(
  '#theme' => 'ep_homepage',
  '#attached' => array('css' => array(...)),

The module provides an ep-homepage.tpl.php template file that contains all the markup, including language, HTML, etc. The #attached CSS file styles everything.

It seems, though, that the proper "Drupal way" to do something like this is to put all the CSS and markup in the theme directory, and all the language inside of t(), and expose the language via preprocessed variables in the module. But there are a number of reasons I don't like this approach:

  • Some of the language is very markup-heavy. There may be sentences like Available now <span class="limited-time">for a limited time only</span>. Putting this into the module mixes module concerns with theming concerns.
  • The CSS in the theme gets aggregated, which means it will be loaded on every pageload—including pages that don't use it. (That is, by putting page-specific CSS into the theme, you sacrifice the benefits of using #attached.)
  • Even when putting all the markup into the theme, the page callback has to return something. But if the theme is taking care of all the markup, what should the page callback return? Just theme('ep_homepage')? This would mean the module should create an empty implementation of the ep-homepage template, and allow the theme to override it with a template of its own, right? This seems like such a silly workaround and a bunch of extra work, just to meet Drupal best practices.

So, I guess my question is: what is the Drupal best practice for a page like this? (And I'd rather not use Page Manager/Panels, since the markup is so complex that I'd rather edit it in a Git-controlled template file than via the Panels UI.)

1 Answer 1


The "Drupal way" would be to NOT create a module to hold content, and NOT create a module for a specific page(s). "Drupal way" would likely be to (1) put all of the language/content w/markup into a node, (2) put other outside-of-content markup and styles into *.tpl.php files and css files, (3) put any PHP functionality that isn't available already in contrib into a custom module, and (4) NOT put any content/language into a theme or into a module.

  • Thanks Link! Given that I need the pages to be Git-controlled, is my only solution to just not do things the Drupal way then? Commented May 22, 2014 at 21:09
  • Unfortunately, as of Drupal 7, content and config is stored in the database and not easily version controlled. This will improve in Drupal 8 where all config is stored in YAML files which can be version controlled, but I think the basic model of a database-driven CMS is to store content in the database. However, something like the node_export module can help this: drupal.org/project/node_export
    – LunkRat
    Commented May 22, 2014 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.