0

I'm using entity print and I would like to get node variables in my twig template, so I can call them like {{ content.field_name }}.

I tried using a preprocess function but I'm not sure I'm doing things well.

Assuming I have a twig template called entity-print.html.twig, here the preprocess functions I tried :

function THEMENAME_template_preprocess_entity_print(&$vars) {
    $vars['field_name'] = $entity->get('field_name')->getValue();
  }

I also tried

  function THEMENAME_template_preprocess_entity_print(&$vars) {
    $vars['field_name'] = $entity->get('field_name')->value;
  }

I'm calling field_name with all of this twig variable for debugging purpose :

   1 {{ content.field_name.0 }}
   2 {{ content.field_name.value }}
   3 {{ content.field_name.0.value }}
   4 {{ field_name.content }}
   5 {{ content.field_name[0] }}
   6 {{ node.field_name.value }}

Nothing come. What am I doing wrong ? Do I have to make a custom module ?

  • Your problem here is that $entity is not defined. – No Sssweat Aug 29 '17 at 17:48
  • try adding $entity = \Drupal::routeMatch()->getParameter('node'); – No Sssweat Aug 29 '17 at 20:05
  • Hi @NoSssweat, thanks for helping. So using $entity = \Drupal::routeMatch()->getParameter('node'); $vars['field_make'] = $entity->get('field_make')->getvalue(); I get page error with "website is currently unable to handle this request." – Aporie Aug 30 '17 at 8:40
  • Hmm ok, let me ask you this, Why aren't you using node--[type].html.twig or node--[nodeid].html.twig? Why did you create entity-print.html.twig ? – No Sssweat Aug 30 '17 at 8:55
  • Because I just want to theme the pdf and not the entire node layout. – Aporie Aug 30 '17 at 8:57
2

If you are writing a preprocess function, then the correct name of the function is THEMENAME_preprocess_entity_print(); replace THEMENAME with the machine name of the theme implementing it. If this is the case, what in the preprocess function you set as $vars['field_name'], where $vars is the array passed as reference to the preprocess function, it is accessible as {{ field_name }} in the Twig template file. See for example template_preprocess_node() and node.html.twig: What the function sets as $variables['node'] is available as {{ node }} in the template file.

Be sure to use the correct filename for the template.

  • Thanks for answering. When using THEMENAME_preprocess_entity_print(); I get an error "webserver is currently unable to handle this request.". Whereas if I use THEMENAME_template_preprocess_entity_print(); everything is running smoothly. – Aporie Aug 29 '17 at 16:38
  • You need to check the server log to see what error you are exactly getting. THEMENAME_template_preprocess_entity_print() is not a preprocess function, though. – kiamlaluno Aug 29 '17 at 17:21
  • Yes, the preprocess function seems to be function THEMENAME_preprocess_entity_print__node__node_type(&$vars) (); so I changed the name of my twig template as entity_print__node__node_type.html.twig, but still impossible to get any values neither with $entity->get('field_name')->getValue(); neither with $node->get('field_name')->getValue(); I'm getting "Notice: Undefined index: node" in drupal log even if I load $node before with $node = \Drupal::routeMatch()->getParameter('node'); – Aporie Aug 29 '17 at 17:27
  • @Aporie this is also a good solution and I believe there is something else causing the error. I have provided my answer separately, but the template_preprocess_node() is the way to go if you enabled the PDF view mode – usernameabc Jan 23 '18 at 19:35
2

Looks like you need to review Entity Print in Drupal 8 again. I am using the Entity Print module and it works just fine. Here are some pointers I would recommend below. Your original post is regarding printing node variables in twig templates

  1. On your content type, navigate to Manage Display-->Expand Custom Display Settings-->Enable PDF. This will create a PDF view mode (which is used for printing)
  2. Create a twig template node--article--pdf.html.twig (replace article with machine name of your content type)
  3. Update your_theme.info.yml and your_theme.libraries.yml as suggested in Entity Print in Drupal 8 so you can control the theme and assign a css file only for print
  4. Copy and add entity-print.html.twig to your subtheme
  5. Using node--article--pdf.html.twig, you can control whatever variable you need. However, I recommend you use the PDF view mode first to see what it can do for you.

I have yet to use a preprocess function and you should only need that if you need additional processing. Using the PDF view mode, entity-print.html.twig and the node--article--pdf.html.twig templates you will be able to print as you need.

Ultimately, you should use the PDF view mode so you can manage the PDF view mode (add classes, divs, order, add/hide/remove fields, etc.) through the UI. I have found that managing what fields are displayed through code can be cumbersome if you have a lot. The view mode can handle a lot of what you need, but you need to enable the PDf view mode first.

Sample entity-print.html.twig

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>{{ title }}</title>
  {{ entity_print_css }}
</head>
<body>
  <div class="optional_class">
      {{ content }}
  </div>
</body>
</html>

Sample node--article--pdf.html.twig:

<article class="optional_class_wrapper">
  {{ content.field_name }}
  {{ content.body }}
  {{ label }} 
  {{ content.field_name.0.value }}
</article>
1

I think this is the problem, you are trying to get the node from the route, only, you are not on a node route, you are on an entity_print route, so node is not available.

As a side note, you should always check that the field exists before trying to get the value. Before you try something like this:

$vars['field_name'] = $entity->get('field_name')->getValue();

You should do something like this:

if ($node->hasField('field_name') && !$node->field_name->isEmpty()) {
  $vars['field_name'] = $entity->get('field_name')->getValue();
}

But in this case, that probably wouldn't even prevent the error, since $node ( or $entity ) isn't even populated here.

What I've resorted to doing for entity_print preprocess functions is basically parsing the string URL. Your print path is something like /print/pdf/{entity_type}/{entity_id}, which contains all of the info you need.

/**
 * Implements HOOK_preprocess_entity_print__entity().
 */
function THEME_preprocess_entity_print__node(array &$variables) {
  $route = \Drupal::routeMatch();
  $entity_type = $route->getParameter('entity_type');
  $entity_id = $route->getParameter('entity_id');
  // double check that you are printing a node, not a view or something else.
  if ($entity_type == 'node') {
    $node = \Drupal::entityTypeManager->getStorage('node')->load($entity_id);
    if ($node->hasField('field_name') && !$node->field_name->isEmpty()) {
      $variables['field_name'] = $node->field_name->value;
    }
  }
}

Now you can access 'field_name' in your twig file just using {{ field_name }}, but once again, check that it's populated before trying to print or you could get another error.

entity-print.html.twig

{% if field_name %}
  {{ field_name }}
{% endif %}

Of course, this assumes 'field_name' is a single value field, not an entity_reference or other sort of complex field.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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