0

I have a page on drupal 7 where I have the text format set to PHP Code. I am using the drupal_add_html_head() to include a few CSS/JS files, and an RSS link. My problem is that everything I add with drupal_add_html_head is only visible for a single view after the caches are cleared. After that single view they do not show up in the view source.

It can be demonstrated with a Body that is as simple as below. The first view will show an alert. If you reload the page, the script is not added, and alert() is not called.

<?php
drupal_add_html_head(array(
  '#tag' => 'script', 
  '#value' => 'alert("Hello world!");',
  '#attributes' => array(
    'type' => 'text/javascript'
  )
), 'jscripttest');
?>

You should see "Hello world!"  But you don't unless you have just 
cleared the cache.

I have also tried drupal_add_css, and drupal_add_js with similar results. The CSS/JS is displayed after the cache is cleared, but only once.

6
  • Why not just add it from template.php? – vintorg Jun 18 '13 at 1:38
  • I only want it to show up on a single page. – Zoredache Jun 18 '13 at 1:39
  • 2
    @vintorg, lets assume for the sake of argument that I want to do it this way, because I want to do it this way. Are you saying what I want to do cannot possibly work? Do you have a reference document you can point me at that will tell me what features I cannot call from within a page? This isn't my Drupal setup really. I am just trying to include something on a page that requires JS/CSS files be loaded in the <head> in the most minimalistic way possible. I don't think I even have access to the template.php. – Zoredache Jun 18 '13 at 1:46
  • 3
    I'm saying it doesn't feel right to me to call drupal_add_js from a PHP filter (even though you can). There can be a million things going on and tracking down why the caching is doing what it is doing can be a lengthy investigation. – vintorg Jun 18 '13 at 1:51
  • 2
    Completely with vintorg here. There are so many problems with "text format set to PHP Code" that I just stopped there. – Letharion Jun 18 '13 at 11:35
3
+25

This is a totally valid question in my opinion. Using the PHP input filter (or eval() in general) is almost never a good idea, but the fact that this code only runs once is not intuitive.

That said, I actually can't reproduce this.

My first thought was that the rendered HTML was being cached in the cache_filter table. But by default, the PHP Input filter is not cached in the cache_filter table. php_filter_info() from php_module:

function php_filter_info() {
  $filters['php_code'] = array(
    'title' => t('PHP evaluator'),
    'description' => t('Executes a piece of PHP code. The usage of this filter should be restricted to administrators only!'),
    'process callback' => 'php_eval',
    'tips callback' => '_php_filter_tips',
    'cache' => FALSE, // <- This is set to FALSE in the module
  );
  return $filters;
}

My next guess was that the anon user Page Cache was somehow ignoring the fact that those functions had been called. But I tested both drupal_add_html_head and drupal_add_js (the latter with both an external file and inline JS) and even for anonymous users, the JS was loaded and executed on all page views with and without the page cache enabled. I also tried all of these scenarios in the default body field and with a field added with the Field API.

I guess that means that my answer is one of the following:

  1. Something is overriding php_filter_info() to set 'cache' => TRUE
  2. You have an additional layer of caching that's causing this on your server
  3. Something else???
2
  • I actually can't reproduce this. -- Oh, how frustrating. You seem to be right. I setup a clean drupal 7 instance locally, and this seems to reliably work. Now I get to either try to track down what is causing the problems, or try and convince my client to do it another way... – Zoredache Jun 18 '13 at 21:30
  • Some troubleshooting ideas. For #1 above: what modules are enabled? Anything that might override the cache settings for the php input type? Check the cache_filter table to see if there is an entry for that node. For #2 above: is there an additional level of caching? Perhaps APC, memcached, or Drupal's contrib module Boost? (I'm not saying that any of those would necessarily cause this behavior, just brainstorming) – Adam Balsam Jun 18 '13 at 23:14
2

In template.php:

function YOURTHEME_preprocess_page(&$vars, $hook)
{
     $req_path = request_path();

     switch ($req_path)    // in your case, the /some-path-that-you-want
     {
         case 'your-path':
             drupal_add_js('/path/to/your/js/foo.js');
         break;
     }
}
0

Try drupal_add_css() and drupal_add_js(), but set the 'every_page' flag to true.

every_page For optimal front-end performance when aggregation is enabled, this should be set to TRUE if the JavaScript is present on every page of the website for users for whom it is present at all. This defaults to FALSE. It is set to TRUE for JavaScript files that are added via module and theme .info files. Modules that add JavaScript within hook_init()

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.