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>?
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.
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
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.
Did you see this comment?
Beware when using this to set an external js file call in D6, eg:
drupal_set_html_head('');
If you don't include a full script closing tag (ie ), it will
break in Firefox (and possibly other browsers, webkit-based ones seem
fine). The tag will fail to close, and will wipe out any other headers
up to the next available tag. This usually results in all
your css files failing to load, plus the next fully-tagged js file. So
use this form instead:
drupal_set_html_head('');
This applies up to and including Drupal 6.16. You can overcome it in
D7 with the new external option in drupal_add_js.
Related
I want to extend default layout and add section for layout But I don't want to use Blade Syntax. As in phpstorm Blade syntax generates errors and IDE stop auto completion and also stop recognizing php tags at all(only after I use # symbol in action()).
So my question is how can I convert
#extends('layouts.default')
#section('content')
#stop
into php tags.
Looking at Laravel's source code (Illuminate\View\Compilers\BladeCompiler) it's:
#extends('layouts.default')
This is the trickiest part. Normally, when you use #extends Laravel compiles it to this: but adds it to a footer variable that's echoed at the end. If you add it at the end of your view instead of the beginning it should work too. (At least it worked in a simple test I did)
<?php echo $__env->make('layouts.default', array_except(get_defined_vars(), array('__data', '__path')))->render(); ?>
#section('content')
<?php $__env->startSection('content'); ?>
#stop
<?php $__env->stopSection(); ?>
However if you're on PhpStorm 8, the Blade syntax is actually supported and I never had a problem with it. What's new in PhpStorm 8?
I'm really confused what my Wordpress does with css... I have a plugin that is loading a css using this script:
wp_enqueue_style('shutter', NGGALLERY_URLPATH .'shutter/shutter-reloaded.css', false, '1.3.2', 'screen');
I recently changed the css and now it seem's to be loaded twice. First the older css, then the changed css. On FTP I just see one file.
Why is it behaving like that und how can I fix it?
It's definitly not a Browsercache problem, I tested it in several browser and cleared the cache several times...
Yes, this css cache issue is always make me mad before. But I find the solution.
I don't know how to put it on your function, but here is the idea:
Give command to your html to call new css everytime you modified the css file, call the css with something like "style.css?1202122354" instead of only "style.css". "1202122354" is last modified datetime on style.css
In my header themes, I ussually use this to call my CSS file:
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); echo '?' . filemtime( get_stylesheet_directory() . '/style.css'); ?>" type="text/css" media="screen, projection" />
check out the php functionfilemtime( get_stylesheet_directory() . '/style.css') is outputting last modified time for style.css
Hope you catch the idea, sorry don't know how to put it on your function :D
Is there any way of disabling a stylesheet in view.yml for a specific action in Symfony?
For example I've got this in my view.yml:
default:
stylesheets: [default.css]
I want to be able to do something like:
displaySuccess:
stylesheet: [!default.css]
to disable default.css in displaySuccess only
Is this possible or do I have to explicitly say which modules/actions should have default.css?
You can remove or add stylesheets to a modules view.yml by doing the following:
displaySuccess:
stylesheet: [-default]
would remove default.css from the display action. Simply putting
displaySuccess:
stylesheet: [-*]
would remove all stylesheets.
to remove for example, unecessary /sfDoctrinePlugin/css/default.css, now you can overwrite the backend styles with your own!
maybe put it into yout layout.php:
<?php sfContext::getInstance()->getResponse()->removeStylesheet('/sfDoctrinePlugin/css/global.css'); ?>
<?php sfContext::getInstance()->getResponse()->removeStylesheet('/sfDoctrinePlugin/css/default.css'); ?>
I'm not 100% certain, but I believe the compiled view.yml file is processed before execution of the action. If that's true, you can do:
public function executeDisplay()
{
$this->response->removeStylesheet('default.css');
}
I find view.yml to be a little inflexible. You may find it easier to have a global "head" template that gets included in your layout(s). Then you can check sfConfig values to see if you should include individual files, making it easier to turn them on and off.
I am trying to remove the default lightbox.js file coming from the Lightbox2 module, by using template.php, and load in my own. I would like to do this via template.php if possible, and not place this code in a custom module. I am adding my javascript file, then unsetting the module javascript file. The problem is $vars['scripts'] isn't getting replaced with the output from $js, and still outputting the module javascript. krumo($js) shows the default lightbox.js removed. Below is what I have in template_preprocess_page. Thanks in advance.
drupal_add_js(path_to_theme() . "/resources/js/lightbox.js", 'theme');
$js = drupal_add_js(NULL, NULL, 'header'); //get header js files in an array
$lightbox_path = drupal_get_path('module', 'lightbox2');
unset($js['module'][$lightbox_path . '/js/lightbox.js']); //unset lightbox default js
$vars['scripts'] = drupal_get_js('header', $js);
Alright, let's take another look at it, then.
Having just looked at http://api.drupal.org/api/function/drupal_add_js/6 a second time, I note that the lightbox code is probably in
$js['header']['module'][$lightbox_path .'/js/lightbox.js']
and not in
$js['module'][$lightbox_path .'/js/lightbox.js'].
I suggest sneaking a dpm($js) in before your 'unset' call, and then hit refresh a couple of times until it shows up, and make sure you've got the exact correct combination of $scope and $type to find the lightbox code at.
(Note: dpm() is a function provided by the devel module, which I guess I'm assuming your'e already using. If you're not, then drupal_set_message('<pre>'. print_r($js, TRUE) .'</pre>); will do as well.
In my application I am allowing users to upload their css style sheets so they can applied to templates. The css is written as an internal style sheet, because at this time I would not like to expose the css style sheet to other users.
That creates room for users to include malicious code into the css file. Initially my plan was to convert all '<' and '>', but that is needed in the css syntax. I am after a white list solution, since it won't be feasible to exhaustively eliminate unwanted characters.
Any suggestions for implementing security measures to this scenario?
You should definitely also filter out at least IE expressions and FF -moz-binding properties... both can be used to run (potentionally malicious) javascript using css.
This cheat sheet contains the most obvious XSS tactics, including some CSS ones.
The safest solution would probably be whitelisting as you suggested (if it is acceptable to limit users to only use whitelisted properties).
I implemented a filter that replaces all < characters to <. The reason is that CSS does not need the < character; the only character it needs is the > which is used for child selectors.
That way users cannot open tags to write malicious code.
I am more than happy to consider any other/better solutions.
Dont allow users to upload a CSS FILE, make an interface that generate the CSS files dynamicly based on the options selected by the user. The options you allow. then you can make a fisical CSS file or you can make a dynamic application who writes CSS based on that configuration, this avoid to have lots of CSS files on the server... its another approach and you dont need to check every posible XSS exploit, its more easy to define what is allowed than parsing CSS and rejecting some dangerous code.
Use CDATA and escape the terminating sequence (]]>). I'm not sure about browser compatibility, though.
Example (untested):
<?PHP
function strReplaceAll($needle, $replacement, $haystack)
{
// Check for infinite loop. (NOT FOOL PROOF!)
if(strpos($replacement, $needle) === FALSE)
return;
$numReplacements = 42;
while($numReplacements)
{
$haystack = str_replace($needle, $replacement, $haystack, &$numReplacements);
}
return $haystack;
}
?>
<style type="text/css">
/*
<![CDATA[
*/
<?PHP echo sstrReplaceAll(']]>', '', $userCss); ?>
/*
]]>
*/
</style>