Personal tools
You are here: Home Documentation How-tos Add an Icon or Text next to hyperlinks similar to the globe icon on external hyperlinks
Support

Get Help

Join our chat rooms or support forums if you have more specific questions.

Plone Training
Learn how to design, build, and deploy a website in Plone through one of the numerous Plone training sessions around the world.
Find Plone training…
 
Document Actions

Add an Icon or Text next to hyperlinks similar to the globe icon on external hyperlinks

Warning: This item is marked as outdated.

This How-to applies to: Plone 2.0.x
This How-to is intended for: Integrators, Customizers

This how-to describes a simple method to automatically add an icon or text next to hyperlinks (similar to the external link globe icon feature)

By default, Plone has a very nice way of automatically adding icons next to documents and hyperlinks. It does this using a combination of CSS and JavaScript.

Sometimes we need to extend this feature to cover other document types. For e.g., I wanted to display an icon next to every PDF document to make the users aware that clicking on the link will actually download a PDF. Here's how I did it.

Assumptions:

A PDF file is recognized not by mime type or any other sophisticated method but by verifying that the last 4 characters in the file name are '.pdf'. If you use a different naming convention or use shortnames to refer to your files, you may have to tweak the logic.

  • Note: While this how-to uses a PDF file as an example, it can be applied to any other extension as well.

So, say you want to display a small PDF icon next to your PDF files. Try this.

Step 1

The JavaScript file at /Plone/portal_skins/plone_ecmascript/plone_javascripts.js has the function defined to dynamically check every hyperlink in the content and apply the appropriate CSS classname to the hyperlink. The CSS property in turn uses the background image property to display the icon. You can check it in the plone.css file typically at /Plone/portal_skins/portal_styles/.

We want to customize the plone_javascripts.js. I copied the file to my custom skin folder and modified the scanforlinks() function as follows:

function scanforlinks() {
    // securing against really old DOMs

    if (! document.getElementsByTagName){return false};
    if (! document.getElementById){return false};
    // Quick utility function by Geir Bækholt
    // Scan all links in the document and set classes on them dependant on
    // whether they point to the current site or are external links

    contentarea = getContentArea()
    if (! contentarea){return false}

    links = contentarea.getElementsByTagName('a');
    for (i=0; i < links.length; i++) {
        if ((links[i].getAttribute('href'))&&(links[i].className.indexOf('link-plain')==-1 )) {
            var linkval = links[i].getAttribute('href')
            // check if the link href is a relative link, or an absolute link to the current host.

            if (linkval.toLowerCase().indexOf(window.location.protocol+'//'+window.location.host)==0) {
                // we are here because the link is an absolute pointer internal to our host
                // vps - show pdf icon if filename has .pdf in it

                if (linkval.toLowerCase().substring((linkval.length-4), linkval.length).indexOf('.pdf') == 0) {
                    //pdf file, add the pdf class
                    wrapNode(links[i], 'span', 'link-pdf')
                }
            } else if (linkval.indexOf('http:') != 0) {
                // not a http-link. Possibly an internal relative link, but also possibly a mailto ot other snacks
                // add tests for all relevant protocols as you like.

                protocols = ['mailto', 'ftp', 'news', 'irc', 'h323', 'sip', 'callto', 'https']
                // h323, sip and callto are internet telephony VoIP protocols

                for (p=0; p < protocols.length; p++) {
                    if (linkval.indexOf(protocols[p]+':') == 0) {
                        // this link matches the protocol . add a classname protocol+link
                        //links[i].className = 'link-'+protocols[p]
                        wrapNode(links[i], 'span', 'link-'+protocols[p])
                        break;
                     }
                }
            } else {
                // we are in here if the link points to somewhere else than our site.
                if ( links[i].getElementsByTagName('img').length == 0 ) {
                    // vps - in my case all my PDF files were internal to my site only.
                    // If you want to add an icon for external links also, add code similar to above here also
                    // we do not want to mess with those links that already have images in them
                    //links[i].className = 'link-external'
                    wrapNode(links[i], 'span', 'link-external')
                    //links[i].setAttribute('target','_blank')
                }
            }
        }
    }
}

Step 2

Now we need to add the CSS definition for 'link-pdf'. I added the following to the ploneCustom.css in my custom skin folder:

/* Display PDF icon next to links to PDF files (where href ends with .pdf) */
.link-pdf {
    background: transparent url(/portal_skins/custom/pdf_icon) right no-repeat;
    padding: 1px 17px 1px 0px;
}
  • Note: You will have to modify your image url path according to your setup. Also, you will have to have uploaded an icon image to the path specified. In the above case, the icon has a shortname of pdf_icon.

That's it. You should now see the icon next to every internal hyperlink to PDF documents.

Add text instead of icon

Okay, sometimes you may not want to add an icon next to every PDF document hyperlink. Say you have a page full of PDF documents and you don't want a hundred icon images clutter your page and distract the user. All you want to do is add a piece of text, e.g., [PDF] next to every PDF file. Here's how to do it.

Customize the plone_javascripts.js file as follows:

function scanforlinks() {
    // securing against really old DOMs

    if (! document.getElementsByTagName){return false};
    if (! document.getElementById){return false};
    // Quick utility function by Geir Bækholt
    // Scan all links in the document and set classes on them dependant on
    // whether they point to the current site or are external links

    contentarea = getContentArea()
    if (! contentarea){return false}

    links = contentarea.getElementsByTagName('a');
    for (i=0; i < links.length; i++) {
        if ((links[i].getAttribute('href'))&&(links[i].className.indexOf('link-plain')==-1 )) {
            var linkval = links[i].getAttribute('href')
            // check if the link href is a relative link, or an absolute link to the current host.

            if (linkval.toLowerCase().indexOf(window.location.protocol+'//'+window.location.host)==0) {
                // we are here because the link is an absolute pointer internal
                // to our host do nothing

                //vps - show pdf icon if filename has .pdf in it
                if(linkval.toLowerCase().substring((linkval.length-4), linkval.length).indexOf('.pdf') == 0) {
                    //pdf file, add the pdf class
                    wrapPDFNode(links[i], 'span', '')
                }
            } else if (linkval.indexOf('http:') != 0) {
                // not a http-link. Possibly an internal relative link, but also possibly a mailto ot other snacks
                // add tests for all relevant protocols as you like.

                protocols = ['mailto', 'ftp', 'news', 'irc', 'h323', 'sip', 'callto', 'https']
                // h323, sip and callto are internet telephony VoIP protocols

                for (p=0; p < protocols.length; p++) {
                    if (linkval.indexOf(protocols[p]+':') == 0) {
                        // this link matches the protocol . add a classname protocol+link
                        //links[i].className = 'link-'+protocols[p]
                        wrapNode(links[i], 'span', 'link-'+protocols[p])
                        break;
                    }
                }
            } else {
                // we are in here if the link points to somewhere else than our site.
                if ( links[i].getElementsByTagName('img').length == 0 ) {
                    // we do not want to mess with those links that already have images in them
                    //links[i].className = 'link-external'
                    wrapNode(links[i], 'span', 'link-external')
                    //links[i].setAttribute('target','_blank')
                }
            }
        }
    }
}

Also, add a new function wrapPDFNode() [modified form of wrapNode, which could also have been extended to add this functionality but I just chose to create a new function) as follows:

/* vps - Display text '[PDF]' next to a pdf document link. Alternative to using
   PDF icon image (copyright issues with modifying size
*/
function wrapPDFNode(node, wrappertype, wrapperclass) {
    // utility function to wrap a node "node" in an arbitrary element of type
    // "wrappertype" , with a class of "wrapperclass"
    wrapper = document.createElement(wrappertype)
    wrapper.className = wrapperclass;
    innerNode = node.parentNode.replaceChild(wrapper,node);
    wrapper.appendChild(innerNode);
    wrapper.innerHTML = wrapper.innerHTML + ' [PDF]';
}

That's it! That should display the text [PDF] next to every PDF hyperlink.

by Vaishal P Sheth last modified February 5, 2006 - 00:44 All content is copyright Plone Foundation and the individual contributors.

Plone/portal_skins/plone_ecmascript/plone_javascripts.js

Posted by Kevin Strasser at December 5, 2005 - 21:13

What/where is this in 2.1.1? I cannot find this javascript function anywhere.

Found it in portal_skins/plone_ecmascript/mark_special_links.js

Posted by Yong Wook Kim at December 13, 2005 - 20:42

I found the same code in plone_ecmascript and the name is mark_special_links.js. I modified this file to remove the globe icon for the external link from my plone site

More generic version

Posted by Michael Dunlap at October 26, 2006 - 22:21
If anyone is interested, I've come up with a more generic version for adding text for the file type. E-mail me at dunlNOSPAMapm [at] u DOT washington [dot] edu

(Let's see the spambots work though that!)

CSS

Posted by Liz Dahlstrom at December 18, 2006 - 20:50
This is also available in the CSS under the .link-external class. To get rid of the globe and the shift to the right to make space for it, add this to your custom CSS file:

.link-external
{
background: #fff; /*Plain white background*/
padding-left: 0px; /*Get rid of the shift to the right*/
}

For any issues with the web site functionality, please file a ticket.

Please consult the policy on plone.org content if you want your content published on this site.

Servers and hosting by