5

I'm trying to create a custom file-link.html.twig for a particular content type. I've looked at https://www.drupal.org/node/2354645 which doesn't link plugin theme twigs like file-link but tried file-link--<CONTENTYPE>.html.twig anyway. It doesn't work.

None of the variables passed include the node or content type. Any ideas on how to proceed?

3 Answers 3

9

There are a number of things you would need to do to accomplish this.

  1. Enable Twig debugging
  2. Create a hook theme suggestions preprocess function
  3. Get the node object within your theme hook.
  4. Craft the theme hook suggestion to get a template name with the node type in it.

Once you have Twig debugging enabled, you can inspect your file link. As a default for file_link, I see:

<!-- THEME DEBUG -->
<!-- THEME HOOK: 'file_link' -->
<!-- BEGIN OUTPUT from 'core/themes/classy/templates/field/file-link.html.twig' -->

In my case, I use Classy as a base theme for my sub-theme, thus the classy path above. but what is missing here is any useful theme hook suggestions out of the box. Next we will remedy that.

Since we are given the theme hook name above, I can craft the theme hook suggestion based on that and by getting the node type and incorporating it into the theme hook suggestion. (see function hook_theme_suggestions_HOOK_alter)

My theme hook alter then would be:

  function MYTHEME_theme_suggestions_file_link_alter(&$suggestions, $vars, $hook) {

  // Get the node type.
  $node = \Drupal::routeMatch()->getParameter('node');
  $type = $node->getType();

  // Create the theme hook suggestion. 
  $suggestions[] = 'file__link__' . 'type_' . $type;

}

Once I do this and drush cr, I will see my new theme hook template suggestion as such:

<!-- THEME DEBUG -->
    <!-- THEME HOOK: 'file_link' -->
<!-- FILE NAME SUGGESTIONS:
   * file--link--type-news.html.twig
   x file-link.html.twig
-->

In my case, my node type is "News" and you can see that in the template suggestion name:

file--link--type-news.html.twig

Now you can create that file and theme away! For more insight on this, I just wrote a blog post about this: Drupal 8 Theming Tutorial: How to Craft Custom Theme Hook Suggestions and Templates

1
  • Thanks for that! I had a hack where I added $variables['node_type'] via MYMODULE_template_preprocess_default_variables_alter but this is much more useful.
    – Nic
    Commented May 29, 2016 at 14:20
1

You have a great answer from @Danny-Englander how to get the theme suggestion for twig. But I think the question is too narrow, it should be broader, without twig:

How do I theme a file link for a specific content type?

To do this, put a class with the content type in the <article> tag in node twig and a class for the file link in file_link twig. Then use css to select all file links inside this article tag. You can use the same selectors for javascript.

If you use the classy theme you should already have set the classes.

The reason for this is, that the node can be displayed in different ways. For example as an entity reference or inside a view. Then you will get a wrong routeMatch or no routeMatch at all. By using the article tag you can deal with this flexible. You can have multiple nodes in one page and all can have different content types.

4
  • Thanks @4k4 but in this instance I wanted to create a different tag hierarchy for just one content type's link template
    – Nic
    Commented May 29, 2016 at 18:51
  • In this case, if you need a solution that works with entity references, views and different kind of layout solutions you would need a custom field formatter, which you put in manage display of the content type.
    – 4uk4
    Commented May 30, 2016 at 6:14
  • Actually I managed to get the content type into the default variables and did a conditional in the twig file
    – Nic
    Commented May 30, 2016 at 6:16
  • That's probably the easiest solution you can do in theming, I would post this as an alternative answer, for future reference.
    – 4uk4
    Commented May 30, 2016 at 6:23
1

I found a solution which worked in this situation, and so am posting for future reference.

I added this to our custom module:

/**
 * Implements hook_template_preprocess_default_variables_alter().
 */
function MYMODULE_template_preprocess_default_variables_alter(&$variables) {

  /** @var Node $node */
  $node = Drupal::routeMatch()->getParameter('node');
  if ($node) {
    $variables['nid'] = $node->id();
    $variables['node_type'] = $node->getType();
  }

}

then took a copy of file-link.html.twig into our custom theme, and added:

{% if (node_type == 'CONTENTTYPE') %}
    <a class="filelink" href="{{ link.url }}" title="{{ description }}">
        <img src="/const8/img/icon-pdf-128.png" alt="Download PDF" title="" class="img-responsive" style="float:right;">Download PDF
        <span class="visible-xs-inline-block">({{ file_size }})</span></a>
{% else %}
  {# All other content types.... #}

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.