HTML Logo by World Wide Web Consortium (www.w3.org). Click to learn more about our commitment to accessibility and standards.

Moving forward with Composr

ocPortal has been relaunched as Composr CMS, which is now in beta. ocPortal 9 will be superseded by Composr 10.

Head over to compo.sr for our new site, and to our migration roadmap. Existing ocPortal member accounts have been mirrored.


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

Written by Chris Graham, ocProducts
ocPortal 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 ocPortal to efficiently implement your design.


Feedback

It is very important that at any point where you think things are confusing, either in ocPortal, or in this documentation, that you write it down and let us know. We strive to make ocPortal 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 ocPortal easy to use.

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

Research into ocPortal

  1. Install the most recent stable version of ocPortal (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 ocPortal 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 what 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 ocPortal. 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:
  1. 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. If content is missing, it shouldn't just leave empty boxes (for example), you need to think how things will work.
  3. 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. Whilst 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. 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. 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 ocPortal 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. Sometimes not everything should show for every user. For example a link to add content might only be shown to administrators.
  8. You may find ocPortal's default templates have large numbers of nested div tags. This is because ocPortal 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.

Implementing your design

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

Static design

  1. Implement your XHTML/CSS as standalone, if you haven't already.
  2. Make sure you have followed these guidelines:
    • Don't use the CSS clear property, because it interferes with how ocPortal handles it's 3-column layout and other default styling. Contain floats in a box using something like overflow: hidden;.
    • 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.
    • 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 and it makes pixel-level browser bugs cause larger problems.
    • Do not use floats unless doing it to make stuff sit next to something else. For example, do not float stuff just to make it not overlap with another float, and do not float stuff to try and work around IE bugs. There are much better ways to solve these problems without resorting to floats (which introduce many other kinds of problem).
    • Do not use background images unless an image really is in the background. It is harder to implement (needs CSS widths/heights setting, which is inflexible) and we can't use transparency in IE6 if we do this and we can't assign alt text. Use 'img' tags Instead.
    • Do not use a CSS reset: ocPortal does not use a CSS reset in it's default templates so you would need to re-theme all ocPortal screens to re-apply default spacings.
    • Make sure the default font size is sensible for the main content area. You will not be able to specify the font size of all text on the final theme as there will be a lot of layout that comes from default ocPortal templates and you won't have time to give them all individual consideration.
    • It's not a good idea to make your main content area too thin, because default ocPortal templates will assume that they have at least about 600 pixels.
    • 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

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 –> Site 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; ocPortal is smart enough to detect if files have been changed in most cases.

This section is accompanied by a video.

Images and CSS

  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 ocPortal as theme images.
  2. Go to edit the CSS for your theme in ocPortal. Do this by going to the Admin Zone, selecting 'Themes' from the drop down, and choosing 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 ocPortal 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 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 panels and have made the assumption that they will never be blank/hidden, then you must put supports_wide=0 into your themes/<theme>/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 ocPortal 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 ocPortal 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 ocPortal.

This section is accompanied by a video.

Laying out your panel/page structure

  1. Once things look fairly good it is time to start incorporating all the individual blocks onto the site, as identified in the 'Research into ocPortal' 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 the Content Management section, underneath the 'Pages' icon. 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 (Comcode is like plain text but with some tags, or you can type [semihtml]...[/semihtml] to put in a mix of raw XHTML and Comcode). Or, you can edit all panels at once in the Zone Editor via the prominent 'Edit in Zone Editor' links. 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'. You can place these using code like {$BLOCK,block=<blockname>}. Similarly sometimes there is a menu in the footer, which can be placed like

      Code

      {$BLOCK,block=side_stored_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 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.

There are a small number of cases where (for performance reasons) ocPortal 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 page by pasting this special comment into it:

    Code

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

This section is accompanied by a video.

Last steps

  1. It is a good idea to verify your theme is stable across different ocPortal 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 ocPortal uses global.css inside an iframe, for example). First do a verification manually by viewing a few screens; good choices are: the forum index, doing a website search, and previewing some changes from an edit form.
  2. Next you can verify your theme more formally by using the 'Screen previews' feature from the 'Themes' section of the Admin Zone. 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 ocPortal 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. We suggest specifically testing in: IE8, IE9, Firefox, Google Chrome.
  4. 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 ocPortal 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.
  5. Also, don't forget to implement a favicon ;). In ocPortal 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.
  6. 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.
  7. 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

What is the difference between Comcode and Tempcode?

ocPortal content, panels, and pages, are mostly written in ocPortal'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).

ocPortal 'Comcode' is very similar to this standard 'bbcode', but it can do a lot more. In ocPortal 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].

In ocPortal we also have our templating system, 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.

In particular some confusion can arise between Comcode and Tempcode, because both languages can be used to place blocks but the syntax is very different due to the conceptual difference between the languages. The concept of an ocPortal block is independent to Comcode or Tempcode, it's just a feature of ocPortal, and both languages can tie in to it.

Here is how blocks can be placed in both languages…

Code

[block="mainparameter" a="1" b="2"]blockname[/block]
is a "Comcode tag". 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:
  • We have this Comcode short-hand notation for it.
  • Most blocks use it to pass in the main parameter the block needs, usually some kind of ID code. For example, for the side_stored_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.

Here is another Tempcode symbol… {$USER}. It shows the member ID of the current logged in user.

When ocPortal runs it actually converts the simple Comcode into the more complex Tempcode. And you can put Tempcode inside Comcode and it will work. But Comcode cannot be used in Templates because it's not processed in there.

Comcode or XHTML?

Comcode is a powerful language but you do not need to use it, because you can just use a single Comcode tag to embed XHTML into that Comcode.
Just write like this:

Code

[semihtml]
XHTML goes here
[/semihtml]

If you have some simple content that is just plain text, it's best to just write it in Comcode. Otherwise, it does not matter a lot if you use XHTML. Comcode exists to make it easier for non-experts to write content, but you know XHTML already.

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 host's, 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!).

Placing blocks into templates

You can place a block in a template like:

Code

{$BLOCK,block=<blockname>,...}
Where "…" is further parameters.

For an example you can see how it is done for the side_stored_menu block, in the 'Menus' section further down.

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 an ocPortal menu) you can generate a consistent link to the page like:

Code

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 ocPortal! The URLs can be different, depending on what SEO options are enabled. 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 ocPortal'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 in XHTML, and we call this "escaping". For example if a URL contains "&" it must actually be written using "&amp;" in the XHTML.

This is actually important for security, if you don't properly "escape" your data it can lead to all kinds of security holes.

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

ocPortal does not handle this automatically because the conversion carries an assumption, and it is up to you to decide in what context your data is being used (e.g. a Javascript template likely would not want XHTML escaping applied). But in 99% of cases it will need the '*'.

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 ocPortal, 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. Go to Content Management > Pages (Comcode Pages) and 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 create :panel_<panelname> and :otherpagename. 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, you will need to make a copy of your logo called themes/<yourthemename>/images/logo_template.png but without any site-name or slogan on it. The Logo Wizard will then write it on. If you need the logo wizard to put them in different places to the default ocPortal logo, or to use different colours, you can put the following into your themes/<yourthemename>/theme.ini file:

Code

site_name_colour=FFFFFF
slogan_colour=6082BF
slogan_x_offset=5
slogan_y_offset=85
slogan_font_size=9
site_name_split=316
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=5
site_name_y_offset=22
site_name_y_offset_small=14
and customise the numbers until they work.

Menus

You 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:
  • zone: used at the top of the default theme.
  • top: styled to work well as a single-layer horizontal menu. On the default theme it's used on the forums, for example.
  • dropdown: a horizontal menu with drop-downs. Used in the Admin Zone, for example.
  • tree: a vertical menu. Used by default on panels.
  • embossed: a vertical menu, that makes each link look like a button.
  • 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 it's 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 side_stored_menu block.

Code

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

Code

[block="<name>" type="<layouttype>"]side_stored_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. If you're making a theme it's best to try and use default pre-existing menu names (ones that are there on any new ocPortal installation) so that the default links are immediately available in your theme (menu links are considered content, so not exported with your theme).
The following default menus exist in ocPortal:
  • zone_menu – top-level navigation, between sections of the website
  • main_content – links to module content category-navigation (a bit formulaic, so best only used if you need a secondary navigation)
  • main_website – website meta-features, good for use as a footer menu
  • main_community – website community links
  • member_features – features relating to members
  • root_website – menu shown on welcome zone, if collapsed zones not enabled
  • Access to specific features: wiki_features, ecommerce_features
  • Forum zone menus: forum_personal, forum_features
  • Collaboration zone menus: collab_website, collab_features

Catalogues (for custom content types)

When you have a custom content type to add (something that there isn't a specific ocPortal 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 –> CATALOGUE_project_staff_CATEGORY_EMBED
  • CATALOGUE_DEFAULT_ENTRY_EMBED –> CATALOGUE_project_staff_ENTRY_EMBED
  • CATALOGUE_DEFAULT_ENTRY_FIELD –> CATALOGUE_project_staff_ENTRY_FIELD
(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 the IMG tag and these can both be found in this way.

This section is accompanied by a video.

Finding where ocPortal CSS is set

If you are using Firefox, there is an excellent free extension called 'Firebug'. There are very similar tools built into all the other major browsers now.

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 an ocPortal 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 ocPortal 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 Firebug 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).

Login boxes

The [block]side_personal_stats[/block] Comcode is used for creating a login box. 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, whilst 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). Like with all blocks you can show it in a template using Tempcode like {$BLOCK,block=side_personal_stats}. For these situations heavy template/CSS changes will probably be needed as if it is in a header it will need to be designed to look long and thin, not box shaped.

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.

Social media buttons

These are achieved using ocPortal'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).

Text resize buttons

A lot of designs have buttons to change the font size. Personally I think this is a dreadful feature (because it's already a feature of every web browser, so achievable by the end user in a consistent way that works across all websites), but a lot of clients like it because they think it is a mark of an accessible website.

Assuming your designs use 'em' font sizes then you can easily achieve it by adding a little Javascript like this to your text size buttons:

Code

onclick="document.body.style.fontSize='120%'; return false;

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.

The default ocPortal panel_top already does something similar to what we do here: it shows a community menu but only on certain 'community-related' ocPortal pages. There is little reason to keep that so should not resist overriding it like we suggest here.

This section is accompanied by a video.

Development/debug mode

If you are developing from a subversion checkout (you'll know if you are) then your install will be in development/debug mode. The main thing you will notice is that invalid XHTML will often create very nasty error screens in the browser. This is an intentional feature, as we throw ocPortal into this mode for developers so that bugs cannot go unnoticed and to ensure we write proper XHTML. On live sites we don't have development/debug mode on because it is inevitable that bad XHTML will leak in, and many versions of Internet Explorer can't support proper XHTML mode anyway.

One problem though is some third-party code won't work with XHTML. For example, we have observed that Google Maps cannot. To disable XHTML you can manually/temporarily add this to the end of the URL: &keep_no_dev_mode=1. This will carry through with any links you click.

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 ocPortal 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 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>.

Internationalisation

ocPortal 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 ocPortal 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

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

DESIGNED_BY_TEAM=Conēµ par {1}

All ocPortal 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.

How Tempcode works, an illustrated example

This is the default BLOCK_SIDE_NEWS.tpl

Code

<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 ocPortal 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 ocPortal templates – ocPortal obviously cannot make an assumption about how many news posts a site has, and content obviously is not hard-coded into templates, so ocPortal 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 ocPortal puts them all together as a sequence, and ocPortal 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_PIECE_SUMMARY.tpl. So CONTENT here is lots of filled-in NEWS_PIECE_SUMMARY.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

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

This just is some static HTML.

5)

Code

{!NO_NEWS}

This is calling up an ocPortal "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 ocPortal 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