Mecha CMS

Mecha CMS blog and documentation.

About the Custom Fields’ CSS and JavaScript Tags

Updated: Sunday, 07 August 2016

Can I write my custom CSS and JavaScript data without having to wrap it in the <style> and <script> tag, and then display it along with the <style> and <script> tag that wraps automatically?

Previously, I have discussed about the reason why I did put an empty <style> and <script> tag in the custom CSS and JavaScript field with a person in the GitHub issues page. I have a good reason for that.

The reason why I put the <style> and <script> tag inside the custom field by default is because I want my users to be able to put another HTML tag in it. For example, with my specifications, users can do something like this in the custom CSS field:

<meta name="author" content="Foo bar">
<link href="{{asset}}default.css" rel="stylesheet">
<style>
/* Custom CSS goes here … */
</style>

… and also can do something like this in the custom JavaScript field:

<div id="fb-root"></div>
<script>
(function(d, s, id) {
    var fjs = d.getElementsByTagName(s)[0], js;
    if (d.getElementById(id)) return;
    js = d.createElement(s);
    js.id = id;
    js.src = '//connect.facebook.net/id_ID/sdk.js#xfbml=1&version=v2.0';
    fjs.parentNode.insertBefore(js, fjs);
})(document, 'script', 'facebook-jssdk');
</script>

Placing the <style> and <script> tag outside the field data (inside the PHP file of the shield) will only restrict the creativity of the users. I feel that it is better to keep my users to write the <style> and <script> tag multiple times.

The only way I can do to tell the users that a <style> and a <script> tag is required inside the custom CSS and JavaScript field is by creating an empty <style> and <script> element as a default placeholder.

But, if you really really really want that behaviour, there is actually a simple solution to solve the problem without having to touch the CMS core. The trick is to use a filter.

First of all, we need to check whether the custom CSS and JavaScript data already wrapped by a <style> and <script> tag. If not, wrap them with a <style> and <script> tag prior to shipping:

Filter::add('custom:css', function($content) {
    // Check whether the data hasn’t
    // been wrapped by a `<style>` tag
    if(strpos($content, '</style>') === false) {
        // Wrap them with a `<style>` tag
        return O_BEGIN . '<style media="screen">' . NL . $content . NL . '</style>' . O_END;
    }
    return $content;
});

Filter::add('custom:js', function($content) {
    // Check whether the data hasn’t
    // been wrapped by a `<script>` tag
    if(strpos($content, '</script>') === false) {
        // Wrap them with a `<script>` tag
        return O_BEGIN . '<script>' . NL . $content . NL . '</script>' . O_END;
    }
    return $content;
});

That’s all.

Donation and Email Subscription