LiveWhale CMS is designed to work well with a range of website coding styles, as long as a few general best practices are followed in the code. These tips can be useful whether you’re designing a site for the LiveWhale team to help implement, or if you’re doing it yourself using your knowledge of theming.
General coding guidelines
LiveWhale works great with HTML/CSS/JS created by outside developers. In most cases, the code buildout of a site can be brought into the LiveWhale CMS with very little substantive change to the codebase or coding style.
This being the case, there are a few general tips that will help you make your code especially friendly to the CMS, and make implementation as quick and easy as possible. Many of these are generally accepted best coding practices, but a couple are related to specific LiveWhale functions and methods.
We keep this article up to date as we learn about new tips and tricks from implementing outside builds. If you’re running into difficulty making your code work in LW, let us know!
Use <ul> for dynamic content listings
Any content updated or managed through the CMS is automatically displayed using an unordered list. The <ul>
markup is great for news story listings, profiles listings, etc. (If you’re developing a profile slider or other unique feature that requires specific markup, you can change the default markup using a widget template.)
Keeping CSS classes to the outermost parent container works best for most widgets, which use the default <ul>
markup. If there are styles (or CSS-triggered Javascript interactions) that are specific to a particular design element or section of the page, those classes should be set on the wrapper div, and not on the child items themselves.
Instead of coding like this:
<div>
<ul class="story-list">
<li class="story-list-item first-item">
List item #1
</li>
<li class="story-list-item second-item">
List item #2
</li>
</ul>
</div>
… code like this:
<div class="story-list">
<ul>
<li>
List item #1
</li>
<li>
List item #2
</li>
</ul>
</div>
And then apply styles or JS functions to .story-list > ul > li:first-child
, for example, instead of .story-list-item.first-item
.
This makes LW conversion much easier— widgets return <ul>
lists by default, for example, and LiveWhale can easily wrap your style around any particular element. There might be some places in the code where this isn’t possible, but in general it should be possible for just about any front end design need.
For dynamic content items delivered as lists, the markup of each list item should be identical.
As an example, imagine a feature story carousel. In that markup, whatever element is repeated to create the individual items in the carousel (usually either an <li>
or a <div>
), ought to be coded identically.
To create widgets in LiveWhale, we take that repeated markup and apply it to the widget in question, replacing dynamic placeholders for the actual content elements. Then a widget, after configuration, repeats that markup as many times as needed for the number of items required in the list.
(Note that a feature like this can include any code you like before or after the repeated element, including wrappers to apply CSS classes, parent tags, etc.)
Use IDs for primary editable content areas (#main, #sidebar, etc.)
Most webpages have content areas for main body text and sidebar text (and often others). Please define areas like this by ID (such as #main, #sidebar, etc.). These IDs should wrap only content that’s going to be editable by the user (and not other page components that might be visually located inside those areas).
LiveWhale admins can quickly make these content areas editable by adding class="editable"
to any region with an ID. Once that class is added, all the content inside that div, including HTML, can be edited by the user. So the ID’d regions shouldn’t contain any elements that you wouldn’t want an end user to potentially remove.
CSS House Style
Everyone has their own coding styles. This is simply the approach we employ and enjoy using:
-
Keep CSS class names clear, consistent and informative.
For example.profile-card
with.profile-card_image
and.profile-card_title
-
We prefer classed selectors over element selectors:
.news-widget_summary
rather than.news-widget > p
This makes it easier for us to change the<p>
to a<div>
if needed or nest the<p>
inside other elements. -
Reduce specificity by avoiding long chained class names if possible
.parent-element_child_grandchild
rather than
.parent-element .parent__child .parent__grandchild
-
Please separate style and structure when coding different versions of a component or layout:
•.news-widget.large
and.news-widget.small
for large/small layout
•.news-widget.yellow
and.news-widget.red
for denoting color separate from sizing
• Layout classes like.page-container.wide
which can be reused on other templates, rather than a template-specific class like.profile-template-body
• Descriptive classes like.large
and.yellow
and.wide
are only used in conjunction with other classes. -
If you like using SASS or LESS preprocessors, please do! We like to take advantage of nested selectors. It makes it much easier to apply an entire set of styles under on parent class.
-
For most components containing text, please account for various text heights when building the component (ie no fixed heights in CSS!). Exceptions can be made, usually for a hero feature at the top of the page, or anything else that is very difficult or time consuming.
JavaScript
-
Javascript that runs on window scroll, resize, or another frequently-occuring event should be throttled/debounced to avoid poor performance.
-
Styles should be kept out of JavaScript if possible. Apply classes with JS, and use these selectors to style with CSS. Indicate the class had been applied by JS by using a descriptive class like is-open or is-active
Adding interactivity to LiveWhale pages
When writing your own custom Javascript/jQuery –- for sliders, modal popups, video features, or anything else that requires click or action listeners –– it’s common to attach those things to the DOM ready:
$(document).ready(function() {
// code here runs on DOM ready
});
However, certain Livewhale widgets may be randomized or paginated, and those things happen after page load. To make sure your scripting also affects those randomized/paginated widgets, we recommend hooking into the lw.randomize and lw.paginate triggers as well.
;(function($) {
// code here runs on DOM ready
$('body').on('randomize.lw paginate.lw', function(e, el){
// code here applies after widgets have been randomized or paginated
});
$('body').on('stopEdit.lw', function(e) {
// code here runs after a page has been edited and saved
});
}(livewhale.jQuery));
We often code these with separate functions, for example an initSliders();
that we run once on DOM ready, and then again after randomize.lw and paginate.lw in case any of those elements are in use in randomized/paginated widgets.
Here are all of the LiveWhale JS hooks that might be useful:
Name | When it’s fired | Example |
---|---|---|
randomize.lw | After widget loads randomized results |
$('body').on('randomize.lw', function(e, el){
|
paginate.lw | After widget loads paginated results |
$('body').on('paginate.lw', function(e, el){
|
pageBeforeEdit.lw | When “Edit Page” is clicked |
$('body').on('pageBeforeEdit.lw', function(e, el){
|
pageEditReady.lw | After “Edit Page” is clicked, once ready to edit |
$('body').on('pageEditReady.lw', function(e, el){
|
stopEdit.lw | After page has been edited and saved |
$('body').on('stopEdit.lw', function(e, el){
|
When Delivering Code to the LiveWhale Team
If you’re having our team help with your design implementation (contact us to discuss), here are some tips for how to prepare your designs to make the CMS conversion of your templates as efficient as possible.
Sample pages
A working HTML page, and an accompanying JPEG graphic, for each template design created for the site. These should be delivered as plain HTML pages, with no server-side includes or other server scripting, separately from the elements below.
One page containing one each of all the dynamic content elements (“widgets”) to be used on multiple pages of the site. These typically include the following:
- news story lists
- navigations
- calendar feeds
- photo/feature carousels
- social media widgets
- and any other content element that will be reusable on the site.
These sample pages should reference the same CSS and JS files that are referenced in the formal code delivery package.
Formal code delivery:
Separate include files for elements common to all pages
-
Head content (head.html)
Including all contents of tag that are consistent across all pages -
Page header (header.html)
Usually includes site title and top level navigation -
Page footer (footer.html)
Include any links to Javascript files that are common to all templates -
Other sitewide include files if appropriate
-
Note: It’s not uncommon for the homepage to have its own unique versions of these elements; while it’s ideal for all includes to be truly sitewide, variant includes for the homepage or another special page are fine.
Page templates
-
One file for each design template included in the package
-
Clearly indicate where file includes are to be inserted (using syntax like INCLUDE: header.html)
-
Filename should indicate the template name and have .php extension (samples: inside-page.php, department-homepage.php, news-story.php)
-
Most LiveWhale sites require a “details page” for the following items:
• News story
• Faculty profile (and staff profile, student profile, etc.) -
Provide a web form with all form field types— ideally using as little markup as possible, with CSS styles applied to generic form elements (textarea, select, input[type=text], etc.)
Editable (“static”) webpage content
- Areas of static content, meaning the editable “informational” text of a webpage, should be clearly indicated— ideally with the class “editable,” applied to only the section of a page that will be editable by webpage editors.
Images
- We strongly recommend using the placeholder.com service to generate image placeholders for use in your page templates. This removes the need to include “generic” images in your code delivery, and makes it simple for us to identify the exact image size needed on the back end. If your webpages are responsive, use the largest size your design requires for the image. Don’t worry about retina sizing— LiveWhale upsizes images automatically for retina screens.
Widget-based (“dynamic”) reusable content
-
Dynamic content, as mentioned above, includes news story lists, calendar feeds, photo/feature carousels, social media widgets, and any other content element that will be reusable on the site. In LiveWhale we call these dynamic content elements “widgets.”
-
Your code should be structured in such a way that any widget could theoretically be placed on any page of the site and function correctly. This means that the CSS classes that make a feature work— the styles for thumbnail images in a list, for example, or classes that trigger jQuery functions— should be limited to the specific block tag containing the markup in question.
-
The code for each repeated element in a widget should be identical. See above for more details.
-
As long as these general rules are respected, dynamic content elements can be used on your webpages any way you like. (As noted above, we do request a single sample page containing one of each dynamic content element designed for the site.)