If you have a look at drupal_add_js, you notice that you're able to specify a $type of 'inline'. This means that instead of requiring yourself to stick your Javascript into a file, you can have it appear inline on the page in its own < script > tag. Having this capability for drupal_add_css would be very helpful when you want to display dynamic CSS:
$color = variable_get('mymodule_color', '#000000');
$css = "p {background-color: $color }";
drupal_add_css($css, 'inline');
As you can see, here we're setting the background color of every p tag to a user chosen color (in this case, black) from the variable table. Although this is a horrible example of what you could do with having include CSS capabilities with drupal_add_css, I believe it gets the point across.
This doesn't have to be actual inline CSS either, as we could just add it to the end of the already aggregated CSS file.
| Comment | File | Size | Author |
|---|---|---|---|
| #61 | drupal-core-add-inline-css-259368-61.patch | 12.19 KB | yannickoo |
| #60 | drupal-core-add-inline-css-259368-60.patch | 12.18 KB | b-prod |
| #49 | 259368.patch | 18.51 KB | robloach |
| #44 | drupal-259368.patch | 19.05 KB | robloach |
| #42 | drupal-259368.patch | 18.62 KB | robloach |
Comments
Comment #1
robloachMany modules would benefit from this, including CSS Injector.
I see inline CSS through
drupal_add_cssworking exactly how it does withdrupal_add_js. When aggregation is enabled, the CSS would be added to the aggregated CSS file. When aggregation is disabled, the CSS would be added directly to the page that's being rendered.Comment #2
robloachFirst hack at it to get this issue going. To test, do the following:
< style>tag.< style>tag, it adds it to the end of the aggregated CSS file.drupal_add_cssthat can add inline dynamic CSS.Comment #3
robloachRemoval of some debugging information.
Comment #4
a_c_m commentedUgly hack/work around, which i'm sure is the "wrong" way to do it, but it works for me.
Comment #5
guardian commenteddrupal_set_html_headimho has a bad name since it's really literally "Add output to the head tag of the HTML page."what you want is
drupal_set_html_head("<style type="text/css">$css</script>");Comment #6
robloachdrupal_set_html_headdoesn't add the CSS to the aggregated CSS file on the page, and is a horrible hack for adding straight CSS. If you use this hack eight different times to add single lines of CSS, then you end up with eight different < style > tags.Mind giving #3 a review? The patch still applies cleanly.
Comment #7
senpai commentedMarking for a review sometime this weekend.
Comment #8
senpai commentedComment #9
robloachNeeds update now that $options went in.
Comment #10
mfer commentedsubscribe.
Comment #11
robloachSticking the following in a node with CSS Optimization/Aggregation either on or off colours the special text red with a blue imaged backgrounds.
Attached is both the patch and a screenshot of what it looks like with aggregation both on and off.
Comment #12
robloachForgot to preprocess/compress the inline scripts when CSS Optimization is off.
Comment #13
robloachWhoops, @import's in .css files broke....
Comment #14
robloachThere we go. Forgot to change to the stylesheet's directory.
Comment #15
mfer commentedThis looks to work but, there are no tests against this functionality to test that it works. Can we get a test?
When CSS preprocessing is turned off the added css is inline. When CSS preprocessing is turned on the added CSS is appended to the preprocessed file. Is this the intent?
Comment #16
senpai commentedThat shouldn't be the case, no.
Also, what should we test?
Comment #17
robloachPreprocessed 'inline' CSS shouldn't be added to the aggregated file?
Comment #18
robloachSticking the following in a node with the PHP filter on and then hitting refresh a bunch of times is a good way to manually test it:
Comment #19
dawehnerthis patch seems to work here
there are some wrong spaces see
i wonders why you wrote "# Added a couple tests for the inline stylesheets" but there is nothing in the patch file
Comment #20
robloachAh damn, I created the tests, but forgot to send them into the patch. I'll hopefully have time to give this another hack this week sometime.
Comment #21
blueyed commentedWhat about letting the "preprocess" option default to TRUE for files and FALSE for inline code?
The reason for it is that "inline" style is probably more often random (and causes too much cache poisoning therefore).
Is that too much black magic?
You appear to use
$datafor both the outer and inner foreach loop now ("foreach ($types as $type => $data)"and "foreach ($types[$type] as $data => $preprocess)").Since the first
$datadoes not get used (but$types[$type]instead), it does no harm, but causes confusion and since it's not being used, I suggest changing it to "foreach (array_keys($types) as $type)".Comment #22
robloachWhen preprocessing is on, it will compress the inline CSS. When preprocessing is off, it won't compress the CSS. It shouldn't add it to the aggregated CSS file because the inline CSS should be able to change on every request made.
@blueyed, the ugly $data loops will be fixed when we hit #92877: Add numeric weight to drupal_add_css.
Comment #23
mfer commentedIn one of the test it says
I don't believe $css_preprocessed should be listed here.
Other than that, it looks good to me.
Comment #24
robloachWhoops, forgot to get rid of some debugging information. Thanks for eagle eyeing that.
Comment #25
AltaVida commentedSubscribe
Comment #26
mfer commentedLooks good, tests pass, manually tested and that passes as well.
--
Matt
www.mattfarina.com
www.innovatingtomorrow.net
www.geeksandgod.com
www.superaveragepodcast.com
Comment #28
robloachFixed the conflict with HEAD, needs a retest.
Comment #29
robloachSorry about that..... Forgot one $path to $data variable.
Comment #30
robloachNeeds update to HEAD.
Comment #31
robloachIncludes update to HEAD due to #345973: Move drupal_add_js $reset parameter as an option for $options['type'].
Comment #33
robloachResubmitting for review because it still applies cleanly, and the test failures were seemingly unrelated.
Comment #34
sunI had to read this sentence 3 times to understand it. Especially, since "type" seems to refer to $options['type'].
A few lines above, we are recommending to prefix filenames with the module's name. This example should adhere to that.
Can we stuff a "string" into that description to make the data type clear?
@param docs are not only using different indentation, but also a different layout for descriptions.
Not sure about the past tense of "output" here.
Please do not use abbreviations in comments. Also, this comment just duplicates what is obvious from reading in the next line. Comments should describe the how's and why's instead.
First line of PHPDoc blocks should not use the third form. Replace with "Process". "for optimization" is a bit confusing here.
$contents is the content? ;)
Lastly, there should be at least one test that verifies the real output and not a direct call to drupal_get_css().
Comment #35
mfer commentedComment #36
robloachThis patch takes tha_sun's documentation comments at #34 into consideration. It also adds a test that creates a node using the PHP filter which hits drupal_add_css('inline'), seeing if rendering the node results in the compressed CSS.
Comment #37
sunSorry, I should have made my point clearer:
Not so good:
Good:
Also, I think we should test the real, expected output, i.e.
Oh, and on a second thought, I think we want to throw a notice to
just like we do for inline JavaScript - in general, usage of 'inline' is not recommended.
Comment #38
sunDumdedumdedum....
"The path to the CSS file relative to the base_path()" - but "/modules/devel/devel.css" is _absolute_. :P
Comment #39
robloachApplies the indentation that sun recommended and tests against the full style tag with assertRaw.
Comment #40
robloachCompleting sentences is a good thing.
Comment #41
sunthen => than
Can we stuff single quotes around type here?
Missing punctuation.
"including any imported stylesheets via @import" (or similar) would make this a bit more grokable on first sight.
Afterwards, RTBC.
Comment #42
robloachDaniel gets "Drupal's Most Awesome Nitpicker Award!" :-)
Comment #43
sunSorry, just ...
"compressed" should probably be replaced by "aggregated". However, after reading the code, it seems like $optimize is neither of both, but the CSS is "minified" instead. Proposal:
Originally, I wanted to append "Defaults to FALSE.", but the recursive logic does not allow that...
Reading even more code, I would even say that for both functions, in reality, $optimize is not optional at all. It was just made optional to allow for the recursive calls (for imported stylesheets), but when directly called from elsewhere, the argument should always be passed?
Comment #44
robloachNow $_optimize defaults to FALSE, so we can essentially say that $optimize defaults to FALSE.....
This seems kind of bike sheddy, but you're right, it seems kind of weird. If you manage to write something better, then please do!
Comment #45
sun/me grins
Unfortunately, the second instance is not yet updated:
Comment #46
sunHrm. Basically, this would also make this obsolete:
However, I am not entirely sure whether we are overlooking a part of the logic that may was the reason for using NULL instead of FALSE by default. I grepped over core, but could not find a function that (is not in common.inc) and invokes drupal_load_stylesheet() without the second argument.
The only other is _drupal_load_stylesheet(). So I have to wonder whether it was implemented this way, because drupal_add_css() processed all CSS in a certain order, invoking drupal_load_stylesheet() subsequently, and (perhaps?) relying on a previously defined $optimize state?
Hint: This is what inline comments should really describe. "Store optimization parameter for preg_replace_callback with nested @import loops." explains nothing.
Comment #47
robloachI'm playing the Bike Shed/Kittens card here. The $optimization documentation error isn't really in scope with this issue anyway. It was a problem before this patch came into existence, and seems like a documentation/logic quirk that could be easily be resolved in a separate issue with a refined scope. Anyone mind giving a final review?
Comment #48
sunok, let's revert anything that has to do with the default value of $optimize (but keeping the "minified" term improvement). I'll do the final review.
Comment #49
robloachThis patch provides "minified" for
drupal_load_stylesheet_content, but leaves the documentation the same fordrupal_load_stylesheetas that function hasn't really changed at all on the API front.If this goes in, webchick, please add both mfer and tha_sun to the commit credit list. They were crazy awesome with code reviews and suggestions.
Comment #50
sunThanks!
This is ready to hit the core.
Comment #51
hass commentedI really hope you have thought about #228818: IE: Stylesheets ignored after 31 link/style tags... this is OT here, but as more style tags we add to a page - the sooner we are running into this critical issue.
Comment #52
robloachHi Hass.... All inline CSS is added into one style tag, so we're okay on that front.
Comment #53
hass commentedExcellent. THX.
Comment #54
owen barton commentedSubscribe - great work guys :)
Comment #55
sunCan we make this a bit more consistent while core maintainers are unavailable?
Otherwise, this looks really, really RTBCRTBC.
Comment #56
mattgilbert commentedsubscribe
Comment #57
webchickGreat work, folks! Committed to HEAD with some comment standardization, per sun.
Marking needs work until this is in the upgrade documentation.
Comment #58
robloachhttp://drupal.org/node/224333#drupal_add_css_inline
Comment #60
b-prod commentedFor those who are interested, here is a patch against 6.x-dev, adaptated from #49. I tagged the issue as "need review" but I don't really hope it will be back-ported.
Comment #61
yannickooThank you B-Prod for your patch. I just added the \n to line 148.
Comment #62
robloachNicely done on the patch. Think it needs a reroll?
Comment #63
robloach#61: drupal-core-add-inline-css-259368-61.patch queued for re-testing.
Comment #64
kenorb commented#61: drupal-core-add-inline-css-259368-61.patch queued for re-testing.