If you always think and work in the same way, you’ll probably get the same results. If you want something completely new, then try something different.
Indeed, when using common CMSs, you have to code several files (like header.php, page.php, post.php, etc.) in order to create a basic structure for your website. With those systems, this base structure acts as a design foundation that you have to update over time to ensure compatibility within your CMS. So, even after you have spent hours coding the files, you have not even started on the design yet.
We think that theme design should be simple (and powerful). When we created our Website Builder, we decided to start from scratch instead of relying on what already existed. This approach gave us the freedom to focus on the things that are really important for designers: styles, content and the logic behind them. No more struggling with technical stuff.
It is a very basic “theme” that provides minimal structure and layout. When you create a new theme, you are actually extending this.
Indeed it’s always enabled in your setup and it acts exactly like the CMS’s base structure we mentioned above, except that you don’t have to create or maintain it.
It will upgrade automatically within your Flectra installation and, since it is included in the Website Builder module, everything is smoothly integrated by default.
An Flectra theme is not a folder containing HTML or PHP files, it’s a modular framework written in XML. Never worked with XML files before? Don’t worry, after following the tutorial, you’ll be able to create your first theme with only basic knowledge of HTML.
Using classical web design workflows, you usually code the layout of the entire page. The result of this is a “static” web page. You can update the content, of course, but your client will need you to work on making even basic changes.
Creating themes for Flectra is a total change of perspective. Instead of defining the complete layout for a page, you can create blocks (snippets) at let the user choose where to “drag&drop” them, creating the page layout on their own.
As a designer, your goal is to style these elements in order to achieve a wonderful result, regardless of where the end user chooses to place them.
Let’s take a tour of our “list” elements:
..container:: row
..figure:: theme_tutorial_assets/img/snippet.jpg
:figclass:col-sm-6
Snippets (or building-blocks)
A piece of HTML code. The user will drag&drop, modify and combine them using our built-in Website Builder interface. You can define sets of options and styles for each snippet. The user will choose from them according to their needs.
..figure:: theme_tutorial_assets/img/page.jpg
:figclass:col-sm-6
Pages
These are normal web pages, except that they will be editable by the final user and that you can define an empty area that the user can “fill” by dragging snippets into it.
..raw:: html
<div class="clearfix themes"></div>
..container:: row
..figure:: theme_tutorial_assets/img/styles.jpg
:figclass:col-sm-6
Styles
Styles are defined using standard CSS files (or Less/Sass). You can define a style as **default** or **optional**. The default styles are always active in your theme, the optional styles can be enabled or disabled by the user.
Thanks to Flectra’s modularity, everything can be personalized even more. This means there are endless possibilities for your creativity. Adding functionalities is easy and it’s simple to provide the end user with customizable options.
Flectra’s themes are packaged like modules. Even if you are designing a very simple website for your company or client, you need to package the theme like an Flectra module.
``category`` defines your module category (always “Theme”) and, after a slash, the subcategory. You can use one subcategory from the Flectra Apps categories list. (https://www.flectra.com/apps/themes)
``depends`` specifies the modules needed by our theme to work properly. For our tutorial theme, we only need website. If you need blogging or eCommerce features as well, you have to add those modules too.
An Flectra page is the visual result of a combination of 2 kind of elements, **cross-pages** and **unique**.
By default, Flectra provides you with a **Header** and a **Footer** (cross-pages) and a unique main element that contains the content that makes your page unique.
Imagine that we want to create a specific layout for a Services page.
For this page, we need to add a list of services to the top and give the client the possibility of setting the rest of the page’s layout using snippets.
Inside your *views* folder, create a **pages.xml** file and add the
As you can see, we wrapped our code into two ``<div>``, one with ID ``wrap`` and the other one with class ``container``. This is to provide a minimal layout.
The next step is to add an empty area that the user
can fill with snippets. To achieve this, just create a ``div`` with
``oe_structure`` class just before closing the ``div#wrap`` element.
The **sequence** attribute defines the link’s position in the top menu.
In our example, we set the value to ``99`` in order to place it last. I you want to place it in a particular position, you have to replace the value according to your needs.
As you can see inspecting the *data.xml* file in the ``website`` module, the **Home** link is set to ``10`` and the **Contact** us one is set to ``60`` by default.
If, for example, you want to place your link in the **middle**, you can set your link’s sequence value to ``40``.
Of course Bootstrap is not enough if you want to provide a unique design. The following steps will guide you through how to add custom styles to your theme.
The final result won't be pretty, but will provide you with enough information to build upon on your own.
Let’s start by creating an empty file called **style.less** and place it in a folder called **less** in your static folder.
The following rules will style our *Services* page. Copy and paste it, then save the file.
.. as of Pygments 2.2, the Less lexer can't handle inline comments or nested
rules so use scss instead, it's not quite perfect but it doesn't trigger
warnings/errors
..code-block:: scss
.services {
background: #EAEAEA;
padding: 1em;
margin: 2em 0 3em;
li {
display: block;
position: relative;
background-color: #16a085;
color: #FFF;
padding: 2em;
text-align: center;
margin-bottom: 1em;
font-size: 1.5em;
}
}
Our file is ready but it is not included in our theme yet.
Let’s navigate to the view folder and create an XML file called *assets.xml*. Add the default Flectra xml markup and copy/paste the following code. Remember to replace ``theme folder`` with your theme’s main folder name.
Since snippets are how users design and layout pages, they are the most important element of your design.
Let’s create a snippet for our Service page. The snippet will display three testimonials and it will be editable by the end user using the Website Builder UI.
Navigate to the view folder and create an XML file called **snippets.xml**.
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
</div>
</div>
</div>
</section>
</template>
As you can see, we used Bootstrap default classes for our three columns. It’s not just about layout, these classes **will be triggered by the Website Builder to make them resizable by the user**.
The previous code will create the snippet’s content, but we still need to place it into the editor bar, so the user will be able to drag&drop it into the page. Copy/paste this template in your **snippets.xml** file.
..code-block:: xml
<template id="place_into_bar" inherit_id="website.snippets" name="Place into bar">
We start by adding a new file in our views folder - name it **options.xml** and add the default Flectra XML markup. Create a new template copy/pasting the following
The previous template will inherit the default **snippet_options template** adding our options after the **background** options (xpath expr attribute).
To place your options in a particular order, inspect the **snippet_options template** from the **website module** and add your options before/after the desired position.
As you can see, we wrapped all our options inside a DIV tag that will
group our options and that will target them to the right selector
(``data-selector=".snippet_testimonial"``).
To define our options we applied ``data-select-class`` attributes to the
``li`` elements. When the user selects an option, the class contained in
the attribute will automatically be applied to the element.
Since ``selectClass`` method avoids multiple selections, the last "empty"
option will reset the snippet to default.
Add **options.xml** to ``__manifest__.py`` and update your theme.
..image:: theme_tutorial_assets/img/restart.png
Dropping our snippet onto the page, you will notice that our new options are automatically added to the customize menu. Inspecting the page, you will also notice that the class will be applied to the element when selecting an option.
Great! We successfully created options for our snippet.
Any time the publisher clicks on an option, the system will add the class specified in the data-select-class attribute.
By replacing ``data-select-class`` with ``data-toggle-class`` you will be able to select
more classes at the same time.
Javascript Options
------------------
``data-select-class`` and ``data-toggle-class`` are great if you need to perform
simple class change operations. But what if your snippet’s customization needs something more?
As we said before, ``data-js`` propriety can be assigned to an options group in order to define a custom method. Let’s create one for our *testimonials snippet* by adding a ``data-js`` attribute to the option’s group div that we created earlier.
Great, we successfully created our javascript editor file. This file will contain all the javascript functions used by our snippets in edit mode. Let’s create a new function for our testimonial snippet using the ``snippet_testimonial_options`` method that we created before.
As you will notice, we used a method called ``onFocus`` to trigger our function. The Website Builder provides several events you can use to trigger your custom functions.
``start`` Fires when the publisher selects the snippet for the first time in an editing session or when the snippet is drag-dropped into the page
``onFocus`` Fires each time the snippet is selected by the user or when the snippet is drag-dropped into the page.
``onBlur`` This event occurs when a snippet loses focus.
``onClone`` Fires just after a snippet is duplicated.
``onRemove`` It occurs just before that the snippet is removed.
``onBuilt`` Fires just after that the snippet is drag and dropped into a drop zone. When this event is triggered, the content is already inserted in the page.
``cleanForSave`` It trigger before the publisher save the page.
Basically all the elements in a page can be edited by the publisher.
Besides that, some element types and css classes will trigger special Website Builder functionalities when edited.
Layout
------
``<section />``
Any section element can be edited like a block of content. The publisher can move or duplicate it. It’s also possible to set a background image or color. Section is the standard main container of any snippet.
``.row > .col-md-*``
Any medium bootstrap columns directly descending from a .row element, will be resizable by the publisher.
``contenteditable="False"``
This attribute will prevent editing to the element and all its children.
``contenteditable="True"``
Apply it to an element inside a contenteditable="False" element in order to create an exception and make the element and its children editable.
``<a href=”#” />``
In Edit Mode, any link can be edited and styled. Using the “Link Modal” it’s also possible to replace it with a button.
Media
-----
``<span class=”fa” />``
Pictogram elements. Editing this element will open the Pictogram library to replace the icon. It’s also possible to transform the elements using CSS.
``<img />``
Once clicked, the Image Library will open and you can replace images. Transformation is also possible for this kind of element.
This html structure will create an ``<iframe>`` element editable by the publisher.
SEO best practice
=================
Facilitate content insertion
----------------------------
Modern search engine algorithms increasingly focus on content, which means there is less focus on **keyword saturation** and more focus on whether or not the content is **actually relevant to the keywords**.
As content is so important for SEO, you should concentrate on giving publishers the tools to easily insert it. It is important that your snippets are “content-responsive”, meaning that they should fit the publisher’s content regardless of size.
Let’s have a look to this example of a classic two column snippet, implemented in two different ways.
Using background images that fit the column height, the publisher will be free to add the content regardless of the image’s height.
Page segmentation
-----------------
Basically, page segmentation means that a page is divided into several separate parts and these parts are treated as separate entries by search engines.
When you design pages or snippets, you should be sure to use the right tags in order to facilitate search engine indexing.
``<article>``
Specifies an independent block of content. Within it should be a piece of self-contained content that should make sense on its own. You can nest ``<article>`` elements within one another. In this case, it’s implied that the nested elements are related to the outer ``<article>`` element.
``<header>``
Indicates the header section of a self-contained block of content (an ``<article>``).
``<section>``
Is the snippet default tag and it specifies a subsection of a block of content. It can be used to split ``<article>`` content into several parts. It’s advisable to use a heading element (``<h1>``–``<h6>``) to define the section’s topic.
``<hgroup>``
Is used to wrap a section of headings (``<h1>`` - ``<h6>``). A great example would be an article with both a headline and sub-headline at the top:
..code-block:: html
<hgroup>
<h1>Main Title</h1>
<h2>Subheading</h2>
</hgroup>
Describe your page
------------------
Define keywords
'''''''''''''''
You should use appropriate, relevant keywords and synonyms for those keywords. You can define them for each page using the built-in “Promote” function found in the bar at the top.
Define a title and a description
''''''''''''''''''''''''''''''''
Define them using the “Promote” function. Keep your page titles short and include the main keyword phrase for the page.
Good titles evoke an emotional response, ask a question or promise something.
Descriptions, while not important to search engine rankings, are extremely important in gaining user click-through. These are an opportunity to advertise content and to let people searching know exactly whether the given page contains the information they're looking for. It is important that titles and descriptions on each page are unique.