Static Prototyping and Keeping Drupal Simple (KDS)

Fredric Mitchell
#Drupal | Posted

If you ask any Drupal developer about their favorite tools, the probability of Views and Panels being in that list are absolute. They are part of the top 100, and with good reason. They provide GUI tools for querying and layout customization.

They also, however, introduce complexity behind-the-scenes.

The technical debt involved with preprocessing views templates or creating custom panel layouts is hard to justify for projects that have small budgets, tight timelines, or hyper-specific design requirements.

One approach is to have a front-end developer interpret flat designs to DOM output introduced by the implementation. While this is common, it adds technical design debt as you deal with unneeded repeated elements, missing HTML5 tags, and unstructured CSS.

You also introduce QA headaches as the gap between what is designed in Photoshop and what is implemented lies solely on subjective design eye.

I believe a better approach is to use static prototypes and manipulate Drupal to the desired DOM using core API functions.

I call it Keeping Drupal Simple (KDS).

Let's explore the KDS philosophy as well as some implementation techniques.

Business Goals

Every decision should be tied to a stated business goal. The 'what if' scenarios of users, both visitors and site administrators, being able to interact with the options Drupal can provide generally push budgets.

Although being able to think of all scenarios is something developers pride themselves on, most business goals can be solved with specific definitions of success and simpler technical solutions.

One way to focus this effort is to ask the right questions. Instead of asking 'Do you need to be able to do x?', follow the principles of Agile and ask 'What business goal is solved of being able to do x?'

This subtle change allows developers to redistribute their efforts from feature rich technical implementations to high value client experiences. It also forces the client to think about the true value of a feature request as it relates to their audience.

This results in reevaluating the need for modules, like Views or Panels, because site configuration priorities are lower than the design and content creation priorities.

Below are four questions I ask when implementing KDS:

  1. What is the business value of editors being able to change the layout / have a dashboard / administer X type of content?
  2. How do you define a successful site visitor experience?
  3. When do you plan for your content creators to create real content and give you feedback?
  4. What business value is lost if X feature is moved to a Phase 2 or 3?

Project Evaluation

It goes without saying that this approach does not work for every project. Evaluating the needs of your client, the project constraints, and the abilities of your team through proper discovery is essential. KDS may work for you if:

  • The project has a small budget and timeline
  • There is a lack strong front-end acuity on the implementation team, either from availability, skill or budget
  • The front-end team knows [insert front-end framework], but not Drupal
  • Site configuration and layout will remain mostly static after launch

Not all of the above factors are required. If your project does satisfy a majority of the conditions, I would consider KDS.

Static Prototyping

One of the driving factors of cost is design interpretation. Based on a given a PSD design or wireframe set, expectations are set with the client about look, feel, and interaction.

The cost to bridge the gap between what is possible on the web and what is designed can be vast.

This can be mitigated by designing in browser and starting with HTML prototypes. Providing a simple static homepage and interior page can set the proper expectations of menu interaction, block placement, and feedback in various browsers.

Thankfully, methods like style tiles and atomic design take this even further by providing a common design relationship between elements.

This accelerates the on-boarding of new project developers because the styleguide contains both design and DOM conclusions.

The static prototype also becomes the source of truth for all decisions.

Being able to explain in concrete terms what elements of a page will and will not have user-defined configuration goes a long way to keeping deliverables within budget.

Work is also done in parallel, decreasing inefficiency.

Front-end developers communicate ideas via static prototypes to the client while also optimizing their DOM and CSS.

Backend developers develop functionality that produces the prototype DOM.

The challenge  becomes bending Drupal towards that markup goal. When applying the static prototype within Drupal, the theme becomes the meeting point. Base themes tend to get in the way and add extra markup or classes, so starting from scratch is best.

The best way to build a theme from a static prototype is to take your interior page and set it as the page.tpl.php. This gives you a starting point to start swapping static components for dynamic Drupal components.

As you swap, you can compare the output of your theme to the static prototype and provide an iterative QA piece for the team.

Some best practices include:

  1. Creating a html.tpl.php and swap out the contents in the <head> tag
  2. Swapping the area where a menu would be for themed menu output via menu_navigation_links()
  3. Combining the static homepage prototype elements and wrap them in a conditional that be set in template.php
  4. Swapping sidebar areas for regions and hard-code them temporarily in template.php to check output

Using your prototype in your tpl files provides an added bonus of only needing to swap out areas if something is dynamic. This accelerates your pace to the deliverable as you're not bogged down with parts of the DOM that will never change and, thus, do not need rendering from the Drupal ecosystem.

 API Over Everything

The most important technical implementation philosophy developers need to remember when implementing KDS is to always try to use core API. The reason isn't because 3rd-party modules are bad.

The reason is because 3rd-party modules have assumptions that can lead to technical debt. Many times, budgets are blown because of the work you have to do to undo a default assumption.

For example, if a static prototype homepage has a listing of content, the delivered DOM may use the article HTML5 tag to segment out the content from the rest of the site.

If you build that listing with Views, you'll have to:

  1. Build the view with the right conditions
  2. Export the view to code
  3. Preprocess the view or create new tpl files
  4. Work to ignore or work-around the extra DOM included from Views
  5. Hope the requirements of the view doesn't change
  6. Hope the client doesn't change anything in the Views interface

Conversely, you can use EntityFieldQuery to grab your listing and theme the results in a custom theme function with the exact DOM desired.

In template.php:

  1. /**
  2. * Implements hook_preprocess_page().
  3. */
  4. my_theme_preprocess_page(&$vars) {
  5. if (drupal_is_front_page()) {
  6. $variables['page']['content'] = my_module_listing();
  7. }
  8. }

In my_module.module:

  1. /**
  2. * List nodes for homepage.
  3. */
  4. function my_module_listing() {
  5. $query = new EntityFieldQuery();
  6. $query->pager(10);
  7. $result = $query->execute();
  8. $output = array();
  9. $nids = array_keys($result['node']);
  10. $nodes = node_load_multiple($nids);
  11. foreach ($nodes as $node) {
  12. $output[] = theme('my_module_listing_single', array('node' => $node));
  13. }
  14. $output[] = theme('pager', $query->pager);
  15. return implode('', $output);
  16. }
  17.  
  18. /**
  19. * Theme a single element in a listing.
  20. */
  21. theme_my_module_listing_single($vars) {
  22. $output = array();
  23. $node = $vars['node'];
  24. $title = filter_xss($node->title);
  25. $desc = filter_xss($node->desc);
  26. $output[] = '<article>';
  27. $output[] = "<h1>$title</h1>";
  28. $output[] = "<p>$desc</p>";
  29. $output[] = '</article>';
  30. return implode('', $output);
  31. }

[/php]

You now have eliminated technical debt from the Views ecosystem and eliminated design debt due to new DOM elements.

While this isn't a critique on the exporting UI workflow, do take time to consider the impact of multiple environments, multiple developers, multiple iterations of development, and a tight timeline.

What happens to your budget when there is a conflict?

What happens to your scrums when clients want to know what 'that button does'?

The goal is to deliver high business value, in a limited scope. This, consequently, reduces the likelihood of scope creep introduced by additional configuration options. This also forces the team to concentrate on the business values communicated at project start.

Not sure which API functions to start with? I recommend starting with these 30.

Why?

Some frequently asked questions I receive of 'Why' or 'How' when it comes to KDS technical implementation:

Q: How do I place blocks, if not by the UI?

  • Create an update hook and place the block delta directly in the table
  • Use Context and hook_context_default_contexts().

Q: What happens if I need to update a field or setting, if not by Features?

  • Review the Field API and update through an update hook.
  • Also, Features are great! I'm not knocking Features. Maybe consider using it as a way to stub your update hook with the proper configuration array through the Feature export and piping that into your install / update hook.

Q: What about initial WYSIWYG configuration, Pathauto configuration, or some other common configuration?

  • See answer above.

Q: Seriously, though. Why would I do this when a module does this for me?

  • Code requires commits and commits provide a history. Having a history of what was changed is good. It helps team members and it helps project managers in tight deadlines and budgets. History gives you a breadcrumb trail of work.
  • Learning the Drupal API also gives you confidence of how things work under the hood. Troubleshooting is easier if you know the execution processes behind those buttons.

Don't Forget Content Creators

Update: 

Here is a make file for starting with KDS.

Here are a few 3rd-party modules (and caveats) that align with the easy content authoring objective:

  • WYSIWYG - CKEditor 1.13
  • Asset Management - Media 1.4
    • Include these two patches
    • Ensure that the jQuery version is <= 1.7 as there is a bug that breaks the media browser in 1.8
  • Simple Workflow - State Machine 2.2
    • Out of the box, every node goes through a simple draft => published workflow
    • Overrides are done via code only
  • Youtube, Vimeo Integration - Video Embed Field 2.0-beta7
    • Link to a video that turns into a field
  • SEO - Metatag 1.0-beta9
  • Sidebar Elements - Bean 1.7
    • Custom types can be added via code only
    • Fields can be added to block types via the form API

I haven't had a chance to use Edit or the other recommendations in the Spark distribution. I'll try to post an update to KDS once I've had a chance to evaluate it, especially since it's in Drupal 8.

KDS is designed to strip down the implementation plan of a Drupal solution from the discovery process to the technical implementation. It's not a one-size-fits-all nor is it a critique on popular modules like Views and Panels. It's main goal is to provide a philosophy of simplicity inside the complex world of a Drupal project.

Please let me know what you think!

I'm curious to hear the community's feedback and if others have found other ways to keep projects streamlined.

In the meantime, learn more about everyone's favorite module, Views in Chris Johnson's blog post "Customizing Views With Context!"

 

Fredric Mitchell