Hello everyone!
Ive been working on a module that implements shortcode functionality (like in wordpress) to replace shortcode tags with html code and do other fancy things...
The module uses the Drupal Filter API to implement a Filter which than can be used by other modules to add custom shortcode tags. For example a second module could use hook_shortcode_info() to add, let's say, a jQuery shortcode like [accordion id="accordion-div" /] which would then be replaced by the filter and the javascript would be added by drupal_add_library('system', 'ui.accordion');.
This all works very well: The shortcode is found by the regex and the callback function for the shortcode is being called with all the information it needs (attributes, tag name and so on). Just replacing the tag with html is no problem at all, the problem begins when I also want to add css, javascript, or libraries.
When I install the modules for the first time, clear the cache of the drupal installation and open a page that contains one of the shortcodes it all works very well. But then, when I reload this page the Javascript and CSS files are not being loaded anymore. I've traced this down to field cachin (cache_field in the database). The node's content field is being cached and therefore the functions that would normally replace the shortcodes in the content of this field do not get called once again. Therefore the drupal_add_library() aswell as the drupal_add_js() are not called.
Clearing the cache makes the javascript content visisible again for the first page visit, afterwards its gone again until I clear the entire cache or just delete the cache_field entry for the node.
This seems very weird to me as I really thought that drupal would remember which external js files and inline js code it loaded during a page call, but it doesn't.
Does anyone maybe have an idea on how to fix this the "neat" way?
Here is the code for the two modules I am working on:
Shortcode Module: http://pastebin.com/ixf2wpcX
SlideshowPro Module: http://pastebin.com/n6cH3yjJ
The "SlideshowPro Module" replaces the shortcode [slideshowpro id="#" type="#" width="#" height="#" layout="#"][/slideshowpro] width the
SlideshowPro Gallery from my SlideshowPro Director installation and loads the .swf using the javascript functionality that the js file from slideshowpro_library() provides. As I already said, this works all to 100% on the first page call but disappears on the second call as the page (and the field content!!!) is being loaded from cache which causes drupal to skip the functions and thus also skip the drupal_add_library call.
Is it a bug that the javascript files are not being remembered by drupal?! I really DON'T want to include the inline javascript with a theming function and I don't want to include the javascript files on the theme layer and also not in "hook_init()" as I don't want to load it on every single page.
Thanks for your help!
Comments
I don't have a specific
I don't have a specific answer to your question, but I have found that it's best to use drupal_add_css() and drupal_add_js() in either the theme function, or the preprocess function when using a template. These are not cached, and as such your code will always be added.
Contact me to contract me for D7 -> D10/11 migrations.
I've tried to remove the
I've tried to remove the
theme_slideshowpro()function, added'template' => 'slideshowpro'toslideshowpro_theme()and created a template file that contains the html markup for the slideshow container so it loads that file instead of the plain theme function. Yet the field content is still being cached and the functions are not loaded. Did you mean this by "when using a template" or what were you getting at? Thanks for the help btw. ... I am really stuck on this issue for like 3 days now :PWhere are you using your
Where are you using your drupal_add_css() and drupal_add_js? In the template?
Contact me to contract me for D7 -> D10/11 migrations.
I tried to use it in
I tried to use it in "hook_preprocess_HOOK" and "template_preprocess_HOOK" and "theme_hook" and in the template file itself (in the module). All didn't work (on the page reload the js and css file are gone).
Maybe this is caused by the fact that the the module is basically a filter and the callback function therefore only gets called when the content is loaded for the first time? Afterwards its in the cache and therefore doesnt get called anymore... I still dont understand why the cache itself doesnt have functionality to remember drupal_add_js and drupal_add_css?!
All templates have a
All templates have a preprocess function. The name of the preprocess function will be determined by the theme name that calls the template.
For example, look at this example:
In this hook_theme(), the theme name is 'some_template_theme'. To add javascript, I would then use the following:
Edit: you'll need to clear the cache after writing this function. It won't be called until the cache is cleared.
Contact me to contract me for D7 -> D10/11 migrations.
Hey! Yes I know that ;), that
Hey!
Yes I know that ;), that function is called "template_preprocess_HOOK" and I already tried it (mentioned that in my previous post), but its also cached (it seems) and therefore not called for a second time :(. I do clear the cache of course and the only time the drupal_add_js works is on the first page call after I cleared the cache. The template_preprocess_HOOK function, like all the others, is not called for a second time!
preprocess functions are not
preprocess functions are not cached. Unless *maybe* you have agressive caching turned on (I haven't tested that). Are you sure your preprocess function was even being called? Add a die() statement to it to see if it is being called or not.
Contact me to contract me for D7 -> D10/11 migrations.
Since its a FILTER that runs
Since its a FILTER that runs on the text content of the node (the "body" field of the node) for one time when the node is being viewed for the first time the filtered content is afterwards cached in "cache_field". I do understand that the filter is not applied for a second time unless the cache is cleared again. What I do NOT understand is that the js files and css files that are being added to the page with drupal_add_library, drupal_add_js and drupal_add_css are NOT being remembered by the cache. When the filter initially loads them because he came across some textual content that he wants to replace with html and js (added by drupal_add_js) drupal _should_ imo write the js file into the cache aswell (maybe in some sort of list of js files that need to be loaded for the page). NONE of the template, theming or preprocess function are called when the page is being loaded for a second time because its just not necessary (from the content point of view), but the js is forgotten. Thats weird!!!!
JS/CSS in hook_init()...
This is why in most cases you want to add your JS and CSS code in your hook_init() function. It sucks because you may end up loading those 1,000,000 times when only necessary 10 times. But the cache isn't smart enough to know when JS/CSS files are being added and then cached here or there. That would require true object oriented programming which Drupal is far off still.
By the way, the filters cache can be turned off with a
case 'nocache': return FALSE;entry. Yet that prevents the caching of your page by the default performance cache system. Which is annoying. Boost will still cache your pages however, but in that case, the CSS and JS are cached along the output. Boost may be your answer.Good luck.
I have a shortcode module
Hi, I wrote a shortcode module. I am testing it now.
It based on the wp's shortcode, but it is a full drupal version now. Plus, I rewrote the whole wp shortcode engine so it is support now the full nested shortcodes.
I am starting to contributing it. But I want to check module duplication before. I think there are a few module with the partial shortcode implementation, but I have to check it.
http://drupal.org/project/shortcode
It contains mistakes, I am not expert with cvs.
--
Denes Szabo - http://internode.hu