HTML Development GuidelinesThese are general principles that are recommended to be applied to any new projects in SilverStripe. You might also want to read the first 2 SilverStripe tutorials to get a understanding of how the templating works. These guidelines are designed to provide designers and developers of SilverStripe widgets, themes and modules with generic HTML that is easily adaptable in different modules and projects. DOCTYPESPer HTML and XHTML standards, a DOCTYPE (short for “document type declaration”) informs the validator which version of (X)HTML you’re using, and must appear at the very top of every web page. DOCTYPEs are a key component of compliant web pages: your markup and CSS won’t validate without them. DOCTYPES are also essential to the proper rendering and functioning of web documents in compliant browsers like Mozilla, IE5/Mac, and IE6/Win. A recent DOCTYPE that includes a full URI (a complete web address) tells these browsers to render your page in standards–compliant mode, treating your (X)HTML, CSS, and DOM as you expect them to be treated. - you can read the whole article from A List Apart here The SilverStripe approved DOCTYPE (and namespace)This is the vaild DOCTYPE that we should use for our sites where appropriate. This is what the default theme - BlackCandy uses. Since this theme will be the most used all Modules *should* work with this DOCTYPE so we can have consistency <?xml version="1.0" encoding="UTF-8"?> ExampleOne thing that SilverStripe does is detect if the site is XHTML or HTML and it has the ability to transform the site between the two. This is done by the Content Negotiator Class.
It automatically rewrites the DOCTYPE and content code to the HTML 4.01 standard if it does not detect the document serving as XML with an XML header. Rendered output with XML tag: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> Rendered output without XML tag: <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> Content negotiation isn’t always appropriate. If you don’t want it, add this line to your _config.php file: ContentNegotiator::disable(); ConcernsSean: XHTML 1.1 to me isn’t necessary, HTML 4.01 does the job, and there isn’t any real value of using XHTML over HTML since IE doesn’t serve up xml documents properly anyway. There’s also some absolutely silly standards, like not being able to use _target attributes in an anchor element because it won’t validate if you do. WTF? Javascript is the less favourable way of doing the same thing in XHTML! Its all in the HEADOur top part of our theme is something like this <?xml version="1.0" encoding="UTF-8"?> After the XML header and the DOCTYPE, The HEAD element contains information about the current document, such as its title, keywords that may be useful to search engines, and other data that is not considered document content. User agents do not generally render elements that appear in the HEAD as content. They may, however, make information in the HEAD available to users through other mechanisms. There are 2 SilverStripe Specific Tags that are needed to be put inside the HEAD section. Base tag<% base_tag %>
base_tag is replaced with the HTML base element. Relative links within a document (such as <img src=”someimage.jpg”...) will become relative to the URI specified in the base tag. This ensures the browser knows where to locate your site’s images and css files. So it is a must for templates! It renders in the template as: <base href="http://www.mydomain.com" />
Meta Tags$MetaTags
This returns a segment of HTML appropriate for putting into the <head> tag. It will set up title, keywords and description meta-tags, based on the CMS
content and is editable in the ‘Meta-data’ tab on a per-page basis. If
you don’t want to include the title-tag <title> (for custom
templating), use By default $MetaTags renders: <title>Title of the Page</title> IncludesWithin SilverStripe templates we have the ability to include other templates from the Includes directory using the SS ‘include’ tag. For example, the following code would include the Incldues/SideBar.ss code: <% include SideBar %>
The includes tag can be particularly helpful for nested menus, reducing clutter. Eg: This code will include Includes/Menu1.ss if there is a Menu(1) object to be rendered. <div id="Navigation"> Inclusion of external files (CSS/Javascript)We automatically include some core SilverStripe css files using Requirements (layout.css, typography.css). Instead of linking to stylesheets from your template instead use this in your Page→init() function: Requirements::themedCSS("stylesheetName"); For IE conditional comments you will still need to have it in your Page.ss file This function will clear either a single or all requirements, where you can use one of the follwing as an argument; ‘css’, ‘javascript’, ‘customScript’, ‘customCSS’. Caution: Clearing single rules works only with customCSS and customScript if you specified a {@uniquenessID}. Requirements::clear(); Dividing your site the correct way!Most Web page designers 10 years ago used a table-based layout to achieve a consistent look. Now, (Thankfully) there’s a different way to achieve the same look.
Using CSS and tags (including
For layout we tend to use Let’s have a look at part of a Page.ss for the main layout elements defining a 2 column layout. <div id="Container"> A couple notes on naming IDs and classes
<div id="Container"><!-- markup goes here --></div> As you can see we normally wrap the site in a container. For this we use the ID ‘Container’. Then we divide the main template into sections. <div id="Header"><!-- markup goes here --></div> We have the Header section which includes things like any banner images/ mastheads/ logos or any stuff that belongs at the top of the page, This might vary on the design of the page <div id="Navigation"><!-- markup goes here --></div> Next is a division for the main navigation. This may contain something like: <div id="Navigation"> This is the standard for creating the main Navigation. As you can see it outputs the Menu 1 in a unordered list. Before stepping into a control (a foreach loop) it’s good practise to check if it exists first. This is not only important in manipulating SilverStripe templates, but in any programming language! <% if MyFunction %> Last and probably least is the Footer division. Here is where you put all the Footer related stuff for your website. Maybe even a nice link saying Website Powered by SilverStripe to show your support. <div id="Footer"> Our Basic Page.ss now<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> $Layout
Now we have our root Page.ss file you’ll notice there’s a variable called Where does this come from and what does it do? This is where sub-templates defined in /templates/Layout are rendered. In this case the page type as defined is just a ‘Page’, therefore it will use templates/Layout/Page.ss. If you have a Page type of NewsHolder it will load the same Page.ss file. However, when it gets to $Layout it will go looking for templates/Layout/NewsHolder.ss. If that doesn’t exist, then it will default to templates/Layout/Page.ss. So, at the very least, we need a Page.ss file and a templates/Layout/Page.ss. A sample templates/Layout/Page.ss file for our 2 column site might look like this: <div id="Content"> MenusBelow is a good example of a menu. It can be used for 2 levels of nesting. Beyond that, you’ll probably need to create functionality to recursively generate templating based on the level your pages are in.
What’s special about this? We’re using
Menu items are also abstracted, so you’re not relying on a certain element to be there, like a <% if Menu(2) %> TablesTables *are* okay in some circumstances, specifically where you want to present tabular data. Make sure you follow a few rules:
Here’s a sample to use as a template. <table summary="The number of employees and the foundation year of some imaginary companies."> |
