canton7 / fuelphp-casset

Better asset management library for fuelphp (with minification!)
MIT License
103 stars 29 forks source link

Add compatibility for inline JS/CSS groups #40

Open benswinburne opened 11 years ago

benswinburne commented 11 years ago

It'd be nice to be able to render groups of inline JS/CSS much like you can with the standard groups.

The reason for this is for example outputting non jQuery related global vars in the header i.e.

var basePath = '/path/to/scripts';

And then also the ability to add some bits after the group in which jQuery is rendered.

\Casset::render_js_inline('without_jquery');
\Casset::render_js('footer'); // includes jquery and other JS which relies on JS from without jQuery inline group like paths for ajax requests etc
\Casset::render_js_inline('with_jquery'); // includes inline js included from within controllers etc which relies on jquery.
</body>

It'd also be nice given the above if dependency support for inline groups might be included too.

Cheers

Ben

canton7 commented 11 years ago

I'm not going to be at a machine with a web stack on it for a few days, but until then...

Are you getting confused between the (confusingly named) inline groups, and the js_inline() / render_js_inline() function pair? The former are normal groups - they consist of files, have deps, etc, except that they are rendered inline. The latter is a fairly basic mechanism for including JS (or CSS) which doesn't come from a file.

You should be able to define three groups (without_jquery, footer, and with_jquery), setting the 'inline' property on the former and latter to 'true', then just render them one after another? i.e.

\Casset::render_js('without_jquery');
\Casset::render_js('footer');
\Casset::render_js('with_jquery');

Mind you, it's been a while since I used Casset, so I could be wrong.

Thinking about it, I can't see the point of being able to define a JS string to be included, and being able to specify dependencies on that string. You might as well just enable those groups. Adding random JS strings to an existing group might be handy, but could well be more effort than it's worth.

benswinburne commented 11 years ago

I'm not confused about the naming of the groups but perhaps I'm just going about my implementation the wrong way. To achieve what I'd like with the groups as they stand now I'd have to write CSS/JS to files so that Casset could include them as part of the group.

Perhaps if I explain the functionality/use case properly rather than trying to abstract it, it'll give you a better understanding.

I have a modular application, which outputs some inline JS in the head such as paths. These can't be saved to a file because they change depending on the installation directory or the currently enabled language etc. The various modules output the variables or bits of code they share.

<script type="text/javascript">
var base_url = 'http://localhost/application/public/';
var active_language = 'en';
var drag_rest_location = "api/v1/actions/test/reorder";
</script>

Now that we have these variables they can be used in other bits of Javascript in any of the groups- great.

jQuery (and other scripts) ideally need to be output just above the </body> tag, so I can render a footer group there for example.

<head>
    \Casset::render_js_inline();
</head>
<body>

    \Casset::render_js('footer'); // Includes jQuery
</body>

But now if I decide that I need to allow a module to output some inline JS but some which relies on jQuery then It appears above the inclusion of jQuery. Similarly, render_js_inline() can cause race conditions when a bit of inline relies on another bit of inline JS, i.e. a modular dependency. There's no way to guarantee that the required inline JS has been output.

The only way to get around the former issue at the moment is as follows. But this doesn't alleviate the inline JS dependencies problem.

<head>
    \Casset::render_js('jquery'); // includes jQuery
    \Casset::render_js_inline();
</head>
<body>

    \Casset::render_js('footer'); // No longer includes jQuery but group has deps => jQuery
</body>

As I say, perhaps I'm looking at this all wrong. If you could provide some insight that'd be much appreciated.

Cheers

canton7 commented 11 years ago

One clarification: when you say "But now if I decide that I need to allow a module to output some inline JS", is that inline JS which can be put in a file, or is that generated at run-time as well?

benswinburne commented 11 years ago

Generated at runtime too. For example I have a WYSIWYG module which can be switched out with various different JS implementations depending on client settings- it determines if there are any instances of Fieldset_Field with the class wysiwyg and it gets their id attribute and generates things like

$(document).ready(function() {
    $('#fieldset-field-id').wysiwyg()/redactor()/ckeditor(); //etc 1.n times
    // or 
    $('.wysiwyg')..wysiwyg()/redactor()/ckeditor(); // etc
});

There are other modules which do similar things but this is just one of the examples.

benswinburne commented 11 years ago

Any word on whether or not you're considering this?

Cheers