views:

147

answers:

4

I want to load an external script in <head>. It is module specific so I want my module to take care of the loading.

In Drupal 6, function drupal_add_js() does not allow to add an external script in <head>. It will be available in Drupal 7 passing the "external" argument to the function. In D6, I can use drupal_set_html_head() instead, but it inserts the given data in the beginning of the <head> which I don't want. I'd like to append data in it.

It turned out that drupal_html_set_head() appends data.

$stored_head .= $data ."\n";

So the behavior I experimented--data was inserted in the beginning of head data--should come from that I call drupal_html_set_head() in my module's hook_init() function.

How can I append data to the very and of <head>?

+2  A: 

There are multiple solutions to work around the problem.

  • use hook_footer() to add the js to the footer
  • make a small jquery script, which creates the <script> element and adds it to <head>
  • do it with a template preprocess function
  • make your own page.tpl.php
Yorirou
NB: I want to insert script in `<head>`.
Török Gábor
I implemented the `template_preprocess_page()` hook and it works nice.
Török Gábor
A: 

Did you see this comment?

http://api.drupal.org/api/function/drupal_set_html_head/6#comment-2083

Kevin
@Kevin: it tells me how to use it correctly. *I use it correctly.* It's normal behavior to prepend data in `<head>`. I want to **append it**.
Török Gábor
@Török Gábor you are in bad luck then. sorry. Drupal uses the .= operator, prepending it. appending is simply not possible in a _correct_ way.
berkes
Oh, sorry, did not see that part.
Kevin
@Kevin, @berkes: i was wrong. It uses the `.=` operator so it *appends*. I call `drupal_set_html_head()` inside `hook_init()`, may be that's the reason.
Török Gábor
+1  A: 

Drupal uses the .= operator to create the $head variable. The $js and $css is kept in an array, and allows you to be re-orderd. $head is a string, and cannot be re-orderd, othern then by ugly, error-prone hacks. Such as regular-expression explosions, re-ordering and imploding.

$heads = preg_explode("\n", $head);
ksort($heads);
$head = implode("\n", $heads);

in your theme's variable pre-processor.

berkes
+1  A: 

The default page.tpl.php (you can find it in /modules/system/page.tpl.php is this:

<head>
  <title><?php print $head_title; ?></title>
  <?php print $head; ?>
  <?php print $styles; ?>
  <?php print $scripts; ?>
  <script type="text/javascript"><?php /* Needed to avoid Flash of Unstyled Content in IE */ ?> </script>
</head>

When you make drupal_set_html_head() it is appending stuff to variable $head, but still there are more variables appended as you see.

One possible solutions is to append the stuff that you want to $scripts, instead of $head.

How?

with a preprocess function from your module:

function MYMODULE_preprocess_page(&$variables) {
    $variables['scripts'] .= $your_stuff;
}

I didn't try this solution, but if doesn't work maybe is because the order of execution. Try to set your module's weight higher, so it will run after the system_preprocess_page.

Other reason why may not work is because the theme is printing the variables in different order in page.tpl.php. But you can't control this from the code of a module.

corbacho
This is the option I chose. Thanks for the detailed explanation.
Török Gábor

related questions