چیدمان

در این فصل خواهید آموخت چگونه:

  • یک header سفارشی ایجاد کنید.

  • یک footer سفارشی ایجاد کنید.

  • یک قالب استاندارد را تغییر دهید.

  • یک بخش copyright اضافه کنید.

  • responsiveness وب‌سایت خود را بهبود دهید.

پیش‌فرض

یک صفحهٔ Odoo، عناصر cross-page و یکتا را ترکیب می‌کند. عناصر cross-page در هر صفحه یکسان هستند، در حالی که عناصر یکتا تنها به یک صفحهٔ خاص مرتبط‌اند. به‌صورت پیش‌فرض، یک صفحه دو عنصر cross-page دارد، header و footer، و یک عنصر اصلی یکتا که حاوی محتوای خاص آن صفحه است.

<div id="wrapwrap">
   <header/>
      <main>
         <div id="wrap" class="oe_structure">
            <!-- Page Content -->
         </div>
      </main>
   <footer/>
</div>

هر فایل XML در Odoo با مشخصات encoding شروع می‌شود. پس از آن، باید کد خود را داخل یک تگ <odoo> بنویسید.

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

توجه

استفاده از نام‌های دقیق برای قالب‌ها، برای یافتن سریع اطلاعات در همهٔ ماژول‌ها مهم است. نام‌های قالب باید فقط شامل alphanumeric با حروف کوچک و underscore باشد.

همیشه یک خط خالی در پایان فایل خود اضافه کنید. این کار را می‌توان با پیکربندی IDE خود به‌طور خودکار انجام داد.

XPath

XPath (XML Path Language) یک زبان عبارت است که به شما اجازه می‌دهد به‌سادگی در میان عناصر و ویژگی‌ها در یک سند XML پیمایش کنید. XPath برای گسترش قالب‌های استاندارد Odoo استفاده می‌شود.

یک نما به این شیوه کدنویسی می‌شود.

<template id="..." inherit_id="..." name="...">
   <!-- Content -->
</template>

صفت

توضیحات

id

ID نمای تغییریافته

inherited_id

ID نمای استاندارد (با استفاده از الگوی زیر: module.template)

name

نام خوانا برای انسان از نمای تغییریافته

برای هر XPath، دو ویژگی را تغییر می‌دهید: expression و position.

Example

/website_airproof/views/website_templates.xml
<template id="layout" inherit_id="website.layout" name="Welcome Message">
   <xpath expr="//header" position="before">
      <!-- Content -->
   </xpath>
</template>

این XPath یک پیام خوش‌آمدگویی را درست قبل از محتوای صفحه اضافه می‌کند.

هشدار

هنگام جایگزینی ویژگی‌های عناصر پیش‌فرض مراقب باشید. از آنجا که قالب شما، قالب پیش‌فرض را گسترش می‌دهد، تغییرات شما بر هر به‌روزرسانی آیندهٔ Odoo اولویت خواهد داشت.

توجه

  • هر بار که یک قالب یا رکورد جدید ایجاد می‌کنید، باید ماژول خود را به‌روزرسانی کنید.

  • XML IDهای نماهای ارث‌برنده باید همان ID رکورد اصلی را استفاده کنند. این کمک می‌کند همهٔ ارث‌بری‌ها را در یک نگاه پیدا کنید. از آنجا که XML IDهای نهایی با نام ماژولی که آن‌ها را ایجاد می‌کند پیشوند می‌گیرند، هیچ تداخلی وجود ندارد.

عبارات

XPath از عبارات path برای انتخاب گره‌ها در یک سند XML استفاده می‌کند. selectorها داخل عبارت برای هدف‌گیری عنصر مناسب استفاده می‌شوند. مفیدترین آن‌ها در زیر فهرست شده‌اند.

selectorهای فرزند

توضیحات

/

از گرهٔ ریشه انتخاب می‌کند.

//

گره‌هایی را در سند از گرهٔ کنونی انتخاب می‌کند که با انتخاب مطابقت دارند، صرف‌نظر از اینکه کجا هستند.

selectorهای ویژگی

توضیحات

*

هر تگ XML را انتخاب می‌کند. اگر انتخاب نیاز به دقت بیشتر داشته باشد، می‌توان * را با یک تگ خاص جایگزین کرد.

*[@id="id"]

یک ID خاص را انتخاب می‌کند.

*[hasclass("class")]

یک کلاس خاص را انتخاب می‌کند.

*[@name="name"]

یک تگ با نام خاص را انتخاب می‌کند.

*[@t-call="t-call"]

یک t-call خاص را انتخاب می‌کند.

موقعیت

position تعریف می‌کند که کد در کجای قالب قرار می‌گیرد. مقادیر ممکن در زیر فهرست شده‌اند:

موقعیت

توضیحات

replace

گرهٔ هدف را با محتوای XPath جایگزین می‌کند.

inside

محتوای XPath را داخل گرهٔ هدف اضافه می‌کند.

before

محتوای XPath را قبل از گرهٔ هدف اضافه می‌کند.

after

محتوای XPath را بعد از گرهٔ هدف اضافه می‌کند.

attributes

محتوای XPath را داخل یک ویژگی اضافه می‌کند.

Example

این XPath اولین عنصر با کلاس .breadcrumb را حذف می‌کند.

<xpath expr="//*[hasclass('breadcrumb')]" position="replace"/>

این XPath یک عنصر <li> اضافی بعد از آخرین فرزند عنصر <ul> اضافه می‌کند.

<xpath expr="//ul" position="inside">
   <li>Last element of the list</li>
</xpath>

این XPath یک <div> را قبل از <nav> که فرزند مستقیم <header> است، اضافه می‌کند.

<xpath expr="//header/nav" position="before">
   <div>Some content before the header</div>
</xpath>

این XPath، x_airproof_header را در ویژگی class هدر حذف می‌کند. در این مورد، نیازی به استفاده از ویژگی separator نیست.

<xpath expr="//header" position="attributes">
   <attribute name="class" remove="x_airproof_header" />
</xpath>

این XPath، x_airproof_header را در ویژگی class هدر اضافه می‌کند. همچنین باید یک ویژگی separator تعریف کنید تا یک فاصله قبل از کلاسی که اضافه می‌کنید اضافه شود.

<xpath expr="//header" position="attributes">
   <attribute name="class" add="x_airproof_header" separator=" " />
</xpath>
این XPath عنصر با کلاس .o_footer_scrolltop_wrapper را قبل از عنصر با

ویژگی ID footer جابه‌جا می‌کند.

<xpath expr="//div[@id='footer']" position="before">
   <xpath expr="//div[@id='o_footer_scrolltop_wrapper']" position="move" />
</xpath>

نکته

استفاده از دستورات move داخل XPath دیگر، شما را مجبور می‌کند فقط از این نوع دستورات استفاده کنید.

Example

مثال خوب:
<xpath expr="//*[hasclass('o_wsale_products_main_row')]" position="before">
   <xpath expr="//t[@t-if='opt_wsale_categories_top']" position="move" />
</xpath>
<xpath expr="//*[hasclass('o_wsale_products_main_row')]" position="before">
   <div><!-- Content --></div>
</xpath>
مثال بد:
<xpath expr="//*[hasclass('o_wsale_products_main_row')]" position="before">
   <xpath expr="//t[@t-if='opt_wsale_categories_top']" position="move" />
   <div><!-- Content --></div>
</xpath>

همچنین ببینید

می‌توانید اطلاعات بیشتری دربارهٔ XPath در این cheat sheet بیابید.

QWeb

QWeb موتور قالب‌سازی اصلی است که توسط Odoo استفاده می‌شود. این یک موتور قالب‌سازی XML است که عمدتاً برای تولید قطعات و صفحات HTML استفاده می‌شود.

دستورات t-call می‌توانند پارامترها را دریافت کنند:

<!-- Old way -->
<t t-call="portal.user_dropdown">
   <t t-set="_icon" t-value="True" />
   <t t-set="_item_class" t-valuef="dropdown" />
</t>

<t t-call="website.layout">
   <t t-set="additional_title">My page title</t>
</t>

<!-- New way (Parametric) -->
<t t-call="portal.user_dropdown"
   _icon="true"
   _item_class.f="dropdown" />

<t t-call="website.layout"
   additional_title.translate="My page title" />

ویژگی (نمونه‌ها)

توضیحات

_icon="true"

مقدار خام را منتقل کنید (در اینجا یک بولی که روی true تنظیم شده است)

_item_class.f="dropdown"

مقدار را به‌عنوان یک رشته منتقل کنید

additional_title.translate="My page title"

مقدار را به‌عنوان یک رشته منتقل کنید

همچنین ببینید

اسناد قالب‌های QWeb.

فیلدهای سفارشی

بسته به نیازهای خود، می‌توانید فیلدهای سفارشی برای ذخیرهٔ داده در پایگاه‌داده ایجاد کنید.

اعلان

ابتدا یک رکورد برای اعلان فیلد ایجاد کنید. این فیلد باید به یک مدل موجود پیوند داده شود.

/website_airproof/data/fields.xml
<record id="x_post_category" model="ir.model.fields">
   <field name="name">x_post_category</field>
   <field name="field_description">...</field>
   <field name="ttype">html</field>
   <field name="state">manual</field>
   <field name="index">0</field>
   <field name="model_id" ref="website_blog.model_blog_post" />
</record>

توجه

ایجاد فیلدها همچنین از طریق یک مدل با استفاده از Python ممکن (و توصیه‌شده) است.

Back-end

فیلد را از طریق یک XPath به نمای مرتبط اضافه کنید. بنابراین، کاربر می‌تواند فیلد را در رابط ببیند و سپس آن را پر کند.

/website_airproof/views/backend/website_blog_views.xml
<record id="view_blog_post_form_category" model="ir.ui.view">
   <field name="name">view_blog_post_form_category</field>
   <field name="model">blog.post</field>
   <field name="inherit_id" ref="website_blog.view_blog_post_form" />
   <field name="arch" type="xml">
      <xpath expr="//field[@name='blog_id']" position="before">
         <field name="x_post_category" string="..." placeholder="..." />
      </xpath>
   </field>
</record>

Front-end

مقدار فیلد را می‌توان با فراخوانی model_name.field_name به‌این شکل، در جایی از صفحه نمایش داد:

/website_airproof/views/website_blog_templates.xml
<h1 t-field="blog_post.x_post_category" />

پس‌زمینه

می‌توانید یک رنگ یا یک تصویر را به‌عنوان پس‌زمینهٔ وب‌سایت خود تعریف کنید.

رنگ‌ها

/website_airproof/static/src/scss/primary_variables.scss
$o-color-palettes: map-merge($o-color-palettes,
   (
      'airproof': (
         'o-cc1-bg':                     'o-color-5',
         'o-cc5-bg':                     'o-color-1',
      ),
    )
);

تصویر/الگو

/website_airproof/static/src/scss/primary_variables.scss
$o-website-values-palettes: (
   (
      'body-image': '/website_airproof/static/src/img/background-lines.svg',
      'body-image-type': 'image' or 'pattern'
   )
);

استاندارد

ابزار ساخت وب‌سایت Odoo بین قالب‌های desktop و قالب mobile تمایز قائل می‌شود تا تطبیق تجربهٔ کاربری با دستگاه را تسهیل کند.

قالب desktop

یکی از قالب‌های پیش‌فرض header را فعال کنید.

مهم

فراموش نکنید که ممکن است نیاز باشد ابتدا قالب فعال header را غیرفعال کنید.

Example

/website_aiproof/data/presets.xml
<record id="website.template_header_default" model="ir.ui.view">
   <field name="active" eval="False" />
</record>

قالب موردنظر را به‌صراحت در فایل primary_variables.scss تنظیم کنید.

/website_airproof/static/src/scss/primary_variables.scss
$o-website-values-palettes: (
   (
      'header-template': 'stretch',
   ),
);
/website_airproof/data/presets.xml
<record id="website.template_header_stretch" model="ir.ui.view">
   <field name="active" eval="True" />
</record>

قالب mobile

هر قالب header همراه با قالب template_header_mobile می‌آید تا تجربهٔ کاربری بی‌نقص در همهٔ دستگاه‌ها تضمین شود.

سفارشی

قالب خود را ایجاد کنید و آن را به فهرست اضافه کنید.

مهم

فراموش نکنید که ممکن است نیاز باشد ابتدا قالب فعال header را قبل از فعال‌سازی قالب سفارشی غیرفعال کنید.

گزینه

از کد زیر برای افزودن یک گزینه برای header سفارشی جدید خود در ابزار ساخت وب‌سایت استفاده کنید.

/website_airproof/static/src/website_builder/header_template_option.xml
<t t-name="website_airproof.HeaderTemplateOption" t-inherit="website.HeaderTemplateOption" t-inherit-mode="extension">
   <xpath expr="//BuilderRow[@label.translate='Template']//BuilderSelect" position="inside">
      <BuilderSelectItem
         id="'header_airproof_opt'"
         title.translate="Airproof"
         actionParam="[
            {
               action: 'websiteConfig',
               actionParam: {
                  views: ['website_airproof.header'],
                  vars: { 'header-template': 'airproof' },
                  checkVars: false,
               },
            },
         ]">
         <Img src="'/website_airproof/static/src/img/wbuilder/template-header-opt.svg'" attrs="{ style: 'width: calc(100% - 0.5rem);' }" />
      </BuilderSelectItem>
   </xpath>
 </t>

صفت

توضیحات

views

قالب(های) قابل فعال‌سازی

vars

نام داده‌شده به متغیر (همان که در primary_variables.scss استفاده شده)

checkVars

تعیین می‌کند که آیا vars برای تنظیم وضعیت گزینه مقایسه می‌شوند.

src (در Img)

thumbnail قالب سفارشی که در انتخاب قالب‌ها در ابزار ساخت وب‌سایت نمایش داده می‌شود

اکنون باید به‌صراحت تعریف کنید که می‌خواهید از قالب سفارشی خود در متغیرهای SASS Odoo استفاده کنید.

/website_airproof/static/src/scss/primary_variables.scss
$o-website-values-palettes: (
   (
      'header-template': 'airproof',
   ),
);

قالب

/website_airproof/views/website_templates.xml
<template id="header" inherit_id="website.layout" name="Airproof - Header" active="True">
   <xpath expr="//header//nav" position="replace">
      <!-- Static Content -->
      <!-- Components -->
      <!-- Editable areas -->
   </xpath>
</template>

فراموش نکنید template_header_mobile را بر این اساس تطبیق دهید تا سازگاری بین desktop و mobile حفظ شود:

website_airproof/views/website_templates.xml
<template id="template_header_mobile" inherit_id="website.template_header_mobile" name="Airproof - Template Header Mobile">
   <!-- Xpaths -->
</template>

کامپوننت‌ها

در header سفارشی خود، می‌توانید چندین زیرقالب را با استفاده از دستور t-call از QWeb فراخوانی کنید:

Sign in

<t t-call="portal.placeholder_user_sign_in"
   _item_class.f="nav-item"
   _link_class.f="nav-link" />

dropdown کاربر

<t t-call="portal.user_dropdown"
   _user_name="true"
   _icon="false"
   _avatar="false"
   _item_class.f="nav-item dropdown"
   _link_class.f="nav-link"
   _dropdown_menu_class.f="..." />

انتخاب‌گر زبان

<t t-call="website.placeholder_header_language_selector"
   _div_classes.f="..." />

Call to action

<t t-call="website.placeholder_header_call_to_action"
   _div_classes.f="..." />

Drop zone

به‌جای تعریف چیدمان کامل یک صفحه، می‌توانید بلوک‌های سازنده (snippets) ایجاد کنید و به کاربر اجازه دهید انتخاب کند آن‌ها را کجا drag and drop کند، و چیدمان صفحه را خودشان ایجاد کنند. ما این را طراحی ماژولار می‌نامیم.

می‌توانید یک ناحیهٔ خالی تعریف کنید که کاربر بتواند آن را با snippets پر کند.

<div id="oe_structure_layout_01" class="oe_structure" />

کلاس

توضیحات

oe_structure

یک ناحیهٔ drag-and-drop برای کاربر تعریف کنید.

oe_structure_solo

تنها یک snippet می‌تواند در این ناحیه drop شود.

oe_structure_not_nearest

اگر یک بلوک سازنده خارج از Drop zoneی که این کلاس را دارد drop شود، بلوک به نزدیک‌ترین Drop Zone منتقل خواهد شد.

همچنین می‌توانید یک drop zone موجود را با محتوای خود پُر کنید.

<template id="oe_structure_layout_01" inherit_id="..." name="...">
   <xpath expr="//*[@id='oe_structure_layout_01']" position="replace">
      <div id="oe_structure_layout_01" class="oe_structure oe_structure_solo">
         <!-- Content -->
      </div>
   </xpath>
</template>

Responsive

Odoo به‌طور کلی به فریم‌ورک Bootstrap متکی است که responsiveness وب‌سایت شما را در desktop و mobile تسهیل می‌کند. عمدتاً می‌توانید روی ۳ جنبه اقدام کنید:

  1. اندازه‌های فونت محاسبه‌شدهٔ خودکار بسته به دستگاه

  2. اندازهٔ ستون‌ها در desktop (ستون‌ها به‌طور خودکار در mobile روی هم چیده می‌شوند)

  3. شرایط visibility (نمایش/پنهان کردن چیزی در desktop/mobile)

اندازه‌های فونت

در Bootstrap 5، اندازه‌های فونت responsive به‌صورت پیش‌فرض فعال هستند و به متن اجازه می‌دهند به‌طور طبیعی‌تری در اندازه‌های دستگاه و viewport مقیاس شود (با تکیه بر متغیر $enable-rfs).

اندازه‌های ستون

Bootstrap از یک grid متشکل از ردیف‌ها و ستون‌ها برای چیدمان یک صفحه استفاده می‌کند. به لطف این ساختار، ستون‌ها می‌توانند در mobile و desktop به‌طور متفاوتی اندازه‌گذاری شوند. در این نسخه، ابزار ساخت وب‌سایت اجازه می‌دهد اندازه‌های mobile (مثلاً col-12) و desktop (مثلاً col-lg-4) را تنظیم کنید، اما نه breakpointهای medium (مثلاً col-md-4).

هشدار

اندازه‌های medium را می‌توان تنظیم کرد اما کاربر نهایی نمی‌تواند آن‌ها را در ابزار ساخت وب‌سایت ویرایش کند.

شرایط visibility

در ابزار ساخت وب‌سایت Odoo، می‌توان sectionهای کامل یا ستون‌های خاصی را در mobile یا desktop پنهان کرد.

این قابلیت از Bootstrap به همراه کلاس‌های خاص Odoo بهره می‌برد:

  • o_snippet_mobile_invisible

  • o_snippet_desktop_invisible

پنهان کردن یک section در desktop:

<section
   class="s_text_block o_cc o_cc1 o_colored_level pt16 pb16 d-lg-none o_snippet_desktop_invisible"
   data-snippet="s_text_block"
   data-name="Text">
   <!-- Content -->
</section>

پنهان کردن یک ستون در mobile:

<section
   class="s_text_block o_cc o_cc1 o_colored_level pt16 pb16"
   data-snippet="s_text_block"
   data-name="Text">
   <div class="container s_allow_columns">
      <div class="row">
         <div class="col-12 col-lg-6 d-none d-lg-block o_snippet_mobile_invisible">
            Column 1
         </div>
         <div class="col-12 col-lg-6">
            Column 2
         </div>
      </div>
   </div>
</section>

کلاس

توضیحات

o_snippet_mobile_invisible

به ابزار ساخت وب‌سایت می‌گوید که عنصر پنهان است و از گزینهٔ شرایط visibility استفاده می‌کند.

o_snippet_desktop_invisible

به ابزار ساخت وب‌سایت می‌گوید که عنصر در desktop و پنهان است و از گزینهٔ شرایط visibility استفاده می‌کند.

d-none

عنصر را در همهٔ موقعیت‌ها پنهان کن.

d-lg-block

عنصر را از breakpointی «large» (در desktop) نمایش بده.

مهم

کلاس‌های o_snippet_mobile_invisible / o_snippet_desktop_invisible باید مشخص شوند تا

گزینهٔ شرایط visibility کارا بماند. حتی اگر یک عنصر در desktop پنهان باشد، ابزار ساخت وب‌سایت فهرستی از این عناصر را نمایش می‌دهد و به کاربر نهایی اجازه می‌دهد بدون جابه‌جایی بین حالت mobile و desktop، عنصر را به‌اجبار نمایش دهد و ویرایش کند.

اجبار به نمایش یک عنصر پنهان روی دستگاه کنونی.