Создание темы для вебсайта

Содержание

В этой статье мы рассмотрим, как использовать модуль website, который идет в стандартной поставке Community Edition.

Подготовка

Для того, чтобы использовать следующий пример, вам необходимо переключить текущий разрабатываемый проект на другую ветку.

Вот ее имя - 16.0-website-usage-example

Затем удалите текущую базу и создайте новую.

Убедитесь, что у вас не осталось вкладок со старыми сессиями

В файл конфигурации в параметры init_modules и update_modules добавьте имя модуля theme_airproof

Запустите менеджер с параметрами -d, -i, и -u

Перейдите откройте браузер по адресу http://127.0.0.1:8069

Небольшое вступление

Использование темы описано в официально документации вот тут. При попытке использовать это описание лично у меня возникло большое количество вопросов, которые не описаны в документации, поэтому эта статья(статьи) буду опираться ровно на те же разделы, которые есть в официальной документации, только уже с опорой на рабочий код, который вы можете найти в моем демо-репозитории.

Тема в odoo

Темой в odoo называется специальный модуль, который объявлен специальным образом:

Создание модуля-темы

  1. В ключе category файла __manifest__.py необходимо указать значение Theme
  2. В ключе depends файла __manifest__.py необходимо добавить модуль website
  3. В имени модуля на первом месте должно стоять ключевое слово theme_

Менеджер тем в odoo

Чтобы установить произвольную тему вам нужно выполнить следующие действия:

Веб редактор

  1. Залогиниться
  2. Выбрать пункт меню Website
  3. Нажмите Edit, чтобы открыть редактор темы

Выбор тем для установки

  1. Нажать Theme
  2. Пролистать вниз и нажать Switch Theme

В появившемся окне выбрать нужную тему:

Менеджер тем

Как видите, наша тема с именем Airproof уже установлена, мы можем ее обновить, удалить или установить другую тему.

Первоначальные настройки темы

Данный раздел опирается на вот эту статью из официально документации.

Все первоначальные параметры указываются в файле primary_variables.scss. Естественно его необходимо добавить в ассеты в файле __manifest__.py:

Базовые параметры Когда будете заполнять параметры обращайте внимание на ключи, которые заполняются в primary_variables.scss файле.

Использование шрифтов

Так как шрифты это важная часть оформления сайта и, как правило, является базовой, то с них и начнем. Odoo может использовать самостоятельно использовать как шрифты от google: Использование шрифтов Google Здесь вы можете видеть пример использования шрифтов от google без дополнительных манипуляций. Достаточно просто правильно объявить их параметры и система сама их начнет использовать через публичное API

А вот пример того, как вы можете использовать любые другие шрифты локально: Использование локальных шрифтов

  1. Объявляете в файле __manifest__.py в бандле web.assets_frontend дополнительный файл который я назвал fonts.scss.
  2. Описывает базовые параметры шрифта, в том числе, указываете url относительно имени модуля
  3. Добавляете описание шрифта в primary_variables.scss

Для того, чтобы эти шрифты применились их необходимо правильно объявить:

Объявление шрифтов

  1. Объявляем шрифт по умолчанию
  2. Шрифт заголовков
  3. Шрифт в панели навигации
  4. Шрифт на кнопках

Результат использования шрифтов:

Результат использования шрифтов

  1. Использование шрифта из коллекции Google Nunito
  2. Использование собственного шрифта AlumniSansPinstripe

Задание собственных ключевых цветов для темы

Так же для темы вы можете объявить базовые цвета. Это делается так же внутри файла primary_variables.scss следующим образом:

Объявление базовых цветов

  1. Объявление пяти базовых цветов
  2. Здесь могут быть объявлены вспомогательные цвета
  3. Данный набор цветов объявляется как airproof и подключается для использования в теме как набор цветов по умолчанию

Результат объявления базовых цветов:

Объявление базовых цветов Обратите что эти цвета используются по всем элементам сайта, а так же видны в веб-редакторе как основные цвета темы.

Продолжение следует...(эта статья будет писаться в несколько подходов, т.к. объем очень большой)

Компоновка элементов страницы

В данном разделе мы будем опираться на вот этот раздел документации. Глобально современный сайт, как правило, состоит из трех основных элементов:

  • Заглавная часть (Header) В этой части как правило находятся контакты, ссылки на социальные сети, а так же основное меню сайта
  • Собственно тело страницы (Webpage). Здесь находится контент конкретной страницы.
  • Подвал (Footer). Здесь располагается информация о компании, контактах и другие ссылки, которые могут быть полезные посетителям, но находятся за рамками основного контента сайта.

Заглавная часть (Header)

Объявление header

  1. Обратите внимание для какой модели создается запись
  2. С помощью директивы xpath заменяем стандартный header своим.
  3. Пример изменения ссылок социальных медиа
  4. Вызов шаблона, который отображает кнопку аутентификации, с передачей параметров

Внимательно изучите шаблон заглавной части целиком. Здесь вы можете увидеть, что все элементы из которых состоит шаблон тоже используют вызов дополнительных шаблонов. Вы можете использовать такую же стратегию, а можете создавать описание html прямо внутри текущего шаблона. Исходите из вашей собственной задачи.

Объявление footer

  1. Обратите внимание для какой модели создается запись
  2. С помощью директивы xpath заменяем стандартный footer своим.
  3. Пример блока с призывом
  4. Пример блока с контактным телефоном
  5. Пример блока с почтой
  6. Пример блока с социальными медиа
  7. Пример блока с собственным логотипом

Обратите внимание, что в отличии от заглавной части здесь не используются дополнительные шаблоны, а все нужные блоки html объявлены прямо тут

Тело страницы (Webpage)

Объявление webpage

  1. Обратите внимание как объявлена запись, если вы хотите объявить ее как record то она должна будет принадлежать модели theme.ir.ui.view
  2. С помощью директивы xpath заменяем стандартный footer своим.
  3. Объявляем переменные, которые будут указывать на необходимость рендерить header и footer.
  4. Собственно тело страницы.

Элементы навигации

В данном разделе мы будем опираться на вот этот раздел документации. В этом разделе мы поговорим про элементы навигации, как их добавлять, убирать и менять

Создание элементов меню

Создание элементов меню

  1. Удаляем элемент меню, который вел на страницу контактов
  2. Пример добавления элемента главного меню. Обратите внимание на поле с именем parent_id в нем вы можете увидеть, что применяется метод search с использованием домена, где происходит поиск по имени родительского url и id вебсайта. Как было сказано ранее сайтов может быть больше чем один(вероятно поиск id сайта надо делать через xml_id, но это пример из официальной документации). В данном случае значение родительского url=/default-main-menu зарезервировано системой. Кстати контроллера для обслуживания данного url не существует, поэтому система вернет 404 страницу
  3. Пункт меню Еще. Создается таким же образом как и предыдущий, но как вы видите он уже имеет дочерние пункты. Поэтому при нажатии на него показывается выпадающий список
  4. Пункт меню, который ссылается на внешний сайт. Обратите внимание на значение поля parent_id, здесь уже применяется поиск нужного id с помощью xml_id, и для данного пункта меню родителем является предыдущий.
  5. Еще один дочерний пункт меню, который возвращает 404 страницу

Мега-меню

Мега меню Мега-меню представляет собой некоторый, достаточно большой, контейнер, куда можно уместить множество дополнительных пунктов меню, уже с помощью обычного html, а так же любой другой произвольный контент.

  1. Атрибут меню, который указывает на то что этот пункт меню является мега-меню
  2. Класс, который добавляется к контейнеру, в который помещается контент мега-меню
  3. Контент мега-меню

Управление страницами

В данном разделе мы будем опираться на вот этот раздел документации. В этом разделе мы поговорим про создание отдельных страниц и их оформление

Уже существующие страницы

В стандартной поставке, внутри системы уже есть несколько предопределенных страниц:

  • Страница ошибки 400
  • Страница ошибки 403
  • Страница ошибки 404
  • Страница ошибки 500
  • Страница Home
  • Страница Contact us

Вы можете отключить уже определенные страницы следующим образом:

Для домашней страницы

<record id="website.homepage" model="ir.ui.view">
    <field name="active" eval="False"/>
</record>

Для страницы контактов

<record id="website.contactus" model="ir.ui.view">
    <field name="active" eval="False"/>
</record>

Так же вы можете изменить уже существующую страниц с помощью наследования и директивы XPath Изменение стандартной страницы для ошибки 404

  1. С помощью атрибута inherit_id переопределяем стандартную страницу 404
  2. С помощью директивы XPath указываем что мы хотим заменить узел id="wrap" содержимым нашей директивы
  3. С помощью предопределенной переменной additional_title указываем название страницы
  4. Пишем контент нашей переопределенной страницы

Предопределенные переменные для использования в страницах

Название страницы:

<t t-set="additional_title" t-value="'...'"/>

Meta описание:

<t t-set="meta_description" t-value="'...'"/>

Добавляем CSS класс на страницу

<t t-set="pageName" t-value="'...'"/>

Прячем Заглавую часть (Header)

<t t-set="no_header" t-value="true"/>

Прячем Подвал (Footer)

<t t-set="no_footer" t-value="true"/>

Создание своей страницы

Для начала давайте добавим картинку, которая будет доступна для использования внутри системы:

Добавляем картинку в медиа каталог

  1. Указываем путь к файлу с изображением относительно имени нашего модуля
  2. Созданная запись с id="img_about_01" в модели ir.attachment становится доступной в медиа каталоге. Атрибут public="True" указывает на то, что этот ресурс будет доступен для всех посетителей сайта, а только внутренних

Теперь используя эту картинку в качестве фона создадим свою страницу: Создаем свою страницу

  1. Наименование страницы, отображается в наименовании вкладки браузера
  2. Поле is_published со значением True указывает на то, что эта страница доступна всем посетителям сайта, а не только внутренним
  3. Поле type со значениемqweb указывает на то, что при формировании страницы будет использовать генератор шаблонов qweb
  4. Поле header_overlay со значением True указывает на то, что хедер не будет прилипать к верху как отдельный блок, а страница, будет как бы заходить за него
  5. Использование ранее объявленной картинки, обратите внимание как указан url до нее /web/image/имя_модуля.id_записи_картинки. Опытные читатель уже заметил что это полный xml_id записи этой же картинки. Т.е. все ресурсы объявленные как в примере выше, будут доступны по url созданному по следующему шаблону: /web/image/xml_d_записи
  6. Поле urlсо значением about-us указывает на то, по какому url будет открываться данная страница
  7. Поле key должно хранить уникальный ключ для данной страницы(я пока не выяснил для чего конкретно, узнаете пишите)

Как добавлять виде описано тут Как добавлять иконки описано тут

Создание и управление отдельными блоками (сниппетами)

В данном разделе мы будем опираться на вот этот раздел документации. В этом разделе мы поговорим про создание отдельных блоков и настройке их поведения

Блоки

В odoo создан механизм для создания собственных блоков контента, которые вы можете создавать, а ваши пользователи применять у себя самостоятельно. Блоки делятся на следующие типы:

  1. Структурные блоки: дают возможность управлять основной структурой сайта
  2. Блоки описания функциональности: дают возможность создавать описание условий и функциональности товаров или услуг
  3. Блоки с динамическим контентом: это анимированные блоки, или связанные с бэкэндом
  4. Блоки вложенного контента: блоки, которые предназначены для размещения внутри других блоков

Увидеть все доступные на текущий момент блоки вы можете вот по этой ссылке:

http://127.0.0.1:8069/website/demo/snippets

Структура файлов

Файлы, которые будут описывать блоки должны находиться в следующих местах: Расположение файлов сниппета

  1. В каталоге со статическими ресурсами создаете каталог snippets, где для каждого блока создаете отдельный каталог и файлы, которые нужны для его работы
  2. В каталоге views тоже создаете каталог snippets, в котором будут основные шаблоны этих самых блоков

Создание блока

Создание блока начинается с создания его шаблона: Объявление шаблона блока

  1. Уникальный id шаблона
  2. Уникальное имя класса шаблона
  3. Отображаемое имя блока в панели конструктора. Если не указано, будет применено название Block.
  4. Используется системой для идентификации блока
  5. Тег <section/> используется для самостоятельных блоков, если же блок предназначен для размещения внутри других блоков, то тэг должен быть <div/>

Внутри блока вы можете использовать стандартную сетку Bootstrap, как это сделать правильно описано вот тут

Теперь нам необходимо сделать так, чтобы наш новый блок появился в меню конфигуратора, и мы могли его использовать

Добавление блока в конфигуратор

  1. Наследуем шаблон с блоками (Здесь применяется стандартный механизм наследования для xml представлений)
  2. Добавляем наш набор блоков (состоящий из одного блока) в перед стандартными блоками
  3. Тэг <t/> в котором мы указываем id="x_theme_snippets" - видимо нужен для служебных целей, чтобы система могла его правильно пристыковать
  4. Уже описываем собственно раздел с нашими блоками атрибут id="x_theme_snippets_category" так же нужно указывать, данный элемент мы уже можем видеть внутри DOM модели браузера
  5. Служебный тег <t/> который собственно и определяет уже наш блок. Обратите внимание что в качестве значения атрибута t-snippet указан полный xml_id, а так же атрибут t-thumbnail где указан путь к svg файлу, относительно имени модуля.
  6. Ключевые слова, которые нужны для поиска блока в общем списке

Про дополнительные опции можете прочитать тут

Теперь давайте перетянем на страницу наш блок и заглянем в его параметры: Добавление добавление свойств к блоку

  1. data-selector - позволяет прицепить к определенному элементу пункт меню редактора и добавлять дополнительные классы через конструкцию data-select-<custom-attribute>. В этом примере мы видим что для элемента с селектором table при выборе какого либо пункта меню добавляются в нашем случае class="table-bordered" для выбранного Bordered. Обратите внимание на служебные теги с префиксом we данные теги указывают на то что это они предназначены для работы внутри WebEditor.

Так же часто возникает ситуация, когда нужно использовать что-то более динамическое и в этом случае необходимо будет использовать javasсript. Вот как это можно сделать:

Добавление js к пункту меню в кофигураторе

  1. Для того, чтобы система знала какую именно функцию вызвать ее имя необходимо указать в качестве имени атрибута с ключевым словом data вначале, где разделителем слов должен быть дефис(kebab-case), а имя функции в js должно быть написано camelCase. В нашем случае атрибут с именем data-start-table-func вызовет функцию с именем startTableFunc
  2. в js файле импортируем объект options из web_editor.snippets.options
  3. Добавляем в реестр options свой собственный класс, который будет наследовать options.Class
  4. Объявленная нами функция будет принимать на вход три параметра:
    1. previewMode - имеет булево значение, определяет, является ли в данный момент блок в режиме предпросмотра
    2. widgetValue - параметр, который является значением атрибута из пункта 1
    3. params - объект, который описывает собственно объект настроек, какие параметры могут быть, какие функции содержатся и какие параметры могут быть выбраны

Создание и формами для произвольной модели

В данном разделе мы будем опираться на вот этот раздел документации. В этом разделе мы поговорим про создание форм на сайте, которые будут автоматически заполнять поля в у казанной модели.

Формы

Формы - отличный инструмент для того, чтобы получить обратную связь от ваших пользователей. В инструментарии вебсайта есть возможность создавать формы для заранее предопределенных моделей. Для этого вам достаточно следовать инструкции из официальной документации. Там указаны модели для которых вы можете сделать формы. Но что делать если мы хотим сделать форму для произвольной модели?. Ниже я расскажу как это можно сделать.

В файл конфигурации проекта в параметры init_modules и update_modules добавьте имя модуля website_first_module

Давайте создадим шаблон формы: Шаблон формы

  1. Создаем пункт меню, который будет вызывать указанный адрес, а по этому адресу будет открываться наша страница с формой.
  2. Для того, чтобы наша форма отправляла данные в нужную нам модель необходимо указать в атрибуте data-model_name="first.model" имя модели, в нашем случае это first.model
  3. Параметр data-success-mode указывает тип подтверждения при удачной отправке данных через форму в нашем случае redirect можем быть еще message но об этом позже
  4. Параметр data-success-page нужен при использовании метода подтверждения redirect и указывает на какую страницу произойдет перенаправление пользователя
  5. При оформлении полей необходимо у тега input указать атрибут name в котором необходимо написать техническое имя поля (из python файла модели)

При открытии шаблона мы увидим три поля, которые можем заполнить. Для того, чтобы добавить эту фому в редактор сайта, необходимо заполнить дополнительные поля:

Форма в редакторе 0. Выделенная прямоугольником запись показывает какие поля и как нужно заполнить для того, чтобы форма появилась в редакторе

  1. Указывается дополнительное поле для хранения дополнительной и мета информации. Чуть подробнее будет в следующем блоке
  2. Наименование формы можно видеть в редакторе

В целом можно пользоваться, но обратите внимание не следующий момент:

Белый список полей

  1. Для того, система сама заполняла поля из полей формы, необходимо указать запуск функции для нужной вам модели, которая пометит поля в системе как доступные для заполнения из формы.
  2. Обратите внимание что мы заполнили 3 поля а значения записались только те, которые указаны в функции 1
  3. Третье значение тоже сохранилось но в текстовом виде в поле из пункта 1 предыдущего блока
  4. Поле для сохранения дополнительной информации с формы.

Обсуждение

Обсудить, указать на ошибки и опечатки можно здесь