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

ocPortal Developer's Guide: Templates

» Return to Contents



ocPortal enforces a strict separation between content, presentation and code. This is referred to as the MVC (model, view, controller) design pattern and has become the evangelised practice for corporate web design.
Template files are stored in a raw format, and are defined with the standard 'override system' of ocPortal; as well as this, though, a theme only has to define those templates it changes from the 'default' theme. Search, parsing, and applying linguistic translation, to templates like this would not be efficient, so ocPortal compiles the templates upon first-use (unless this option is disabled).
The ultimate compilation target for templates is 'serialised tempcode'; if the template is cached as this, it will be loaded direct into memory, and it will be bound to the parameters of the template (for example, a download box template might take the download name and URL as parameters).

ocPortal supports template overrides for PDA's. If there is a template with the prefix THIN_, then this template will be used instead of the normal template if keep_thin is in the URL, or if a PDA was detected.

Template Guidelines:
  • Templates have been kept very simple. The whole point is to keep code out of the presentation, so if we started applying things like complex looping or if's into individual templates, it would become un-editable (easily) in an HTML editable. We also don't want code in the templates so templates can't become a security issue to a server [NB: XSS could be introduced]
  • {X} means "Insert parameter X". If no parameter {X} is given, no replacement is made
  • {!X} means "Insert language element X". If the language element is missing, ocPortal will give an error page
  • {!X,BLAH} means "Insert language element X with parameter BLAH". BLAH may be a symbol or a template parameter. If the language element is missing, ocPortal will give an error page
  • {$X} means "Insert symbol X". The symbols are not PHP variables (although the syntax is similar, because it is an analogous concept). Instead, a number of general symbols are defined (see example.txt). For example, the site name of base URL.
  • Templates are not just used for HTML, they are sometimes used for other structured text (e.g. comcode emails, phrases)
  • Template parameters are often other templates to be embedded. This is called template encapsulation, and the whole site is built up by encapsulating different templates into each other. Nothing is echoed-out/embedded-html inside modules or blocks
  • Templates should be defined at a high granularity of detail. For example, form elements should all be done through templates - in fact modules/blocks should contain no HTML at all (not even entities!)
  • The most extreme template is probably EMAIL_SUBJECT, which allows the user to customise an outgoing e-mail's subject line. Take note on the granuarity and clean design we are trying to achieve
  • All modules/blocks should wrap themselves in a unique or a standard template. Ordering, structural-layout and what is on a page shouldn't be implicit in the code. This might lead to tiny silly looking templates, but it is worth it
  • Try to use standard templates wherever possible, to make editing easier and keep consistency high, but if there is reason (prettiness, bespokeness, or whatever) to use custom templates, do it
  • Try to make templates encapsulate each other, instead of making START_X and END_X combinations. By encapsulating templates we allow easier editing, use less templates, improved simplicity and more elegance
  • Never use native language in templates or modules/blocks
  • If a section of HTML needs a standard-box around it (to make it stand out as a lump on its own), then if no title is needed, use the {$START/END_TABLE} symbols from within the templates. This allows the templates to be edited to use tailored table types if needed.
  • For making modules, you must use HTML templates and not comcode. This is for efficiency, control, and simplicity of design
  • HTML escaping is done in templates, by adding a * before a symbol/parameter/language closing brace
  • If you want to have a tooltip for an image (perhaps the image meaning is not obvious), use the title tag. The alt tag is intended for alternate text when the image itself is not viewable. This means, if you want a tooltip, you must have BOTH alt and title attributes. Whilst IE would only need alt, we must obey the STANDARDS.
  • class=blend must be used on almost all <img> tags ; put it as the first attribute so it's easy to find non-conforming tags using a file search
  • Break CSS and Javascript up modularly, so to avoid shoving things for specific modules into global files; at the same time, promote re-use by putting sensible stuff into global files
  • Don't use the XHTML style attribute except in certain conditions that could be considered structural
  • Don't ever use inline <style> because it's invalid. Use require_css with standard theme sheets.
  • Inline <script> is absolutely fine, so long as it's not a primary page that could instead use require_js. Inline <script> is very handy when a block needs some Javascript, as it's too late to include the JS time by the time the block is decached and output; it's also handy when it would just be over-engineering to create new JS files. Inline <script> should use the proper CDATA technique.
  • Javascript must not be required for functionality, unless there are alternatives
  • Template names should use unique prefixing for the 'template set' they are in, and screens should end in '_PAGE', and files only used for blocks should be named 'BLOCK_<block-name>[_SUFFIX]'. Template names should be in upper case.
  • Templates must make sense to an HTML editor: no substituting tag attribute names with template parameters, for example
  • Only use layout tables where CSS cannot replace them (there are a few major cases but they are exceptions in the grander scheme of things); when using them, mark with a blank summary. Do not use crazy hacks just to avoid layout tables. Make sure CSS works on IE.
  • Test on IE6 (anything older is ancient), latest Firefox, latest Opera, latest Konqueror, latest Safari (the assumption is that all but IE users regularly upgrade browsers)
  • Write semantic and accessible markup: all markup regulations must be met, including the manual checks defined in the XHTML page of the devguide
  • Colons and so forth may be used in templates in a visual way (even though strictly it is an English'ism). However, you can't make assumptions about word order by saying things like {!GO} {!HERE}
  • You may assume that if there is Javascript support, there is AJAX support: but don't be silly and use AJAX when an iframe would be just or more suited!
  • Name CSS classes according to what they are for and not what they do (e.g. big_and_red_page_icon is a terrible name)
  • Pass in additional unused parameters to the template where appropriate; raw timestamps, IDs, etc
  • For viewing content: if someone has permission to edit something, pass in EDIT_URL as the URL to edit it, otherwise pass in as empty; use the standard STAFF_ACTIONS include method for displaying any actions within the template
  • Use colgroup for table column widths, not CSS 'width'
  • Don't use unusual symbols like » in templates as characters, because they likely look wrong if the language character set is changed: instead use HTML entities
  • Only forcibly open up links in new windows in these conditions:
    • The action is strictly auxillary to an ongoing action (e.g. opening up documentation to read whilst performing the action)
    • An ongoing action is being performed that will spawn many followup actions that are not going to flow
    • It is a link to an external website on the main website placed in a prominent position (e.g. link to RSS news story)
    • When it's a Javascript popup box (this is actually another example of a 'strictly auxillary action')
  • Do not forcibily open up links in these conditions, or any other not mentioned above:
    • When it's a link to an external site not in a prominent position on the main website
    • The action is arguably auxillary but often many not be (e.g. Editing a zone by alt+shift+control clicking a zone name)
    • When moving between non-strongly related resources (e.g. clicking on a username in the forumview)
    • Do not provide dual new-window and non-new-window links, as it's redundant - the web browser can handle it
  • When links are sent to new windows, remember to use {!LINK_NEW_WINDOW} in the link title
  • Don't open Javascript windows unless there's a good reason to (a popup box)

Key Templates:
  • BASIC_HTML_WRAP, For pages outside of the core pages system that need to generate full XHTML
  • COMMENTS, For making comments
  • RATING/VOTING, For rating resources
  • HTML_REFRESH, For pages outside of the core pages system that need to redirect to something else
  • REDIRECT_PAGE, When a page knows its going to redirect, use this template to say "this is done, I am refreshing in a few seconds"
  • MOVE_PAGE, For pages where something is being moved between pages/sections/whatever
  • FORM_PAGE, A page that is for data entry
  • FORM, A form, but not a big one: a part of a page only
  • VIEW_SPACE, A part of a page that is for viewing data
  • INDEX_PAGE/INDEX_PAGE_ENTRY/INDEX_PAGE_ENTRY_DUMMY, A page having a shortish paragraphed list of things to choose
  • INDEX_PAGE_FANCY/INDEX_PAGE_FANCY_ENTRY/INDEX_PAGE_FANCY_ENT
    RY_DUMMY, A page having a shortish HTML list of things to choose
  • INDEX_PAGE_FANCIER/INDEX_PAGE_FANCIER_ENTRY/INDEX_PAGE_FANCI
    ER_ENTRY_DUMMY, A page having a shortish tabled/descripted list of things to choose
  • WARNING_TABLE, A table on a page that is a warning about the nature of that page
  • POST, Some kind of discussion post
  • LINK_LIST_START/LINK_LIST_MIDDLE/LINK_LIST_LAST, A list of links, maybe buttons. At time of writing, separated by " | "
  • NOTHING_HERE, For an embedded message mentioning something that isn't there (e.g. no posts yet)
  • CATEGORY_LIST/CATEGORY_ENTRY, A list of things to choose from inside a category (some kind of category / page)
  • DO_NEXT/DO_NEXT_ITEM, Task Manager interface
  • TABLE_TABLE/TABLE_TABLE_HEADER_ROW/TABLE_TABLE_HEADER_ROW_CE
    LL/TABLE_TABLE_ROW/TABLE_TABLE_ROW_CELL, Templates for rendering a plain table of something
  • TABLE_TABLE_ACTION_DELETE_CATEGORY/TABLE_TABLE_ACTION_DELETE
    _ENTRY/…, Buttons for performing actions on a tables rows
  • RESULTS_*, for displaying pages of information and information shown in tables
  • CONFIRM_PAGE/FORM_CONFIRM_PAGE, Show a preview and confirm it's ok
  • YESNO_PAGE, Confirm the action is as wanted
  • TABLE_SEPERATOR, Spacing between standard-box
  • FORM_DESCRIP_SEPERATOR, Spacing to allow for multiple lines in a form entries description
  • FORM_GROUPED, FORM_GROUP, A form where the fields are grouped
  • BLOCK_SPACER, Make a gap between blocks/tables
  • NEXT_BROWSER_*, Very simple browsing through multiple pages
  • MODLINK_*, Show a link to do some moderation/staff action, but not one related to content management
  • PRIVILEGE_ACTION_*, Show links to do some content management action to viewed content
  • PAGE_SUBTITLE_TREE, Show a subtitle that is in tree-form
  • MEDBORDER_BOX, Much like a standard-box
  • PAGE_BUTTON/PAGE_ITEM_BUTTON, Show a standard shaped button on the page
  • REVISION_*, For resources with a revision history
  • CATEGORY_TREE_SPLIT/CATEGORY_TREE_SPLIT_ESCAPED, Very simple template for separating elements of tree-elements in a line in a drop-down list

Dynamic pages (modules) are constructed out of templates, where the code necessitates a certain kind of template structure, with certain parameters: unfortunately there is no way this could be any different. The only way to template something like the download system, would be to go through the templates used by the system and change them on a one-by-one basis. If you choose 'XHTML' from the choices in the login block, you can view the XHTML source of a page; if you then choose the big link at the top of that, the page will be spit out with markers so you can identify the templates used in it's construction. Another method is to go through the source code (if you understand it) and look to see what do_template commands are called. A third way would be to make educate guesses… for example, the main download module template is called 'DOWNLOAD_PAGE'. Generally you can ignore the small templates unless you want to define a high granularity of detail (and you must also be careful with them, because they are often used on different modules: if 563 templates is a lot, it might be 1563 if we hadn't done that :S).

Static pages are far easier. When reproducing a static page you aren't constrained by any code requirements and have full artistic control, except for the fact it is put between the menus and inside the GLOBAL template, with HEADER at the top and FOOTER at the bottom. To create a static page, you can just add a comcode page and either write it in comcode, or just put your HTML between comcode 'html' tags. Those GLOBAL, HEADER and FOOTER templates will give you control over the majority of your sites layout. Additionally, ocPortal is by default constructed out of what we call "standard boxes". By editing CSS and editing the STANDARDBOX_* templates, you can give your site a very independant look; this is what the gusblue and alien themes do, and are good reference examples.

The best way to theme ocPortal is to start with ocPortal, then craft it towards how you want it to be, bit by bit. It's unfortunate it can't just morph styles as easily as changing an .htm file, but this is just the unavoidable nature of advanced software containing lots of code driven features. It is possible to make ocPortal look completely different with a lot of templating; but it is also possible and a lot easier to work with ocPortal's default template, making fairly minor changes, and tweak it toward a very stylised direction.

I really don't like working in text boxes on web pages, I'd rather use a text editor. So what I do is I turn off the ocPortal template cache in the configuration and I just edit the .tpl files directly. I find it a lot quicker.
In fact, by default if ocPortal is installed on your own computer, all the caches are turned off and XHTML validation is turned on. ocPortal runs slower, but I find it a lot easier to work locally in my own text editor, without worrying about caches getting in the way, or internet connection latency or downtime.

Most of these functions here are basically front-ends for templates, so that you don't have to use do_template all the time.

sources/templates.php

Global_functions_templates.php

Function summary

void init__templates ()
tempcode put_in_standard_box (tempcode content, mixed title, ?string dimensions, ID_TEXT type, string options, string meta, string links, boolean expand, string toplink)
tempcode get_page_title (mixed title, boolean dereference_lang, ?array params, ?tempcode user_online_title, ?array awards)
tempcode hyperlink (mixed url, mixed caption, boolean external, boolean escape, mixed title, ?string accesskey, ?tempcode post_data, ?string rel, ?ID_TEXT overlay)
tempcode paragraph (mixed text, string guid, ?string class)
tempcode div (tempcode tempcode, string guid)
tempcode inform_screen (tempcode title, mixed text)
tempcode warn_screen (tempcode title, mixed text, boolean provide_back)
tempcode form_input_hidden (ID_TEXT name, string value)
tempcode form_input_list_entry (string value, boolean selected, mixed text, boolean red, boolean disabled)
tempcode with_whitespace (string in)
tempcode redirect_screen (tempcode title, mixed url, mixed text, boolean intermediatory_hop, ID_TEXT msg_type)

void init__templates()

Standard code module initialisation function.

Parameters…

(No return value)


Return to the function index for this class Expand: View the source code to this function

tempcode put_in_standard_box(tempcode content, mixed title, ?string dimensions, ID_TEXT type, string options, string meta, string links, boolean expand, string toplink)

Get the tempcode for a standard box (CSS driven), with the specified content entered. Please rarely use this function; it is not good to assume people want anythings in one of these boxes... use templates instead

Parameters…

Name content
Description The content being put inside the box
Type tempcode

Name title
Description The title of the standard box, string or Tempcode (blank: titleless standard box)
Default value
Type mixed

Name dimensions
Description The width/height classification (e.g. 100%, 100%|300px, …) (NULL: unset)
Default value
Type ?string

Name type
Description The type of the table. Refers to a template (STANDARDBOX_type)
Default value classic
Type ID_TEXT

Name options
Description '|' separated list of options (meaning dependant upon templates interpretation)
Default value
Type string

Name meta
Description '|' separated list of meta information (key|value|key|value|…)
Default value
Type string

Name links
Description '|' separated list of link information (linkhtml|…)
Default value
Type string

Name expand
Description If the box will be allowed to expand.
Default value boolean-false
Type boolean

Name toplink
Description Link to be added to the header of the box
Default value
Type string

Returns…

Description The contents, put inside a standard box, according to the other parameters
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode get_page_title(mixed title, boolean dereference_lang, ?array params, ?tempcode user_online_title, ?array awards)

Get the tempcode for a page title. (Ones below the page header, not in the browser title bar.)

Parameters…

Name title
Description The title to use (usually, a language string code, see below)
Type mixed

Name dereference_lang
Description Whether the given title is actually a language string code, and hence gets dereferenced
Default value boolean-true
Type boolean

Name params
Description Parameters sent to the language string (NULL: none)
Default value
Type ?array

Name user_online_title
Description Separate title to put into the 'currently viewing' data (NULL: use $title)
Default value
Type ?tempcode

Name awards
Description Awards to say this has won (NULL: none)
Default value
Type ?array

Returns…

Description The title tempcode
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode hyperlink(mixed url, mixed caption, boolean external, boolean escape, mixed title, ?string accesskey, ?tempcode post_data, ?string rel, ?ID_TEXT overlay)

Get the tempcode for a hyperlink.

Parameters…

Name url
Description The URL to put in the hyperlink (URLPATH or tempcode)
Type mixed

Name caption
Description The hyperlinks caption (either tempcode or string)
Type mixed

Name external
Description Whether the link is an external one (by default, the external template makes it open in a new window)
Default value boolean-false
Type boolean

Name escape
Description Whether to escape the hyperlink caption (only applies if it is not passed as tempcode)
Default value boolean-false
Type boolean

Name title
Description Link title (either tempcode or string) (blank: none)
Default value
Type mixed

Name accesskey
Description The access key to use (NULL: none)
Default value
Type ?string

Name post_data
Description Data to post (NULL: an ordinary link)
Default value
Type ?tempcode

Name rel
Description Rel (link type) (NULL: no special type)
Default value
Type ?string

Name overlay
Description Open in overlay with the default link/form target being as follows (e.g. _top or _self) (NULL: an ordinary link)
Default value
Type ?ID_TEXT

Returns…

Description The generated hyperlink
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode paragraph(mixed text, string guid, ?string class)

Get the tempcode for a paragraph. This function should only be used with escaped text strings that need to be put into a paragraph, not with sections of HTML. Remember, paragraphs are literally that, and should only be used with templates that don't assume that they are going to put the given parameters into paragraphs themselves.

Parameters…

Name text
Description The text to put into the paragraph (string or tempcode)
Type mixed

Name guid
Description GUID for call
Default value
Type string

Name class
Description CSS classname (NULL: none)
Default value
Type ?string

Returns…

Description The generated paragraph
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode div(tempcode tempcode, string guid)

Get the tempcode for a div. Similar to paragraph, but may contain more formatting (such as <br />'s)

Parameters…

Name tempcode
Description The tempcode to put into a div
Type tempcode

Name guid
Description GUID for call
Default value
Type string

Returns…

Description The generated div with contents
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode inform_screen(tempcode title, mixed text)

Get the tempcode for an info page.

Parameters…

Name title
Description The title of the info page
Type tempcode

Name text
Description The text to put on the info page (string, or language-tempcode)
Type mixed

Returns…

Description The info page
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode warn_screen(tempcode title, mixed text, boolean provide_back)

Get the tempcode for a warn page.

Parameters…

Name title
Description The title of the warn page
Type tempcode

Name text
Description The text to put on the warn page (either tempcode or string)
Type mixed

Name provide_back
Description Whether to provide a back button
Default value boolean-true
Type boolean

Returns…

Description The warn page
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode form_input_hidden(ID_TEXT name, string value)

Get the tempcode for a hidden form element.

Parameters…

Name name
Description The name which this input field is for
Type ID_TEXT

Name value
Description The value for this input field
Type string

Returns…

Description The input field
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode form_input_list_entry(string value, boolean selected, mixed text, boolean red, boolean disabled)

Get the tempcode for a list entry. (You would gather together the outputs of several of these functions, then put them in as the $content in a form_input_list function call).

Parameters…

Name value
Description The value for this entry
Type string

Name selected
Description Whether this entry is selected by default or not
Default value boolean-false
Type boolean

Name text
Description The text associated with this choice (blank: just use name for text)
Default value
Type mixed

Name red
Description Whether this entry will be put as red (marking it as important somehow)
Default value boolean-false
Type boolean

Name disabled
Description Whether this list entry is disabled (like a header in a list)
Default value boolean-false
Type boolean

Returns…

Description The input field
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode with_whitespace(string in)

Display some raw text so that it is repeated as raw visually in HTML.

Parameters…

Name in
Description Input
Type string

Returns…

Description Output
Type tempcode

Return to the function index for this class Expand: View the source code to this function

tempcode redirect_screen(tempcode title, mixed url, mixed text, boolean intermediatory_hop, ID_TEXT msg_type)

Redirect the user - transparently, storing a message that will be shown on their destination page.

Parameters…

Name title
Description Title to display on redirect page
Type tempcode

Name url
Description Destination URL (may be Tempcode)
Type mixed

Name text
Description Message to show (may be Tempcode)
Type mixed

Name intermediatory_hop
Description For intermediatory hops, don't mark so as to read status messages - save them up for the next hop (which will not be intermediatory)
Default value boolean-false
Type boolean

Name msg_type
Description Code of message type to show
Default value inform
Type ID_TEXT
Values restricted to warn inform fatal

Returns…

Description Redirection message (likely to not actually be seen due to instant redirection)
Type tempcode

Return to the function index for this class Expand: View the source code to this function

sources/templates_interfaces.php

Global_functions_templates_interfaces.php

Function summary

tempcode tpl_crop_text_mouse_over (string text, integer len)

tempcode tpl_crop_text_mouse_over(string text, integer len)

Get tempcode for cropped text, that fully reveals itself on mouse-over.

Parameters…

Name text
Description The text
Type string

Name len
Description The length to crop at
Type integer

Returns…

Description The cropped text
Type tempcode

Return to the function index for this class Expand: View the source code to this function

How to set up a do-next browser

The do-next browser is passed an array of lines. Here is an example of one, after the do_lang stuff has been written out:

Code

   array('blog_icon',array('cms_news',array('type'=>'ad'),'cms'),'Add a blog entry','Blah blah this text is hovered'),

Going from left to right:
  • the icon theme image name
  • the page name (cms_news)
  • the list of URL parameters (in this case, one: 'type' as 'ad')
  • the zone (cms)
  • the link caption
  • the hover text