CRM — Odoo Business 0.1 documentation

主题教程

Odoo歌颂自由。自由的设计师去进一步和自由的用户自定义一切,根据他们的需要。

准备好创建自己的主题了吗?伟大的.在你开始之前,有些事情你应该知道。本教程是一个指导创建Odoo主题。

网页设计师简介

如果您使用的是Odoo首次一个网页设计师,你是在正确的地方。课程将概述Odoo题材创作的基础。

From common CMS to Odoo

哪里是我的header.php文件 ?

这通常是从一个用WordPress或Joomla来到Odoo首次工作的网页设计师的第一个问题。

事实上,当使用普通的CMSs,你有几个文件的代码(像header.php,page.php,post.php,等)为你的网站创建一个基本的结构。有了这些系统,这个基础结构作为一个设计基础,你必须更新随着时间的推移,以确保兼容性在您的CMS。所以,即使你花了几个小时编码文件,你还没有开始设计。

不会 用于创建Odoo主题.

Odoo default theme structure

Odoo有一个默认的主题结构。这是一个非常基本的“主题”,提供最小的结构和布局。当你创建一个新的主题,你实际上是延长。事实上,它总是在你的设置和它的行为完全像CMS的基础结构,我们上面提到的,除了你不必创建或维护它。它会自动升级在你安装,因为它是Odoo,包括在网站模块,一切都是默认的顺利整合。

因此,您完全可以自由地专注于设计,而这个结构提供集成和功能的工作。

Main features:

  • Basic layouts for pages, blog and eCommerce
  • Website Builder integration
  • Basic Snippets
  • Automatic Less/Sass compiling
  • Automatic Js and CSS minification and combination

Main technologies:

  • Twitter Bootstrap
  • jQuery
  • jQuery UI
  • underscore.js

Thinking "modular"

一个主题是不是Odoo文件夹包含HTML或PHP文件,这是一个模块化的框架写的XML。以前从未使用XML文件?别担心,在遵循了教程之后,你就可以用HTML的基本知识来创建你的第一个主题。使用经典的网页设计工作流程,你通常会编码整个页面的布局。其结果是一个“静态”网页。你可以更新内容,当然,但是你的客户需要你的工作甚至根本性的变化。

创建主题为Odoo是一个总的视角转换。而不是定义一个页面的完整布局,您可以创建块(片段),让用户选择在哪里“拖放”他们,创建自己的页面布局。我们称这种模块化设计。

想象一个Odoo主题为“元素和选项列表”,你必须创造和风格。 作为设计师,你的目标是设计这些元素,以实现一个美妙的结果,无论最终用户选择放置在哪里。

让我们参观一下我们的“列表”元素:

Snippets (或积木)

一段HTML代码。用户将拖放,修改和组合使用我们的内置网站建设者接口。可以为每个代码段定义选项和样式集。用户会根据自己的需要选择。

页面

这些都是正常的网页,除非它们将由最终用户编辑,并且您可以定义一个空区域,用户可以通过将片段拖动到其中来“填充”。

Styles

风格是使用标准的CSS文件定义(Less/Saas)。您可以定义样式为 默认 or 选择. 默认样式总是在您的主题中处于活动状态,用户可以启用或禁用可选样式。

功能

借助于Odoo的模块化,一切都可以个性化更。这意味着你有无限的创造力。添加功能很简单,它很简单,为最终用户提供可定制的选项。

Odoo's XML文件, 总览

任何Odoo XML文件从编码规范。之后,你必须写你的代码内 <data> tag, placed into an </odoo> tag.

[XML]
<?xml version="1.0" encoding="utf-8" ?>
<odoo><data>
    ## YOUR CODE HERE
  </data>
</odoo>

你创建的每一个元素和选项都必须放在<template> 标签, 如这个例子.

[XML]
<template id="my_title" name="My title">
  <h1>This is an HTML block</h1>
  <h2 class="lead">And this is a subtitle</h2>
</template>

以前的代码定义了标题,但不会显示template与任何部分的Odoo 默认结构不相关. 如果您想修改odoo内部的HTML,推荐使用xpath, qWeb.

继续阅读教程,学习如何正确地扩展它与你自己的代码。

更新你的主题

由于在安装主题时只加载XML文件,所以每次更改XML文件时都必须强制加载。要做到这一点,请单击模块页中的“升级”按钮。

创建主题模块

Odoo的主题是封装模块。即使你为你的公司或客户的一个非常简单的网站设计,你需要包装的主题像Odoo模块。

主文件夹
创建一个像这样命名的文件夹: theme_ 跟着你的主题的名字.
__manifest__.py
创建空文档并将其保存到文件夹中 __manifest__.py. 这将包含你的主题的配置信息.
__init__.py
创建另一个空文件并命名它 __init__.py. 这是一个强制性的系统文件. 创建并留空.
viewsstatic 文件夹
在主文件夹中创建它们. 在 views 你将放置你的XML定义你的片段,你的页面和你的选项。 static 文件夹是适合你风格的地方,图像和自定义JS代码。

最后的结果应该是这样的:

Edit __manifest__.py

Open the __manifest__.py 您创建并复制/粘贴如下:

{
  'name':'Tutorial theme',
  'description': 'A description for your theme.',
  'version':'1.0',
  'author':'Your name',

  'data': [
  ],
  'category': 'Theme/Creative',
  'depends': ['website'],
}

用你喜欢的任何东西替换前四个属性值。这些值将被用来识别您的后端Odoo新主题.

The data property will contain the xml files list. Right now it’s empty, but we will add any new files created.

application: True is mandatory.

category defines your module category (always “Theme”) and, after a slash, the subcategory. You can use one subcategory from the Odoo Apps categories list. (https://cdn.openerp.hk/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.

...
'depends': ['website', 'website_blog', 'sale'],
...

Installing your theme

安装你的主题,你只是把你的主题文件夹里面你Odoo安装插件。

之后,导航到设置页面,寻找你的主题,点击安装按钮。

一个Odoo页面结构

一个Odoo页面是一个组合的2种元素的视觉效果 , cross-pages and unique. 默认情况下,Odoo为你提供了一个Header and a Footer (跨页)和一个独特的主元素,它包含使页面独特的内容。

若要检查默认布局,只需使用网站建设者。点击 Content ‣ New Page 和添加页面名。使用浏览器检查页面。

<div id=“wrapwrap”>
  <header />
  <main />
  <footer />
</div>

扩展默认标题

默认情况下,Odoo头包含一个反应的导航菜单和公司的标志。您可以轻松添加新元素或样式现有的。

To do so, create a layout.xml file in your views folder and add the default Odoo xml markup.

<?xml version="1.0" encoding="utf-8" ?>
<odoo>
  <data>

  </data>
</odoo>

Create a new template into the <data> tag, copy-pasting the following code.

<!-- Customize header  -->
<template id="custom_header" inherit_id="website.layout" name="Custom Header">

  <!-- Assign an id  -->
  <xpath expr="//div[@id='wrapwrap']/header" position="attributes">
    <attribute name="id">my_header</attribute>
  </xpath>

  <!-- Add an element after the top menu  -->
  <xpath expr="//div[@id='wrapwrap']/header/div" position="after">
    <div class="container">
      <div class="alert alert-info mt16" role="alert">
        <strong>Welcome</strong> in our website!
      </div>
    </div>
  </xpath>
</template>

The first xpath will add the id my_header to the header. It’s the best option if you want to target css rules to that element and avoid these affecting other content on the page.

第二个XPath将在导航菜单之后添加欢迎消息.

最后一步是添加layout.xml所使用的XML文件的列表主题。要做到这一点,编辑你__manifest__.py file like this

'data': [ 'views/layout.xml' ],

Update your theme

伟大!我们成功地添加了一个ID导航菜单后的页眉和元素。这些变化将适用于网站的每一页。

创建特定页面布局

假设我们想为服务页创建特定的布局。对于这个页面,我们需要向顶部添加一个服务列表,并给客户端使用片段来设置页面剩余部分的可能性。

在你的 views folder, create a pages.xml file and add the default Odoo markup. Inside <data> create a <template> tag, set the page attribute to True and add your code into it.

<?xml version="1.0" encoding="utf-8" ?>
<odoo>
  <data>
    <!-- === Services Page === -->
    <template name="Services page" id="website.services" page="True">
      <h1>Our Services</h1>
        <ul class="services">
          <li>Cloud Hosting</li>
          <li>Support</li>
          <li>Unlimited space</li>
        </ul>
      </template>
    </data>
  </odoo>

页面标题将是模板ID在我们的情况下 Services (from website.services)

We successfully created a new page layout, but we haven't told the system how to use it. To do that, we can use QWeb. Wrap the html code into a <t> tag, like in this example.

<!-- === Services Page === -->
<template name="Services page" id="website.services" page="True">
  <t t-call="website.layout">
    <div id="wrap">
      <div class="container">
        <h1>Our Services</h1>
        <ul class="services">
          <li>Cloud Hosting</li>
          <li>Support</li>
          <li>Unlimited space</li>
        </ul>
      </div>
    </div>
  </t>
</template>

Using <t t-call="website.layout"> 我们将扩大Odoo默认页面布局与我们的代码。

正如你所看到的,我们把我们的代码封装成两个 <div>, one with ID wrap 和另一个与类container. 这是提供一个最小的布局.

下一步是添加一个空区域,用户可以填充片段。要做到这一点,只需创建一个 div with oe_structure class just before closing the div#wrap element.

<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<data>

<!-- === Services Page === -->
<template name="Services page" id="website.services" page="True">
  <t t-call="website.layout">
   <div id="wrap">
     <div class="container">
       <h1>Our Services</h1>
       <ul class="services">
         <li>Cloud Hosting</li>
         <li>Support</li>
         <li>Unlimited space</li>
       </ul>
       <!-- === Snippets' area === -->
       <div class="oe_structure" />
     </div>
   </div>
  </t>
</template>

</data>
</odoo>

我们的页面几乎准备好了。现在我们所要做的就是增加 pages.xml in our __manifest__.py file

'data': [
  'views/layout.xml',
  'views/pages.xml'
],

Update your theme

很好,我们的服务页面已经准备好了,您将能够访问它通过导航到 /yourwebsite/page/services.

你会注意到在下面拖放片段是可能的 我们的服务 list.

Now let's go back to our pages.xml and, after our page template, copy/paste the following code.

<record id="services_page_link" model="website.menu">
  <field name="name">Services</field>
  <field name="url">/page/services</field>
  <field name="parent_id" ref="website.main_menu" />
  <field name="sequence" type="int">99</field>
</record>

此代码将添加一个链接到主菜单 .

排序 属性在顶部菜单中定义链接的位置。在我们的例子中,我们将值设置为 99 为了把它放在最后。我想把它放在一个特定的位置,你必须根据你的需要更换价值。

你可以检查 data.xml file in the website module, the Home link is set to 10 and the 联系我们 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.

Add Styles

odoo包括引导城市的默认。这意味你可以把所有的优势functionalities样式和布局引导出的盒子。

当然,引导是不够的,如果你想提供一个独特的设计。下面的步骤将指导您如何将自定义样式添加到主题中。最终的结果不会很漂亮,但会为你提供足够的信息来建立自己的。 style.less 并将其放置在文件夹中 less 在静态文件夹中. 以下规则将风格我们 Services 页。复制粘贴,然后保存文件。

.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;
    }
}

我们的文件已经准备好了,但还没有包含在我们的主题。

让我们浏览到视图文件夹,并创建一个名为 assets.xml. A的XML文件。添加默认Odoo XML标记和复制/粘贴以下代码。记得要更换 theme folder 为您的主题的主文件夹名称.

<template id="mystyle" name="My style" inherit_id="website.assets_frontend">
    <xpath expr="link[last()]" position="after">
        <link href="/theme folder/static/less/style.less" rel="stylesheet" type="text/less"/>
    </xpath>
</template>

我们只是创建了一个模板指定我们的文件少。正如你所看到的,我们的模板有一个特殊的属性叫 inherit_id. 这属性告诉Odoo我们指的是另一个模板经营秩序。

In this case, we are referring to assets_frontend template, located in the website module. assets_frontend 指定由网站建设者加载的资产清单和我们的目标是添加我们的文件少到这个列表。

This can be achieved using xpath with the attributes expr="link[last()]" and position="after", which means "把我的样式文件并将其置于列表中的最后一个链接之后资产".

把它放在最后一个,我们确保我们的文件将被加载在最后,并采取优先.

Finally add assets.xml in your __manifest__.py file.

Update your theme

我们的Less文件现在包含在我们的主题,它将自动编译,压缩和合并Odoo的全部资产。

Create Snippets

由于用户设计和布局页面是如何设计的,它们是你设计中最重要的元素。让我们为我们的服务页面创建一个代码段。该片段将显示三个见证,它将是由最终用户使用网站建设者UI编辑。导航到视图文件夹并创建一个名为 snippets.xml. 添加默认Odoo XML标记和复制/粘贴以下代码。模板包含将由代码段显示的HTML标记。

<template id="snippet_testimonial" name="Testimonial snippet">
  <section class="snippet_testimonial">
    <div class="container text-center">
      <div class="row">
        <div class="col-md-4">
          <img alt="client" class="img-circle" src="/client_1.jpg"/>
          <h3>Client Name</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        </div>
        <div class="col-md-4">
          <img alt="client" class="img-circle" src="/client_2.jpg"/>
          <h3>Client Name</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        </div>
        <div class="col-md-4">
          <img alt="client" class="img-circle" src="/client_3.jpg"/>
          <h3>Client Name</h3>
          <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
        </div>
      </div>
    </div>
  </section>
</template>

如你所见,我们为三列使用了引导默认类。这不仅仅是关于布局,这些类 将由网站生成器触发由用户使他们调整大小.

以前的代码将创建代码段的内容,但我们仍然需要将其放入编辑器栏,这样用户就可以拖动&把它丢进页面。复制/粘贴此模板在您 snippets.xml file.

<template id="place_into_bar" inherit_id="website.snippets" name="Place into bar">
  <xpath expr="//div[@id='snippet_content']/div[@class='o_panel_body']" position="inside">
    <t t-snippet="theme_tutorial.snippet_testimonial"
       t-thumbnail="/snippet_thumb.jpg"/>
  </xpath>
</template>

用XPath,我们针对一个特定的元素与ID snippet_structure. 这意味着片段将出现在结构标签。如果要更改目标选项卡,则只需替换 id value in the xpath expression.

Tab NameXpath expression
Structure//div[@id='snippet_structure']
Content//div[@id='snippet_content']
Feature//div[@id='snippet_feature']
Effect//div[@id='snippet_effect']

The <t> 标签将我们的片段的模板调用并将分配一个缩略图放置在img文件夹。你现在可以从片段栏拖动你的片段,把它丢到你的页面,看看结果。

Snippet options

选项允许出版商编辑片段的外观使用网站建设者的用户界面。使用网站生成器功能,您可以轻松地创建片段选项,并自动将它们添加到用户界面 .

Options group properties

选项分组分组。组可以具有定义包含的选项将如何与用户界面交互的属性。

data-selector=" css selector(s) "
将包含到组中的所有选项绑定到特定元素 .
data-js=" custom method name "
用于绑定自定义JavaScript方法。
data-drop-in=" css selector(s) "
定义可以将代码段插入的元素列表 .
data-drop-near=" css selector(s) "
定义可以在其中删除代码段的元素列表。

Default option methods

选项将标准CSS类应用于代码段。根据您选择的方法,UI将表现不同.

data-select_class=" class name "
在同组data-select_class定义了一个类列表,用户可以选择应用。一次只能启用一个选项。
data-toggle_class=" class name "
data-toggle_class应用一个或多个CSS类从列表中的一段。 Multiple selections can be applied at once.

让我们演示默认选项如何使用一个基本示例。

我们开始添加一个新的文件在我们的视图文件夹-命名它 options.xml 添加默认Odoo XML标记。创建一个新的模板复制/粘贴如下

<template id="snippet_testimonial_opt" name="Snippet Testimonial Options" inherit_id="website.snippet_options">
  <xpath expr="//div[@data-js='background']" position="after">
    <div data-selector=".snippet_testimonial"> <!-- Options group -->
      <li class="dropdown-submenu">
        <a href="#">Your Option</a>
        <ul class="dropdown-menu"> <!-- Options list -->
          <li data-select_class="opt_shadow"><a>Shadow Images</a></li>
          <li data-select_class="opt_grey_bg"><a>Grey Bg</a></li>
          <li data-select_class=""><a>None</a></li>
        </ul>
      </li>
    </div>
  </xpath>
 </template>

正如你所看到的,我们将所有的选项封装在div标签中,将组我们的选项,将他们的目标选择权 (data-selector=".snippet_testimonial").

To define our options we applied data-select_class attributes to the li元素.当用户选择一个选项时,所包含的类属性将自动应用于元素。

Since select_class method avoids multiple selections, the last "empty" option will reset the snippet to default.

Add options.xml to __manifest__.py and update your theme.

将我们的代码页滴到页面上,您会发现我们的新选项将自动添加到自定义菜单中。检查页面时,您还将注意到在选择选项时,类将应用于该元素.

让我们创建一些CSS规则,以提供我们的选项的视觉反馈。打开我们的 style.less 文件并添加以下内容

.snippet_testimonial {
  border: 1px solid #EAEAEA;
  padding: 20px;
}

// These lines will add a default style for our snippet. Now let's create our custom rules for the options.

.snippet_testimonial {
  border: 1px solid #EAEAEA;
  padding: 20px;

  &.opt_shadow img {
    box-shadow: 0 2px 5px rgba(51, 51, 51, 0.4);
  }

  &.opt_grey_bg {
    border: none;
    background-color: #EAEAEA;
  }
}

好的!我们成功地为我们的片段创建了选项。

在选择出版商点击任何时间,系统将在data-select_class属性指定的类。

By replacing data-select_class with data-toggle_class 您将能够选择同时上课 .

Javascript Options

data-select_class and data-toggle_class 是伟大的,如果你需要执行简单类更改操作。但是,如果您的片段的定制需要更多的东西吗?

As we said before, data-js 为了定义自定义方法,可以将条件赋给选项组。让我们为我们创造一个 testimonials snippet by adding a data-js attribute to the option’s group div that we created earlier.

<div data-js="snippet_testimonial_options" data-selector=".snippet_testimonial">
  [...]
</div>

完成.从现在起,网站建设者将寻找一个 snippet_testimonial_options 方法每次发布时编辑模式。

让我们进一步创建一个JavaScript文件,名称 tutorial_editor.js 并把它放入 static 文件夹. Copy/paste the following code

(function() {
    'use strict';
    var website = odoo.website;
    website.odoo_website = {};
})();

好的,我们成功地创建了我们的JavaScript编辑器文件。此文件将包含我们的片段在编辑模式中使用的所有JavaScript函数。让我们创建一个新的功能,我们的见证片段使用 snippet_testimonial_options 我们之前创建的方法.

(function() {
    'use strict';
    var website = odoo.website;
    website.odoo_website = {};

    website.snippet.options.snippet_testimonial_options = website.snippet.Option.extend({
        on_focus: function() {
            alert("On focus!");
        }
    })
})();

正如你注意到的,我们使用了一种称为 on_focus 触发我们的功能。网站生成器提供了几个事件,您可以使用它来触发自定义函数.

Event描述
start当出版商选择在编辑会话的第一时间段或当片段拖掉页
on_focus每次用户选择代码段或将代码段拖放到页面中时都会引发火灾。
on_blurThis event occurs when a snippet loses focus.
on_clone片断复制后的火灾。创建一个新的JS变量($clone)包含克隆元素。
on_remove它发生之前,片段被删除。
drop_and_build_snippet在代码段拖动并拖放到拖放区域之后进行火灾。当触发此事件时,内容已插入页面中.
clean_for_save在发布服务器保存页面前触发.

让我们将新JavaScript文件添加到编辑器资产列表中。回到 assets.xml and create a new template like the previous one. This time we have to inherit assets_editor instead of assets_frontend.

<template id="my_js" inherit_id="website.assets_editor" name="My Js">
  <xpath expr="script[last()]" position="after">
    <script type="text/javascript" src="/theme_tutorial/static/src/js/tutorial_editor.js" />
  </xpath>
</template>

Update your theme

让我们测试我们新的JavaScript函数。输入编辑模式并输入页面。现在你应该看到我们绑定的JavaScript警报了 on_focus event. 如果您关闭它,然后单击您的片段外,然后点击它再次,事件将再次触发.

Editing Reference Guide

基本上一个页面中的所有元素都可以由出版商编辑。除此之外,一些元素类型和CSS类将触发特殊的网站建设者功能时编辑.

Layout

<section />
任何部分元素可以像块内容一样编辑。出版商可以移动或复制它。也可以设置背景图像或颜色。节是任何代码段的标准主容器。
.row > .col-md-*
任何媒介引导柱直接下降从。行元素,将由出版商可调整大小。
contenteditable="False"
This attribute will prevent editing to the element and all its children.
contenteditable="True"
将它应用到一个元素在一个contenteditable =“假”元素,以创建一个例外,使元素及其子编辑。
<a href=”#” />
在编辑模式下,任何链接都可以编辑和样式。使用“链接模式”也可以用按钮替换它。

Media

<span class=”fa” />
象形文字元素。编辑该元素将打开图标库替换图标。也可以使用CSS变换元素。
<img />
一旦点击,图像库将打开,您可以替换图像。转换也是可能的这种元素。
<div class="media_iframe_video" data-src="[your url]" >
  <div class="css_editable_mode_display"/>
  <div class="media_iframe_video_size"/>
  <iframe src="[your url]"/>
</div>

这个HTML结构将创建一个 <iframe> 元素可由发布者编辑.

SEO 最佳方法

Facilitate content insertion

现代搜索引擎算法越来越注重内容,这就意味着较少关注 keyword saturation 更注重内容是否是 其实相关的关键字.

由于内容对于SEO来说非常重要,你应该专注于给出版商轻松插入的工具。重要的是,您的片段是“内容响应”,这意味着他们应该适合出版商的内容,无论大小。

让我们来看看这个经典的两列片段的例子,用两种不同的方法实现。

错了

使用固定的图像,出版商将被迫限制文本,以按照布局。

好的

使用适合于列高度的背景图像,发布者可以自由添加内容,而不考虑图像的高度。

Page segmentation

基本上,页面分割意味着一个页面被分成多个独立的部分,这些部分被单独的条目当作搜索引擎来处理。 当您设计页面或片段时,您应该确保使用正确的标签,以便搜索引擎索引。

<article>
指定内容的独立块。它应该是一个独立的内容,应该有意义的自己。你可以嵌套 <article> 彼此的元素。在这种情况下,隐含的嵌套元素与外部 <article> element.
<header>
指示内容的自包含块的标头节(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>). 一个很好的例子就是一篇标题和副标题都在顶部的文章 :

<hgroup>
  <h1>Main Title</h1>
  <h2>Subheading</h2>
</hgroup>

描述您的页面

Define keywords

您应该使用适当的,相关的关键字和同义词的关键字。您可以定义每个页面使用内置的“促进”功能,发现在顶部的酒吧。

定义标题和描述

使用“促进”功能定义它们。保持您的页面标题短,包括主要关键字短语的页面。好的标题引起情绪反应,问问题或承诺某事。

描述,而不是重要的搜索引擎排名,在获得用户点击非常重要。这是一个广告内容的机会,让人们搜索准确地知道给定的页面是否包含他们正在寻找的信息。重要的是每个页面的标题和描述都是独一无二的。