Saturday 23 January 2010

How to insert a link tag in Blogger / Blogspot html - Hacking Blogger without JQuery



In my previous post I showed how it was possible to insert a CSS file into the head element of a Blogger / Blogspot page, at load time using JQuery. This is useful because Blogger does not allow you to add <link> tags in the "Edit HTML" tab.

I decided that JQuery was a bit overkill. Ok shitloads overkill. It's better to just do it with a small amount of javascript. The following code will insert a <link> tag into the head at load time.

function insertCSS(filename) {
    var link = document.createElement("link")
    link.setAttribute("rel", "stylesheet")
    link.setAttribute("type", "text/css")
    link.setAttribute("href", filename)
    document.getElementsByTagName("head")[0].appendChild(link)
}
insertCSS("http://your.site/tools/libraries/prettify.css");

I'm talking within the context of being able to prettyprint your code, so I put this code into a file called bloggerPrettifyHack.js. This allows me to simply include 2 javascript files - bloggerPrettifyHack.js, and prettify.js.
<script type="text/javascript" src="http://your.site/tools/libraries/bloggerPrettifyHack.js"></script>
<script type="text/javascript" src="http://your.site/tools/libraries/prettify.js"></script>

Then at the bottom of my page I make the call to colorize :)
<script type="text/javascript">
  prettyPrint();
</script>

Note: I tried to add the prettify.js file dynamically using the same technique. It loads just fine, however the pretty-printing doesn't work. I'm guessing it's something to do with event firing. Ideally I'd like to have a single .js file to which does everything. Can someone can provide a quick (not too nasty) workaround?


Update:
Due to a few code posts, I noticed multiple duplicates of the CSS file in the <head> tag. Also the prettyprint.js was seen in the content sections of each post. To combat this I decided to do a simple check and delete. Here's the modified code.
function insertCSS(filename) 
{
    var inHead = alreadyInHead(filename);    
    if (inHead == true)
        return;
    
    var link = document.createElement("link")
    link.setAttribute("rel", "stylesheet")
    link.setAttribute("type", "text/css")
    link.setAttribute("href", filename)
    document.getElementsByTagName("head")[0].appendChild(link)
}

function alreadyInHead(filename) {
    var links = document.getElementsByTagName('link');
    
    for (var i = 0; i < links.length; i = i +1)
    {
        var link = links[i];
        var href = link.getAttribute("href");
        if (href == filename) {
            return true;           
        }
    }
    return false;
}

function remove(filename) 
{
    var scripts = document.getElementsByTagName('script');
    for (var i = 0; i < scripts.length; i = i + 1) {
        var node = scripts[i];
        var src = node.getAttribute("src");
        if (src == filename) {
            node.parentNode.removeChild(node);
            i -= i - 1;
        }
    }
}

insertCSS("http://your.site/tools/libraries/prettify.css");
remove("http://your.site/tools/libraries/bloggerPrettifyHack.js");
remove("http://your.site/tools/libraries/prettify.js");

I'm still cringing because there are still multiple calls of prettyPrint(). Can anyone help out with this one?

No comments:

Post a Comment