0

I would like to add custom property on drupal's stylesheets <link /> tag. I tried following in hook_css_alter:

foreach ($css as &$style) {
  $style['#attributes']['property'] = 'stylesheet';
  $style['#attributes'] = ['property' => 'stylesheet'];
  $style['property'] = 'stylesheet';
  $style['element']['#theme'] = 'stylesheet';
  $style['#markup'] = '<stylesheet />';
  $style['element']['#markup'] = '<stylesheet />';
}

Nothing seeps to do any changes, and I feel like I am guessing around. So how to properly alter <link /> elements markup?

Second question would be how to get all stylesheets as array in theme. It seeps that in Drupal 8 beta 10 you cloud just do {% for style in styles %} in Your twig template, but with beta 12 update this does not work, styles returns placeholder element.

3
  • I don't have the answer (don't have time to check just now either), but just so you're not heading down the wrong path: there's no template_css_alter(), you're probably thinking of hook_css_alter() which isn't meant to control the associated markup as far as I know
    – Clive
    Commented Jul 1, 2015 at 10:21
  • Yeah, hook_css_alter, thanks for noticing :). BTW is there any documentation which functions are available in .theme file, and witch only in .modules (only in modules)? I thought that functions starting with template_ are meant to use in template and hook_ are meant to be used in modules, but now I know I was wrong Commented Jul 1, 2015 at 10:24
  • Added an answer, but I saw later that this was for D8, if you have any trouble swapping the service, I can provide an example
    – SebCorbin
    Commented Jul 1, 2015 at 12:35

1 Answer 1

4

Drupal 8

$css variable is converted to an array of <link> tags through CssCollectionRenderer::render(), so you just have to swap this service (https://www.drupal.org/node/2026959) and override render function:

class MyModuleCssCollectionRenderer extends CssCollectionRenderer {
  /**
   * {@inheritdoc}
   */
  public function render(array $css_assets) {
    $elements = parent::render($css_assets)))
    foreach($elements as &$elements) {
      $element['#attributes']['property'] = 'stylesheet';
    }
    return $elements;
  }
}

Drupal 7

The CSS files are managed by drupal_get_css. After being altered by hook_css_alter(), $css is passed in a render array:

// Render the HTML needed to load the CSS.
$styles = array(
  '#type' => 'styles',
  '#items' => $css,
);

This render array is declared in system_element_info() as:

$types['styles'] = array(
  '#items' => array(),
  '#pre_render' => array('drupal_pre_render_styles'),
  '#group_callback' => 'drupal_group_css',
  '#aggregate_callback' => 'drupal_aggregate_css'
);

As you can see there is a pre-render callback drupal_pre_render_styles(), this is the function responsible for converting the $css variable to <link> tags. This is where you can work, just add you own callback in a hook_element_info_alter():

/**
 * Implements hook_element_info_alter().
 */
function mymodule_element_info_alter(&$types) {
  // Add a pre_render callback to styles.
  $types['styles']['#pre_render'][] = 'mymodule_pre_render_styles';
}

/**
 * Append property to stylesheet <link> tags.
 */
function mymodule_pre_render_styles($elements) {
    foreach($elements as &$element) {
        $element['#attributes']['property'] = 'stylesheet';
    }
}

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.