Search

Hi all, here’s a quick question. How do you organize your site’s assets (CSS, Javascript, etc.) within your page templates? I use a master.xsl utility, but I’ve recently found it to be somewhat inflexible for including assets on an individual page basis.

In my case the <head> is contained in the master.xsl template. So for example, if I want to include a stylesheet in an individual page, I either put it in master.xsl (thereby having it loaded on the whole site), or I have to embed it somewhere in the page’s template below the <head>, which is ugly.

I considered using <xsl:call-template>, and passing it a parameter with the link to the stylesheet, but this still seems sort of clunky once you have a couple of assets you want to include.

Any clever ideas? I’m sure one of you guys has done this :)

Allen accomplishes this with modes:

In your head:

<!-- Whatever stuff you need sitewide -->
<xsl:apply-templates select="data" mode="assets"/>

And then on your page:

<xsl:template match="data" mode="assets">
    <!-- page-specific stuff -->
</xsl:template>

Make sure you’ve got a blank template match on that mode in your master too, to prevent it dumping out the contents of /data if no matching template is found in a child page…

That’s how I was looking at doing it, I was also looking at using named templates, but I couldn’t get it to work either way.

I wanted to apply CSS from the master.xsl and the page specific CSS. I couldn’t figure out how to do it…

I more or less do the same thing.

<xsl:if test="$current-url=blahblahblah">
  whatever I need included goes here
</xsl:if>

$current-url can be replaced with whatever param is more convenient.

Thanks everyone! I think I’ll give modes a go…

Yep, I’m using modes for an intranet ensemble that uses a single master template for all pages.

My template looks something like this:

<xsl:template match="/">
    <html lang="en">
        <head>
            <xsl:apply-templates mode="page-title" />
            <meta name="description" content="" />
            <meta name="author" content="" />
            <xsl:apply-templates mode="css" />
        </head>
        <body id="{$current-page}-page">
            <xsl:apply-templates mode="header" />
            <xsl:apply-templates mode="nav" />
            <xsl:apply-templates mode="aside" />
            <xsl:apply-templates />
            <xsl:apply-templates mode="footer" />
            <xsl:apply-templates mode="js" />
        </body>
    </html>
</xsl:template>

Then, I am able to override any of these apply-templates instructions in each page template, sometimes depending on whether a JavaScript, CSS, or XML file has been uploaded with the entry.

Each entry can potentially have a completely different layout.

That’s really clever. You are essentially simulating a call-template, but with the ability to use matching template overrides. Cool!

Ugh, I tried this and couldn’t get it to work for some reason. I had, for instance a CSS moded template on the master stylesheet for global CSS, then one on the specific page, but neither would work correctly.

I will revisit this as it must be something I did wrong…

@bauhouse: awesome, that’s exactly what I was going for!

I have an empty template in my master.xsl:

<xsl:template name="head" />

And then just before the end of my <head>-tag in my master.xsl I put:

    ...
    <xsl:call-template name="head" />
</head>

Now, if I have certain pages which have the need to add some other content to the head, I simply create a <head>-template, causing it to override the empty one located in my master.xsl:

<xsl:template name="head">
    <link rel="stylesheet" type="text/css" href="portfolio.css" />
</xsl:template>

I do this same trick for my <title>- keywords- and description-(meta)-tags, so I can adjust the title, keywords and description of each page if I want to. In this case, the master meta-template (as I call it), is not an empty template (like head), but holds a default title, keywords and description.

kanduvisla hit an important point: There are not only matched template overrides as used by bauhouse, but also named template overrides. So no matter which route you take, “overriding” is king.

When I try to override a template when calling it by its name just like kanduvisla said, I get an error:

xsl:template: error duplicate name 'assets'

So I'm forced to use the mode method or have an empty template in all my pages.. any idea where that comes from?

I see in my local phpinfo() the libxslt version being libexslt Version 0.8.13 where as on some server I can read libexslt Version 1.1.24

Do you think this my be a reason?

I don't think that this is the reason. I assume that you are simply doing something wrong. :-)

That's right :)

Turns out I was using an <xsl:include> instead of an <xsl:import> to call my master.xsl.. lesson learned!

Weirdly getting an error saying that I have a duplicate template name when using Kanduvislas approach Comment #11, any idea what could be wrong?

have empty template at bottom of template and a call-template in the head markup of master..

Then each page xsl file has a xsl:template name="metadata" but it says there is a duplicate named template.. hmmmm

This is the error:

XSLTProcessor::importStylesheet(): xsl:template: error duplicate name 'metadata'
XSLTProcessor::transformToXml(): No stylesheet associated to this object

Can you post your xsl?

It's cool, I just removed the blank template bit and put a choose otherwise block in each page for now. it's only 5 pages, but loads of categories.. they are also filtered in DS.. so fingers crossed I'm good for now.

@monoo2

Perhaps case as here. You are <include>ing master.xsl instead of <import>ing it :)

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details