Composr Tutorial: Designer themes, implementing a clean-room design

Written by Chris Graham (ocProducts)
Composr is designed for maximum design flexibility, and has a lot of functionality so you can match high quality designs with high quality features. This tutorial will show you how you, as a web designer, can leverage Composr to efficiently implement your design.

Much of the contents of this tutorial is also present in other tutorials in greater detail. Our goal here is to bring information together in a clear focused way.

This tutorial does assume you have developed basic Composr knowledge, such as what blocks and panels are. You may also wish to dip into other tutorials as you slowly work through this, such as the Tempcode programming tutorial.


Feedback

It is very important that at any point where you think things are confusing, either in Composr, or in this documentation, that you write it down and let us know. We strive to make Composr the most user-friendly way for making a sophisticated cost-effective website and we really need to know where people get confused in order to do that. Our job is never done making Composr easy to use.

Anything that makes you think for more than 30 seconds is an issue we may want to resolve.

Research into Composr

Make sure you have followed these guidelines:
  1. Install the most recent stable version of Composr (or beta/RC release if you know you need to develop for a newer version or are working to a more distant deadline).
  2. Get a good understanding of what features Composr has. In particular, what screens and blocks are available. This is important because your themes will have to make use of these facilities to implement the designs.
    • Add some test content for each content type. This will give you test data and also give you an idea of the features available and what fields there are.
    • Edit the front page (there's a link to do it under it as long as you are logged in as an Administrator). On the form you'll see an "Add Block" button that can add all the different blocks. You don't actually need to add all the blocks to see them because there's a preview feature. Preview all the blocks and look at the options to see what they do.
    • Visit the site-map, and go to each screen on it. This will give you an idea what screens the system has.
  3. Now that you know what features are available, you need to decide which features will be used for each part of your design. Making_a_theme.pdf shows an annotated theme design that was done by someone who has never used Composr. You can see via the annotations how this clean-room-design can be implemented.

As a designer you will find a number of challenges that a designer does not normally face, so make sure you have followed these guidelines:
  1. Editability: All content in a design has to be editable, so there's got to be some kind of feature associated with all the content. Every bit of text is associated to some kind of field for some kind of content type.
  2. Optional content: If content is missing (for example), it shouldn't just leave empty boxes, it should instead either remove boxes or automatically insert placeholder content. You need to think how things will work.
  3. Content growth: Often there will be more or less content on the final site than you've laid out in your design. Maybe in your design you assumed you could lay things out in columns of 3 items, but the end-user decided to add 5.
  4. Text growth: While you can probably ensure that you can align things on a design, when users start adding content, you cannot know how much they will type.
  5. Block rearrangement: For a theme, chances are the end user will make changes. For instance, they may switch out your choice of blocks with a different choice. Therefore you have to implement in a modular way, so that design elements or pages you did not specifically give attention to still look decent. A good example of this is styling the standard box templates (which most blocks will use) so that all boxes look good, rather than trying to style each individual block completely separately.
  6. Comprehensive style framework: Similarly, you won't have time as a designer to give individual design attention to each screen, so you will need to work modularly for this reason also, applying new styles on top of the default Composr styles in such a way that your styles are applied generally enough to display wherever is appropriate but if they are very specific that they are not applied too generally. By making sensible decisions about making styles apply wherever appropriate but only wherever appropriate you are essentially creating a consistent design language, which is a key part of the normal branding process anyway.
  7. User levels: Sometimes not everything should show for every user. For example a link to add content might only be shown to administrators.
  8. Expect deep nesting: You may find Composr's default templates have large numbers of nested div tags. This is because Composr is designed in various kinds of component which often are surrounded in div tags to keep them together. We have to design our styles in a modular way, so typically each style concept is applied to a different div tag so that things aren't muddled up and the system is properly organised and partitioned. For example, we might have a div to contain a row of floats, and a div for each box being floated and then various div tags for the content within those boxes; a manual static theme could use less div tags, but it would be more inflexible for re-styling, less modular, and not viable for easy use in a CMS.

This section is accompanied by an annotated PDF (note that some PDF software can't display annotations like the official Adobe reader can)

Static design

You can develop your static design before working with Composr, just like you would in any normal web design process.

Make sure you have followed these guidelines:
  • Modular float clearance: Don't use the CSS clear property, because it interferes with how Composr handles its 3-column layout and other default styling. Contain floats in a box using something like overflow: hidden;.
  • Flexible height: Avoid setting CSS heights wherever possible. If you set heights then if people increase their font size then it's likely text will overflow and look awful. There's rarely a true reason to set a height anyway: if you need to clear floats, use the technique described above.
  • Flexible width: Do not assign widths or heights or min-widths or min-heights unless necessary (e.g. to make sure you align with a background's size). It makes it very hard to adapt designs later if the spacings change.
  • Flexible layout: Do not use floats on every block in the layout. There are much better ways to solve these problems without resorting to continuous use of floats (which introduce many other kinds of problem). An exception is if you are using a grid system.
  • No CSS resets: Do not use a CSS reset: Composr does not use a CSS reset in its default templates so you would need to re-theme all Composr screens to reapply default spacings if you used a CSS reset. If you must use a CSS reset then it will need adjusting to be scoped beneath a particular position(s) in the DOM tree.
  • Target styles precisely: Similarly, don't apply overly-broad styles thinking you'll undo them for any case that does not match – any broadly defined style must be a very general one, because you won't want to add dozens of exceptions back in to cater for the pre-coded HTML usage that Composr has in its myriad of templates
  • Sensible font size: Make sure the default font size is sensible for the main content area. You will not be able to individually specify the font size of each text block on the final theme as there will be a lot of layout that comes from default Composr templates and you won't have time to give them all individual consideration.
  • Plenty of content space: It's not a good idea to make your main content area too thin, because default Composr templates will assume that they have at least about 600 pixels.
  • Distinct image naming: Do not have two images with the same name but different extensions. For example do not have an example.jpg and an example.gif. They should have different names such as examplea.jpg and exampleb.gif.
  • Distinct class naming: Don't invent CSS class names that are too generic and thus risk clashing, e.g. description.
  • Tidy code: If other people will be working with your CSS, lay it out neatly, with plenty of comments (Composr will minify the CSS on output, so this won't hurt performance).
  • Modular CSS: Try to modularise your CSS according to Composr's own modularisations. For example, keep news CSS separate from galleries CSS. This allows you to then place it in the appropriate Composr CSS files, rather than having to dump it all into global.css.

Implementing your design into Composr

This section will step through how to build your design, in a number of steps and sub-steps.

This is what will happen with the elements of your static design (roughly):
  • The XHTML will be spread between your theme's GLOBAL_HTML_WRAP.tpl template, Comcode panels, the Comcode start page, and many block templates within your theme.
  • The CSS will mostly be incorporated into your theme's global.css CSS file, and possibly also some other CSS files in your theme.
  • Your images will be added into your theme as theme images.
  • Your JavaScript will be added to the custom_globals.js template.

A starting point (the Theme Wizard)

  1. Using the Theme Wizard (in Admin Zone > Style > Themes), create a base theme that matches the colour of the theme that needs to be build as closely as possible (if your theme has many colours, choose the one used most). Tell it to make the theme active.
  2. You will also want to make sure the 'Block cache' is disabled in the configuration (Admin Zone > Setup > Configuration > Performance options > Caches). This will allow you to make block template changes without having to worry about emptying the block cache each time. It is advisable to leave the other caches as they are; Composr is smart enough to detect if files have been changed in most cases.

This section is accompanied by a video.

Images and CSS

CSS loads images with a base URL within the themes/<yourthemename>/templates_cached/EN directory (i.e. where the compiled CSS files get placed). CSS always works like that, rather than loading relative to where the current page URL is. This is problematic and confusing, and best solved by not using relative URLs – use the theme image system instead, as described below.

  1. Take your theme images and copy them into a new themes/<yourthemename>/images_custom/<yoursitename> directory. This will allow you to reference them in Composr as theme images.
  2. Go to edit the CSS for your theme in Composr. Do this by going to Admin Zone > Themes, then the 'Edit CSS' option next to your theme. Choose to edit the global CSS file. Take your CSS and paste it on the top (don't remove the default CSS!). If you prefer, you can edit themes/<yourthemename>/css_custom/global.css in your favourite text editor.
  3. You need to change the image references in your CSS. If you had something like images/example.jpg it would need to be changed to {$IMG,<yoursitename>/example}. You should not add the .jpg/.png/.gif on the end. This will make it find themes/<yourthemename>/images_custom/<yoursitename>/example.jpg (or example.png or example.gif).

This section is accompanied by a video.

Global layout of XHTML

  1. You will next need to start modifying templates to incorporate your "global" XHTML (XHTML you expect to show on all pages). Start with the main one: GLOBAL_HTML_WRAP.tpl. You can do this in Composr from the themes section, or you can do it in your favourite text editor (e.g. Dreamweaver) by copying for example themes/default/templates/GLOBAL_HTML_WRAP.tpl to themes/<yourthemename>/templates_custom/GLOBAL_HTML_WRAP.tpl. It will take you a bit of time to learn what default template code to keep and what can go. Basically you will want to keep:
    • The contents of the <head> tag from GLOBAL_HTML_WRAP.tpl
    • References to panels, like {$LOAD_PANEL,left} from GLOBAL_HTML_WRAP.tpl, so that panels can still be placed (assuming you have panels on your design! - or you may have a left and no right, or vice-versa). You can rearrange it all and place it in different places, and you don't need all the stuff about widths because you are allowed to make bigger assumptions than our default templates can. It is possible to hard-code the equivalent of panels into the GLOBAL_HTML_WRAP.tpl template instead of using separate files, but is makes it harder for webmasters to make changes. If you feel more comfortable not using panels at first this is fine.
    • {MIDDLE} from GLOBAL_HTML_WRAP.tpl, which is the main content of a page.
    • {$MESSAGES_TOP} and {$LATE_MESSAGES} from GLOBAL_HTML_WRAP.tpl, which is used to put out status messages as you complete things on the site or if small errors happen.
    • {$JS_TEMPCODE,footer} and the <script> tag from GLOBAL_HTML_WRAP.tpl.
    • {$COPYRIGHT`} from GLOBAL_HTML_WRAP.tpl, which should be used instead of the hard-coded copyright of your design (most designs have it).
    • The rest (and there are lots, because our default theme is very thorough) can be removed.
  2. If you have incorporated left and/or right Composr panels and have made the assumption that they can never be blank/hidden (even on pages in Composr that are normally full-width), then you must put supports_wide=0 into your themes/<yourthemename>/theme.ini file.
  3. Once you have your main XHTML incorporated you will see lots of problems with layout, because there will be incompatibilities with your styling and the default styling. So now is a good time to fix all these. You probably will want to remove many of the default styles Composr uses from global.css, but be careful to only remove really general layout style rules – don't just remove huge chunks of CSS indiscriminately.
  4. Similarly, you may find you made assumptions in your CSS. For example, you may have set quite specific styles for default elements because you only use them in a specific way on your design (e.g. making all strong tags really large). Your Composr theme will need to not make too many assumptions like this, remember a lot of your CSS will be running on screens you haven't given individual design attention to because they will be running a lot of default XHTML from Composr. Adjust your CSS so it targets your style rules with the necessary specificity.

This section is accompanied by a video.

Laying out your panel/page structure

Comcode overview

Comcode is like plain text but with some tags.

You can use [semihtml]...[/semihtml] to put in a mix of raw XHTML and Comcode also, should you want precise control over the HTML.

Blocks are linked in via Comcode [block] tags.

Comcode is explained in more detail further down.

  1. Once things look fairly good it is time to start linking in all the individual blocks onto the site (via Comcode), as identified in the 'Research into Composr' stage.

    Mostly this is done by editing individual Comcode pages.
    For example, the left panel is a page called :panel_left that you can edit from Content Management > Pages (Comcode pages). Or, you can edit it by copying pages/comcode/EN/panel_left.txt to pages/comcode_custom/EN/panel_left.txt and using any text editor.

    You will probably want to blank out what is already in the files and start them from scratch. At this stage we are not considering style, only content/structure, so consider your block decisions from the first stage but forget about design for now.

    Place the blocks as appropriate onto your:
    • Comcode page: Start page, :start
    • Comcode page: Left panel (if you have one on the design), :panel_left
    • Comcode page: Right panel (if you have one on the design), :panel_right
    • Comcode page: Top panel (if you have one on the design), :panel_top
    • Comcode page: Bottom panel (if you have one on the design), :panel_bottom
    • GLOBAL_HTML_WRAP.tpl: Often there will be blocks in the header, like search or login blocks. You can place these using Tempcode rather than Comcode like:
      {$BLOCK,block=<blockname>}. The default template already shows this in some cases, and the Using blocks tutorial provides a section "Tempcode syntax". Similarly sometimes there is a menu in the footer, which can be placed like:

      Code

      {$BLOCK,block=menu,type=<menu-type>,param=<menu-name>}

This section is accompanied by a video.

Lots of XHTML template editing

Which template?

If you put &special_page_type=show_markers onto the end of the URL you're at (i.e. in your address bar) it will overlay details about what templates you're using. Similarly if you put &special_page_type=tree onto the end of the URL you're at it will show a structure of what templates are used to generate the page.
(actually these parameters to append will start ? not & if the URL does not have a ? in already)

There are a small number of cases where (for performance reasons) Composr does not feed full templating structure all the way through the system, in which case the templates can't be shown with show_markers. In this case you can guess the names via &special_page_type=tree or if you are feeling very technical you can look at the PHP code (for example most of the templates uses in the main_news block are mentioned in sources/blocks/main_news.php as PHP calls to do_template).

  1. Now that the blocks are placed, you need to style them. See the tip to the right for how to find out what templates to edit.
  2. There's a big risk that the final webmaster may come along and ruin any custom XHTML you have written via editing using the WYSIWYG editor. You can disable the WYSIWYG editor for a Comcode page by pasting this special comment into the end of the page:

    Code

    {$,page hint: no_wysiwyg}{$,page hint: no_smart_conversion}

This section is accompanied by a video.

JavaScript

It is likely that you will have JavaScript code for the design.

If this code is page-specific, you may just end up including it in your Comcode page.

However, if it should run site-wide as initialisation or library code, you should add it to the custom_globals.js JavaScript template.

This template is specifically created so that you can easily slot in new JavaScript code.

Last steps

Testing:
  1. It is a good idea to verify your theme is stable across different Composr screens. When you defined the global layout and associated CSS it is possible you made some bad assumptions, like assuming fixed width styles can be placed on body (which is bad if Composr uses global.css inside an iframe, for example). First do a verification manually by viewing a few screens; good choices are:
    1. the forum index
    2. doing a website search
    3. previewing some changes from an edit form
  2. Next you can verify your theme more formally by using the 'Screen previews' feature from Admin Zone > Style > Themes. It provides details of all screens, and you can check them for how well they work. Don't spend ages on this unless you have made very extensive modifications or the site is going to use a very wide number of default Composr features, but at least do some checks on some random selections to give yourself greater confidence.
  3. Test your theme for all the major browsers.

Supplementary concerns:
  1. You will need to make an e-mail template. If you are making a theme, do this by overriding the MAIL.tpl template into themes/<yourthemename>/templates_custom/MAIL.tpl. However if you are making a website it is absolutely critical you save it into themes/default/templates_custom/MAIL.tpl or otherwise the default e-mail theme and Composr branding will be used on many system e-mails or queued e-mails. When designing an e-mail template, don't think about it as themeing – put whatever CSS code you wish to use directly inline in the template, as e-mail clients are not good at rendering general purpose CSS rules.
  2. Also, don't forget to implement a favicon ;) . In Composr this is done just as a theme image called favicon, so you can override it by making a themes/<yourthemename>/images_custom/favicon.ico file.
  3. If you override any existing default theme image manually, such as a favicon, you will need to empty the theme image cache from Admin Zone > Tools > Cleanup Tools.
  4. You may also want to check how the website prints, possibly adding some print-overrides into your CSS file (CSS can target printing separately, and the default global.css does already to an extent)

Things you may wonder about

Comcode vs Tempcode vs XHTML

Comcode:
Composr content, panels, and pages, are written in Composr's markup language, called Comcode.

On most forum software people can make posts using "bbcode". It's a bit like HTML but with the < turned to [. So in bbcode you can do like [b]this is bold[/b]. It's so that users can do styling without having to write full HTML (with <br> tags for white-space preservation, etc), and also for security reasons (so users can't do things like <script> tags).

Composr 'Comcode' is very similar to this standard 'bbcode', but it can do a lot more. In Composr we use it for content. For security and simplicity and power.
You can do all kinds of powerful things very simply in Comcode. E.g. [ticker]scrolling text[/ticker].

Tempcode:
In Composr we also have our templating system used within our templates, and the language for that is called Tempcode.

A "markup language" is a language where you have text and then tags in it to add extra meaning. HTML is a markup language and so is Comcode.
Tempcode is not really a markup language. We call it a "filtering language". I won't confuse you unnecessarily by explaining what we mean by that, but it may help you remember that they're not the same thing or equivalent. It will become more clear when you read the "How Tempcode works, an illustrated example" section.

What's the difference between Comcode and Tempcode?
Comcode is primarily a content language designed for the convenience of end-users, and applies automatic formatting and has a large library of convenient tags. Tempcode is a precise HTML-embedded language with minimal syntax and no automatic formatting.

Practically speaking though, you can also write arbitrary HTML within Comcode (using the [html] tag or the [semihtml] tag), and you can also use Tempcode directly within Comcode.

At the end of the day it just comes down to what you're editing: Comcode pages are based in Comcode, templates are written in Tempcode. If you want to write pure Tempcode-style within Comcode (i.e. no automatic formatting, and HTML-support), put it all between [semihtml]...[/semihtml].

When Composr runs it actually automatically converts the simple Comcode into the more low-level Tempcode.

Referencing blocks

The concept of a Composr block is independent to Comcode or Tempcode, it's just a feature of Composr, and both languages can tie in to it. This section shows how blocks can be placed in both languages.

The "Comcode tag" is written like:

Code

[block="mainparameter" a="1" b="2"]blockname[/block]
The following Comcode is also equivalent:

Code

[block param="mainparameter" a="1" b="2"]blockname[/block]
…because the parameter named param can be written in short-hand. param is only special in two ways:
  1. We have this Comcode short-hand notation for it.
  2. Most blocks use it to pass in the main parameter the block needs, usually some kind of ID code. For example, for the menu block it is the name of the menu to be loaded.

The "Tempcode symbol" is written like:

Code

{$BLOCK,block=blockname,param=mainparameter,a=1,b=2}
As you can see there is no short-hand for skipping out 'param' in Tempcode, and the parameters are written in a different way, and the block name is also given as a parameter named block.

Referencing blocks, practical example

Here is an example of loading up the main_quotes to load a quotes file called quotes

Comcode:

Code

[block="quotes"]main_quotes[/block]

Tempcode:

Code

{$BLOCK,block=main_quotes,param=quotes}

JavaScript libraries (such as jQuery)

You may have used some JavaScript libraries in your design. jQuery is very common nowadays. You can reference these JavaScript resources very simply in the <head> tag just like you would in any simple static website, and it won't cause any problems.

If you are using jQuery you may want to consider linking to the online copy that Google hosts, because then visitors will get a faster page load time because it's probably already cached on their computers (because many sites use the same copies). Obviously only do this if your site is always going to be viewed on the live Internet (it's not good for Intranets!).

Creating page-links

If you are linking to a specific page via a template or some XHTML within a Comcode page (i.e. you're not using a Composr menu) you can generate a consistent link to the page like:

Code (Text)

href="{$PAGE_LINK*,site:news}"
 
news is the name of the page being linked to, and site is the zone the news page is in.
You can usually identify page-links to use from the URL. In this case the URL would be something like:
  • http://yourbaseurl/site/index.php?page=news
  • or, http://yourbaseurl/site/news.htm
  • or, http://yourbaseurl/site/pg/news.
You can see now one reason why we don't hard-code URLs in Composr! The URLs can be different, depending on what URL Scheme is in use. Page-links also make it easier to use the same code on different domain names.

Escaping (* to the right of variable names)

You may wonder why above we put a * after calling up Composr's $PAGE_LINK symbol with a parameter site:news. It doesn't serve an obvious purpose.
What it actually does is makes sure the data is ready for use within XHTML without being treated itself as XHTML, and we call this "escaping".
For example if a URL contains & it must actually be written using &amp; in the XHTML.
All special characters must be changed, <&lt; and >&gt; and &&amp;.

This is actually important for security, if you don't properly "escape" your data it can lead to all kinds of security holes.
Imagine a URL that contained JavaScript code: you would not want that code to execute when that URL was embedded.

Therefore we quite consistently escape our symbols and template parameters, even if we trust them.
For example, we say {$SITE_NAME*} not {$SITE_NAME} if we are embedding the site name into an XHTML template.

Composr does not handle this automatically because the conversion carries two assumptions:
  1. That the particular part of the template is XHTML (as opposed to for example some JavaScript code within a <script> tag)
  2. That you don't want XHTML to embed directly. You do in some cases, such as when you are placing a block
But in 99% of cases it will need the *.

Finding where Composr CSS is set

Web browsers now almost all contain excellent developer tools. Simply right-click on what you want to see the style for and click 'Inspect' (or sometimes it is 'Inspect element').

It will tell you all the styles applied to that element, and the CSS selectors they come from, and the CSS file involved. It is then easy to search in the CSS to locate and alter that selector.

For example, if you 'Inspect' a link at the bottom of a Composr standard box, you will find there is this selector applying styles to it:

In addition, you will see there is an XHTML element tree that you can look at. If you are trying to identify what CSS classes or IDs are available to attach a style too, the XHTML element tree makes this very easy.

Modify or rewrite?

You could approach modifying parts of the default Composr styling in different ways. You'll make a decision based on what your trying to achieve and what is fastest.

Given a certain part of the styling you could make the following choices…
  1. You could leave it alone, if it looks okay by default.
  2. You could choose to use browser developer tools to find the default styles/classes, and make some changes to the default.
  3. You could go into the right template, and change a class name to point to your own class.
  4. You could completely rewrite the relevant template with your own XHTML (which of course will already be linked to your own CSS classes).

Specific advice for specific situations

New panels / re-used text / content-in-layout

There are three situations that may require you to add new panels to Composr, or to add a special content page that is included in another:
  1. New panels: most designs use some combination of left/right/top/bottom panels and a header and a footer. But it might not always be the case, one could imagine all kinds of complex panel arrangements.
  2. Re-used text: It might be the case that some text is used on many pages, so you don't want to keep copy & pasting it.
  3. Content-in-layout: Often a design will include some content in the header that the final webmaster might want to edit. If you are your own webmaster it doesn't matter so much, but ideally it's better to give someone the name of a page to edit instead of a template.

The solution to these problems are page/panel inclusion into templates. Any page name that starts with "panel_" is a panel and won't be shown in the site-map. Similarly, any page name that starts with "_" is considered special and won't show in the site-map.
To include a new panel with the page name of panel_panelname it is as simple as placing this code into your template:

Code

{$LOAD_PANEL,panelname}
To include a page named otherpagename into another Comcode page you can do something very similar using this in the page being included into:

Code

{$LOAD_PAGE,otherpagename}

Obviously the pages you reference must exist to show. To create them…
  1. Go to Content Management > Pages (Comcode pages)
  2. Type in the new page-link beneath the list of existing pages. For example, for these examples (assuming we are working in the welcome zone) we would type :otherpagename.
  3. You will then be in the page editor and can define the page contents there.

This section is accompanied by a video.

Logo wizard

If you want the Logo Wizard to be able to modify your logo (so that other people using your theme can build their own theme-appropriate logo), you will need to make these theme images:
  1. themes/<yourthemename>/images/logo/default_logos/1.png (the actual logo image)
  2. themes/<yourthemename>/images/logo/default_backgrounds/1.png (the background to the full header)
The logo wizard will use these as source files when creating the compound logo. If you need the logo wizard to put them in different places to the default Composr logo, or to use different colours, you can put the following into your themes/<yourthemename>/theme.ini file:

Code (INI)

logo_x_offset=0
logo_y_offset=0
site_name_colour=FFFFFF
site_name_split=425
site_name_split_gap=6
site_name_font_size_small=18
site_name_font_size=26
site_name_font_size_small_non_ttf=4
site_name_font_size_nonttf=5
site_name_x_offset=110
site_name_y_offset=30
site_name_y_offset_small=20
 
and customise the numbers until they work.

Menus

You probably don't want to hard-code sets of page-links into templates for themes as it's hard to edit (a theme should not assume what pages a site has, although it is okay to make smaller assumptions, like what social media buttons it might use), so we suggest you use menus. There are a number of different default menu layout types:
  • dropdown: a horizontal menu with drop-downs that can also work as a single-layer horizontal menu. Used on all zones in Composr, by default.
  • tree: a vertical menu. Used by default on panels.
  • embossed: a vertical menu, that makes each link look like a button, well-suited for tablets.
  • popup: a vertical menu, with pop-outs (the vertical equivalent of a drop-down menu).
  • select: a simple XHTML <select> based navigation menu.
The menu layout types are distinguished by their templates. Each menu type has its own set of templates that includes the name of the menu layout type. The template naming pattern would be MENU_<layouttype>.tpl, MENU_BRANCH_<layouttype>.tpl and MENU_SPACER_<layouttype>.tpl. You can create a new menu layout type just by making a new set of templates (using an existing set as a base), but this is virtually never necessary: it is often easiest just to customise one of the default sets.

You can have as many menus of each layout type as you like. They are placed using the menu block.

Code

{$BLOCK,block=menu,type=<layouttype>,param=<name>}
and in Comcode like:

Code

[block="<name>" type="<layouttype>"]menu[/block]
Where <name> is something that identifies the particular menu instance, holding together the links in that particular menu instance. You can just make the <name>s up, and you'll get a new empty menu each time you do.

For example…

Tempcode:

Code

{$BLOCK,block=menu,type=tree,param=samplemenu}
Comcode:

Code

[block="samplemenu" type="tree"]menu[/block]

Catalogues (for custom content types)

When you have a custom content type to add (something that there isn't a specific Composr feature for, such as "Project Staff" or "Representatives" on making_a_theme.pdf), you'll need to make a catalogue. Decide what fields you want then add the catalogue from the 'Content Management' zone.

You will probably want to have a non-tree catalogue, with a display type of 'field-maps' (these can be changed later if needed).

When you have added the catalogue you will need to add a category to it, and then add at least some test entries to that category.

Catalogue templating

For this example, we will assume you are trying to show off the catalogue via a block in your design, rather than an individual page.

Use the main_cc_embed block to embed the catalogue (the Add Block tool can add this for you, and it will help you select your catalogue category).

The default catalogue templates are very formulaic in their arrangement of content. This is because they know nothing about the content and thus just display it consistently according to the catalogue's display type (tabular, field-maps, or list). If you want full layout control you should use a display type of 'field-maps' for your catalogue and then you can place/style each field individually. Before we do this though, we need to override the catalogue templates for our individual catalogue.

To do this copy the following templates and edit the copies (for this example I am assuming your catalogue has the codename 'project_staff'):
  • CATALOGUE_DEFAULT_CATEGORY_EMBED.tplCATALOGUE_project_staff_CATEGORY_EMBED.tpl
  • CATALOGUE_DEFAULT_FIELDMAP_ENTRY_WRAP.tplCATALOGUE_project_staff_FIELDMAP_ENTRY_WRAP.tpl
  • CATALOGUE_DEFAULT_FIELDMAP_ENTRY_FIELD.tplCATALOGUE_project_staff_FIELDMAP_ENTRY_FIELD.tpl
(by overriding catalogue templates to a particular catalogue name we can make changes without interfering with how other catalogues look)

Each individual field is passed into the main template (for the case of the main_cc_embed block, it is CATALOGUE_project_staff_CATEGORY_EMBED), with names like {FIELD_0} etc (this is the first field). {FIELDS} is the formulaic arrangement and you'll probably want to remove it.

If you're not sure what parameters are available to use in a template you can add this code temporarily:

Code

{+START,PARAM_INFO}{+END}
And this will show a full print out of all the parameters available to you. Often it's hard to read this if you don't have a lot of space in your design at the time of you putting this in, but you can copy and paste it out to a word processor to keep it for reference. For example you may want the URL or the parameter for an <img> tag and these can both be found in this way.

This section is accompanied by a video.

Login boxes

The [block]side_personal_stats[/block] Comcode is used for creating a login box for use on a panel. However the side_personal_stats block displays differently according to whether you are logged in or not (obviously…).
The BLOCK_SIDE_PERSONAL_STATS_NO.tpl template is displayed for non-logged in users, while the BLOCK_SIDE_PERSONAL_STATS.tpl template is displayed for logged in users.

When you design a page you probably only think of it as a login box, but when you make a real site you obviously need to think about what happens when someone is already logged in, as everything has to function nicely too, as it's not a static design anymore.

Often designs will show the login box via a template instead, usually when it needs displaying in the header (so, the GLOBAL_HTML_WRAP.tpl template). Composr has a different block for this which is placed via {$BLOCK,block=top_login}. This is actually what the default theme does in Composr 10+.

If you want to simulate what it looks like when you are logged out you can do it without logging out put &keep_su=Guest on the end of the URL (or ?keep_su=Guest if you don't have a '?' symbol in the URL you're at).
This technique is very useful because you can have one tab showing what a logged in user sees, and one tab showing what a non-logged-in user sees (a "Guest") – you avoid having to login/logout all the time to do testing.
Guest can be substituted for any username, so long as you are logged in as an administrator initially.
For more information on the SU feature, see the Testing access and privileges tutorial, Access control and privileges section.

Social media buttons

These are achieved using Composr's main_screen_actions block. We have default links for all the biggest social networks, but you can do whatever customisations you like to the block and add other social networks very easily (you'll see that all the links in the template that we already have follow a fairly simple pattern).

Complex content arrangements

Sometimes a design will have what looks like a panel but actually only appears on the start page. For example, there might be an obvious page area, panels either side of the page area, and an obvious header, but also a bar that goes above the panels and is only shown for the start page. The best way to implement this is by actually making it a panel (one of the default ones, panel_top) but putting some special code in there to make it only show for the start page. You can do this with the following code:

Code

{+START,IF,{$MATCH_KEY_MATCH,:start}}
...
{+END}

It's easier to put it all in a panel like this and say that panel should only show on one page than trying to make the rest of the start page be a weird shape.

This section is accompanied by a video.

Internationalisation

Composr has excellent support for multiple languages. You may have noticed how Comcode pages (including panels) are located in 'EN' folders. If other language packs are installed there are folders for other languages, so that you can have a different copy of each Comcode page for each language.

There is a block that contains a drop-down list for switching languages, the side_language block. Often a design will put neat little flag icons on, in which case you need to put this code as the href of your link (this example if for a French flag icon): {$SELF_URL*,0,0,0,keep_lang=FR}. The keep_lang URL parameter will be added to the current URL via this link, and Composr will keep passing it through for any further clicks.

You will need to ensure you don't put English text into your templates. To avoid this you need to use "language strings". Let's pretend you have this text in a template:
Designed by BigBoy designs
to internationalise it you would need to create a named language string. We'll pick a name that represents the text. In this case, DESIGNED_BY_TEAM. We would replace the text with {!DESIGNED_BY_TEAM,BigBoy designs} and add this to the lang_custom/EN/global.ini file (create this file if it does not already exist):

Code (INI)

DESIGNED_BY_TEAM=Designed by {1}
 
Do you see how we passed in a bit of constant text to the phrase that would not be translated ("BigBoy designs") and embedded it via {1}? By doing this we avoid assuming word-order, because some languages order words in different ways.

To make a French version of this string, we would simply add this to lang_custom/FR/global.ini:

Code (INI)

DESIGNED_BY_TEAM=Con&#xE7;u par {1}
 

All Composr content can be translated, so you don't need to worry about things like menu items. The content text can be translated by the site team from the Admin Zone via a prioritised translation queue.

Proceeding to build a real site

If you are not just making a theme, but a whole site, you will need to do some of the following also:
  1. Add all your real content
  2. Edit the menus in the theme, to place the real final links
  3. If a page does not exist in the standard Composr then the page needs to be created. The menu can link to non-existing pages (so make up a name for the "Link" field, like "my_new_page") and when this menu item is clicked it shows an error that the page doe not exist and also gives an option to add this page. Once the page is added, this can be edit it like any other Comcode page.
  4. Install any non-bundled addons you may need, such as the Google Maps addon
  5. If you have used completely new theme images inside content, such as Comcode pages or catalogue entries (using in your own theme's CSS or templates is fine) then you actually want these theme images to be defined inside the default theme rather than your own theme. This is because theoretically any theme could need to use these images, not just your one. So for each of these "content theme images" move themes/<yourthemename>/images_custom/<yoursitename>/<example> to themes/default/images_custom/<yoursitename>/<example>.

How Tempcode works, an illustrated example

This is the default BLOCK_SIDE_NEWS.tpl

Code (HTML)

<div class="box guid_{_GUID}"><div class="box_inner">
        <h3>{TITLE}</h3>

        {+START,IF_EMPTY,{CONTENT}}
                <p class="nothing_here">{$?,{BLOG},{!BLOG_NO_NEWS},{!NO_NEWS}}</p>
        {+END}
        {+START,IF_NON_EMPTY,{CONTENT}}
                {CONTENT}
        {+END}

        {+START,IF_NON_EMPTY,{ARCHIVE_URL}{SUBMIT_URL}}
                <ul class="horizontal_links associated_links_block_group">
                        {+START,IF_NON_EMPTY,{ARCHIVE_URL}}
                                <li><a rel="archives" href="{ARCHIVE_URL*}">{!VIEW_ARCHIVE}</a></li>
                        {+END}
                        {+START,IF_NON_EMPTY,{SUBMIT_URL}}
                                <li><a rel="add" href="{SUBMIT_URL*}">{!ADD_NEWS}</a></li>
                        {+END}
                </ul>
        {+END}
</div></div>
 

Now I will explain what this means, by cutting it up into pieces…
  1. Code

    {CONTENT}

    This shows the news posts within the block. They have been passed in as the CONTENT parameter from the Composr PHP code. All the news posts are together in sequence within this parameter.

    This is an important concept to understand because it happens a lot in Composr templates – Composr obviously cannot make an assumption about how many news posts a site has, and content obviously is not hard-coded into templates, so Composr fills in whatever is the appropriate template separately for each item of content (each of those 'instances' gets parameters relating to that item of content), then Composr puts them all together as a sequence, and Composr puts that sequence into the 'wrapper' template as a normal parameter.

    In this case the 'wrapper' template is BLOCK_MAIN_NEWS.tpl and the template filled in for each individual item of content (the 'instance') is NEWS_BOX.tpl. So CONTENT here is lots of filled-in NEWS_BOX.tpl templates put together.
    Another example: For a 'tree' menu, the 'wrapper' template is MENU_tree.tpl and each menu link is done as an 'instance' of the MENU_BRANCH_tree.tpl template.
  2. Code

    {+START,IF_EMPTY,{CONTENT}}
       ...
    {+END}

    This puts the "…" in the page only if there are no news posts passed in. i.e. If there are no news posts (because there is no news), the "…" bit shows.
    This is useful to show a "there is no news yet" message when there is no news.
  3. Code

    {+START,IF_NON_EMPTY,{CONTENT}}
       ...
    {+END}

    This is the opposite to '2'. It shows the "…" part if there are news posts passed in.
    This is useful if you want to do something like put <ul>...</ul> around the news (if each item is a list entry) but only want to show the <ul> and </ul> if the list is not going to be empty.
    i.e. this kind of thing…

    Code

    {+START,IF_NON_EMPTY,{CONTENT}}
       <ul>
          {CONTENT}
       </ul>
    {+END}

    Often we will use it in templates even when it is not needed if we also have a IF_EMPTY, to make the code clearer.
  4. Code (HTML)

    <p class="nothing_here">...</p>
     

    This just is some static HTML.
  5. Code

    {!NO_NEWS}

    This is calling up a Composr "language string". It is the string we have that says "there is no news yet". We don't hard-code English in our default templates because we don't want to assume Composr sites will be in English.
    For themes it is alright to hard-code English text.
  6. Code

    {$?,{BLOG},{!BLOG_NO_NEWS},{!NO_NEWS}}

    This is a little bit of logic. BLOG is a parameter that is either true or false, and it is passed to specify whether the block is showing a "blog".
    In English this code is saying…

    "If this is a blog, show the language string BLOG_NO_NEWS otherwise show the language string NO_NEWS."

    The purpose of the logic is we don't want to say "there is no news yet" when we are talking about blog posts (we want to say something like "there are no posts yet").
  7. Code

    {$IS_NON_EMPTY,{SUBMIT_URL}}

    This checks to see if the parameter SUBMIT_URL is passed in. If it is then it outputs 'true' otherwise it outputs 'false'.

    SUBMIT_URL is the parameter containing the "add news" URL. We only pass it in to the block if the current user has access to add news. So before we can output an <a> link to that URL we need to check it's actually available.

    However, because this code is actually used inside a check (see 11, below) it is not actually output directly, it just is used for that check.
  8. Code

    {$?,...,<a rel="add" href="{SUBMIT_URL*}">{!ADD_NEWS}</a>|}

    This checks to see if "…" is true, and if it is then it puts out a <a> tag using SUBMIT_URL as the URL and a language string ADD_NEWS as the link text.

See also


Feedback

Please rate this tutorial:

Have a suggestion? Report an issue on the tracker.