January 2, 2007

Why I Seldom Map CSS Files in TemplaVoila

By: Ron Hall

Cat: TYP03, CSS, TypoScript, TemplaVoila

I moved to TemplaVoila templating earlier this year in order to take advantage of FCE's and local processing in individual templates. I originally connected my CSS files using the "Select HTML header parts" feature of TV. However, I have recently changed that practice. Let me first explain what I do now and then why I do it. By the way, I would recommend you also consider this approach even if you use the "modern template building" approach instead of TV.

Currently, instead of selecting the CSS file in TV, I add the HTML code for the stylesheet link to my page object. For example:

page = PAGE
page {
  headerData = TEXT
  headerData.value = <link rel="stylesheet" type="text/css"
    href="/fileadmin/styles/base.css" />
  typeNum = 0
  10 = USER
  10.userFunc = tx_templavoila_pi1->main_page
}

Why do I do this? It makes it much easier to tweak or completely rework the CSS in future updates of the site. Let's say in the given example that you want to rework the CSS for a live site. After setting up a test section within the site, you can add the following to a template on the top page of the test section:

 page.headerData = TEXT 
page.headerData.value = <link rel="stylesheet" type="text/css"
  href="/fileadmin/styles/base_v2.css"


This will allow you to test all of your current templates using the new CSS file on the pages in the test section of the site. Once everything is perfect then just adjust the code on the main template to the new CSS and the entire site is changed--all without having to remap any templates.

Do I ever map CSS files in TV? Yes, particularly if the CSS is unique to that template. But for the main CSS used throughout the site I use the method just detailed.

 

Comments

Excellent tip Ron. I will consider using this technique on a website revamp I'm starting.

There is another benefit of using your method. Normally (the TV way - selecting HTML Header Parts) when you update the TV Template file, you'd better select the HTML Header Parts *AGAIN*, or else the CSS for your template will not be included. Using your method, you can just update the HTML, and not have to worry about including the CSS. One less thing to worry about!

Hmm... another thought - I guess you could include multiple javascript and css files using this method, right? That would remove the requirement for using "Select HTML Header Parts" except when you want to do something that's unique to that template. Does that sound right?

Thanks again for the tip!
David Lanier, 01/04/07
 
Yes, David. You are correct on all your comments. Using this method does eliminate having to select the header parts each time you make adjustments to the template. And, yes, you can use the same code to include other things (like javascript, HTML comments, etc) into the head of your document.
Ron Hall, 01/04/07
 
Another advantage of using TS to include the CSS is the possibility to use conditional comments to fix IE's various bugs, which is _not_
possible with TV's mapping. Here is a (working) example from a life site:

page.headerData.10 = TEXT
page.headerData.10.value (
<style type="text/css">
@import 'fileadmin/templates/css/standard.css';
@import 'fileadmin/templates/css/popup.css';
@import 'fileadmin/templates/css/menu.css';
@import 'fileadmin/templates/css/pages.css';
</style>
<!--[if lte IE 6]>
<style type="text/css">
@import 'fileadmin/templates/css/iefix.css';
</style>
<![endif]-->
)

Note the use of '( ... )' instead of '=' in ...10.value; not really neccessary, but it looks nicer in the generated pages. Also note the inclusion of several different CSS files, each tailored to a
specific job (the site has a CSS image popup feature, see below).

If you need special CSS imports/inclusions on specific branches of your site you always can overwrite page.headerData.10.value either by some condition in the central TS, or by a different specification in the TS
field of the topmost page of that branch. Then you often might want to clear the derived settings with:

page.headerData.10.value >

before resetting it to different imports/includes.

The only thing lost with the TS approach is the (half-) automatic inclusion of CSS files, when just a specific DS needs special handling. Then talk to your designer, most often there is a solution, not
requiring that (remember, that CSS files are typically only read once in a while and cached then by the browser, thus beeing available for other pages without a reread, unless you request it)!

Besides, the above .../pages.css deals with special handling for very specific pages to be formatted differently than the rest of the site. This works by giving every page a unique body id and using more
specific CSS selectors for the pages needing special attention. The unique body id attribute is derived from the pages uid and generated by this TS setup (could be the page alias for more readable CSS selectors):

# Let's have a special tag with an id attibute,
# so that we can have special CSS formatting applied not only to the
# body, but also to any descendant element of that body (everything)
page.bodyTagCObject = TEXT
page.bodyTagCObject {
# We want the 'value' property to have 'getText' behaviour
insertData = 1
value = <body id="page_{page:uid}">
}
Georg Rehfeld, 07/06/07
 
Thanks, Georg.
I am with you on the body id.
I code the id into the HTML template as in:
<body id="alt-1">
or
<body id="alt-2">
I then map the body tag through TV header parts but include the css file through TS.
Ron Hall, 07/06/07
 
First of all, thanks for all the helpful tips found on your site. In order to help a little, I wanted to add that it's possible to include CSS via TS with this line

page.includeCSS.base = fileadmin/template/css/base.css

Note that .base after includeCSS is an index. You can overwrite it in some page of your site (like in the test part you mentionned)
Hope it will help
G. Colson, 08/28/07