Updated on 11 October 2017

The goal of this section is to give hints about where to search by indicating the Drupal specific terms.

For most cases, you can find up-to-date code in the Examples for Developers module.

[ This section needs to be completed, see the project roadmap for this site. ]

Topics to be added:

  • Get a link from a module and a Twig template (internal or external, route and path distinction).
  • Add variables to a template: introducing preprocess functions.
  • Create a template in a module and pass variables from a Controller.
  • Cache heavy operations
  • Cache a defined context (cache tags)

Avoid repeating tasks

Solution: scaffold code via Drupal Console.

Most of the code can be generated: modules, themes, services, ...
Just check the generate section from the Drupal Console Cheat Sheet

More about setting up Drupal automation tools.

Override a specific behavior

Solution: implement a hook.

While there are object oriented solutions that will be described later, small overrides can be achieved via this technique.

Create a custom module via Drupal Console generate:module, then use any of these hooks.

Example of hook usage: alter forms or a dedicated form.
For performance, try to be specific if the hook is available: prefer the hook_form_FORM_ID_alter to the main hook_form_alter.

Examples will be provided.

Get a custom template

You could require custom templates for

  • Region
  • Content type
  • Content type display mode
  • A very specific entity, by id (Node, Block, ...).

Solution: use templates that follows the template suggestions naming convention in your theme.

Template suggestions

They are all described here, but you can easily get their names via a configuration of your local environment.

Some examples:

  • Article teaser: node--article--teaser.html.twig
  • Front page: page--front.html.twig
  • Maintenance page: maintenance-page.html.twig

Working With Twig Templates
Twig Template naming conventions

You may also want to create your own template suggestions.

Create a route

Solution: define entry in the *.routing.yml file from a module.
Use Drupal Console generate:controller to generate a class that extends ControllerBase.

Read more about the routing system

Get the current node id

$node = \Drupal::routeMatch()->getParameter('node');
if ($node && $node instance of \Drupal\node\Entity\Node) {
  // You can get nid and anything else you need from the node object.
  $nid = $node->id();

Get the current user

$user = \Drupal::currentUser();
$roles = $user->getRoles();

Embed JS and CSS

Solution: use the libraries definition.

Call a feature from the API

Solution: get a service from the container.

In a hook

Use via a static method call.

Example: use the language manager to get the current language id (for English, returns 'en').

$language = \Drupal::service('language_manager')->getCurrentLanguage()->getId();


$language = \Drupal::languageManager()->getCurrentLanguage()->getId();

In an object (Controller, Block, ...)

Use it via dependency injection. Static call can still be used, but it is not regarded as a best practice for testing.

While generating a Controller, Block or Form with Drupal Console, the interactive command will ask if any dependency injection should be added. Sweet.

Example of dependency injection for a Form

Execute a query and use the Entity API

Solutions: several options are available through the API.
Use the API to get the benefits from the SQL abstraction layer and ensure that your queries are secure (avoid SQL injection, ...).

Use entity_type.manager

API over any entity.
Example: get a node object for a node id

In the context of a Controller, assumes that the service 'entity_type.manager' is injected.

$node = $this->entityTypeManager->getStorage('node')->load($node_id);

Use entity query

Use it to query any entity (Node, Term, User, Block, Views,  ...).
Example: get all the node ids for a content type.

$content_type = 'article'; // entity query inject from a Controller
 $query = $this->entityQuery->get('node')->condition('type', $content_type);

$ids = $query->execute();

Use the database query API

Also known as DBTNG (Database The Next Generation).

Use it to execute queries on other tables than entities.

Understand the translation system

A really valuable serie of blog posts is the translation tidbits serie from Gábor Hojtsy.
In a serie of 20 posts, he covers everything that you should know about the translation system.

See also this topic in the Build section.

Create a content form

Solutions: before creating a form via code, check the Webform module.

If you need a form that is not covered by Webform, use Drupal Console to scaffold the code via drupal generate:form then use the Form API pages.

Create a configuration form

Some examples where a configuration form is needed

  • Settings for your custom Block (e.g. how many items to display) : use the Drupal Console option that will be proposed after executing drupal generate:plugin:block
  • Global settings for a module (e.g. web service endpoint) : use Drupal Console drupal generate:form:config
  • ...

Also, refer to the Form API pages listed above.

Prevent timeout for operations that contains many items

Solution: for heavy processing, use batch or queue.

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • No HTML tags allowed.
  • Lines and paragraphs break automatically.
  • Only images hosted on this site may be used in <img> tags.
CAPTCHA This question is for testing whether or not you are a human visitor and to prevent automated spam submissions.