Best Practices

"How should I write code?"

This document is a work in progress. Unlinked items are planned topics, feel free to contribute.

Standards

All work must conform to established best practices and coding standards. Code quality is ensured in a variety of ways:

  • All code must conform to Drupal Coding Standards. This is enforced via local git hooks and code checks performed during continuous integration.
  • All front end code must follow Drupal Theming Best Practices.
  • All code must be reviewed by a peer or established integrator before being merged into the master branch.
  • All new features must covered by an automated test that mirrors the ticket acceptance criteria.

Exporting configuration

All site functionality should be represented in version-controlled code. This includes all configuration. Drupal configuration is typically exported via Features.

Features

Please see Configuration Management for Features best practices.

Configuration updates

  • If a change is happening, that change needs to be documented in code, preferably an update hook. E.g.,
    • Reverting features and feature components features_revert_module()
    • Enable / disable module module_enable()
    • Adding indexes to databases db_add_index()
  • Updates needs to be actively monitored. This should be done using NewRelic, SumoLogic, Logstreaming, and/or other monitoring tools.
  • Updates need to be intentional. E.g., don't use cloud hooks or cron jobs to automatically execute updates or clear caches.

Caching

Without caching, Drupal is slow. As a general rule of thumb, try to cache everything that you can and try to invalidate that cache only when it is likely to be stale.

Caching is complex. Because caching is so complex, it's difficult to provide general guidelines for caching strategies. Here are the factors the should be considered when making caching decisions:

  • What is serving the cache? E.g., CDN, Varnish, Memcache, DB, APC, etc.
  • What is being cached? An entire page, one component of a page, bytecode, etc.
  • Is the cache context-aware? I.e., is there only one version of the cached data or might it differ depending circumstances? E.g., the "Welcome [username]" block changes depending on the logged-in user.
  • What circumstances render the cached data stale? E.g., a cached view of press releases is stale when a press release is updated.
  • How should the cache be invalidated? E.g., invalid after X minutes, triggered by a user action, etc.

Specifically, ensure that you are properly caching data at every level possible, including:

  • Page caching (Varnish)
  • Database query caching (Memcache)
  • Views caching
  • Block caching
  • Panels caching
  • Entity caching
  • Twig caching
  • APC / Opcache (Code caching)
  • Static caching
  • CDN (Content Delivery Network)

See the Drupal 8 Cache API documentation for information in implementing your caching strategy.

Patching

All modifications to contributed code should be performed via a patch. For detailed information on how to patch projects, please see patches/README.md

Views

Please see views.md.

Logging

  • Any configuration changes from custom modules should be logged to watchdog (also Acquia Library recommendations
  • Any destructive actions must be logged

Building content types

@todo Document:

  • Appropriate time to use fields
  • Audit for overly complex content types
    • Reason: All fields loaded for each node load
    • Use case: Needs translations, user-facing form, revisions, etc.