[ADD] extensions: add a custom example admonition

closes odoo/documentation#1501

X-original-commit: acda12669d
Signed-off-by: Antoine Vandevenne (anv) <anv@odoo.com>
This commit is contained in:
wan 2021-11-25 11:08:47 +00:00 committed by Antoine Vandevenne (anv)
parent fd25322fda
commit 2bf697bda4
9 changed files with 54 additions and 23 deletions

View File

@ -112,7 +112,7 @@ extensions = [
# Youtube and Vimeo videos integration (youtube, vimeo directives)
'embedded_video',
'exercise_admonition',
'custom_admonitions',
# Redirection generator
'redirects',

View File

@ -36,19 +36,19 @@ concepts to the proper understanding of the following reports:
- **Revenue Churn**: It corresponds to the monthly recurring revenue loss rate.
.. admonition::
Let's imagine a 2$ increase in a subscription service.
.. example::
Let's imagine a 2$ increase in a subscription service.
- We lost 3 customers out of the initial 20, which generates a **Logo Churn** of 15%.
- | Therefore, the 56$ of MRR difference out of the initial 600$ causes a **Revenue Churn**
| of 9,33%.
- We lost 3 customers out of the initial 20, which generates a **Logo Churn** of 15%.
- | Therefore, the 56$ of MRR difference out of the initial 600$ causes a **Revenue Churn**
| of 9,33%.
.. image:: media/difference-between-logo-churn-and-revenue-churn.png
:align: center
:alt: Difference between logo churn and revenue churn in Odoo Subscriptions
.. image:: media/difference-between-logo-churn-and-revenue-churn.png
:align: center
:alt: Difference between logo churn and revenue churn in Odoo Subscriptions
Reminder: even though they seem to evolve in the same direction most of the time, it might not
be the case all the time.
Reminder: even though they seem to evolve in the same direction most of the time, it might
not be the case all the time.
- **Customer Lifetime Value (CLV)**: Indicates how much revenue can be expected for a customer
during his/her entire contract. This approach emphasizes the importance of customer retention,

View File

@ -26,7 +26,7 @@ Integrating messaging features to your model is extremely easy. Simply inheritin
the ``mail.thread`` model and adding the messaging fields (and their appropriate
widgets) to your form view will get you up and running in no time.
.. admonition:: Example
.. example::
Let's create a simplistic model representing a business trip. Since organizing
this kind of trip usually involves a lot of people and a lot of discussion, let's
@ -200,7 +200,7 @@ The ``mail`` module adds a powerful tracking system on fields, allowing you
to log changes to specific fields in the record's chatter. To add tracking
to a field, simple set the tracking attribute to True.
.. admonition:: Example
.. example::
Let's track changes on the name and responsible of our business trips:
@ -272,7 +272,7 @@ can override the ``_track_subtype()`` function:
:returns: a subtype's full external id or False if no subtype is triggered
.. admonition:: Example
.. example::
Let's add a ``state`` field on our example class and trigger a notification
with a specific subtype when this field change values.
@ -422,7 +422,7 @@ The urls in the actions list can be generated automatically by calling the
:returns: link of the type selected for the record
:rtype: str
.. admonition:: Example
.. example::
Let's add a custom button to the Business Trip state change notification;
this button will reset the state to Draft and will be only visible to a member
@ -609,7 +609,7 @@ which means that while the alias is stored in another table, you have
access to all these fields directly from your parent object. This allows
you to make your alias easily configurable from the record's form view.
.. admonition:: Example
.. example::
Let's add aliases on our business trip class to create expenses on the fly via
e-mail.
@ -738,7 +738,7 @@ and the specific widgets to display them (via the field ``activity_ids``) in the
view and kanban view of your records (``mail_activity`` and ``kanban_activity``
widgets, respectively).
.. admonition:: Example
.. example::
Organizing a business trip is a tedious process and tracking needed activities
like ordering plane tickets or a cab for the airport could be useful. To do so,

View File

@ -174,7 +174,7 @@ into a compatible type:
* :func:`~odoo.fields.Date.to_date` will convert to a :class:`datetime.date`
* :func:`~odoo.fields.Datetime.to_datetime` will convert to a :class:`datetime.datetime`.
.. admonition:: Example
.. example::
To parse date/datetimes coming from external sources::
@ -855,7 +855,7 @@ Domain criteria can be combined using logical operators in *prefix* form:
Individual criterion generally have a negative form (e.g. ``=`` ->
``!=``, ``<`` -> ``>=``) which is simpler than negating the positive.
.. admonition:: Example
.. example::
To search for partners named *ABC*, from belgium or germany, whose language
is not english::

View File

@ -1003,7 +1003,7 @@ take the following attributes:
* ``plan``: If enabled and ``edit`` enabled, a "magnifying glass" button will be displayed
on time slots to plan unassigned records into that time slot.
.. admonition:: Example
.. example::
When you do not want to create records on the gantt view and the beginning and end
dates are required on the model, the planning feature should be disabled

View File

@ -1,10 +1,18 @@
""" Add a new "exercise" admonition directive. """
""" Add new custom admonition directives. """
from docutils import nodes
from docutils.parsers.rst.directives import admonitions
from sphinx.locale import admonitionlabels
class example(nodes.Admonition, nodes.Element):
pass
class Example(admonitions.BaseAdmonition):
node_class = example
class exercise(nodes.Admonition, nodes.Element):
pass
@ -14,6 +22,11 @@ class Exercise(admonitions.BaseAdmonition):
def setup(app):
app.add_directive('example', Example)
app.add_node(example, html=(
lambda self, node: self.visit_admonition(node, 'example'),
lambda self, node: self.depart_admonition(node),
))
app.add_directive('exercise', Exercise)
app.add_node(exercise, html=(
lambda self, node: self.visit_admonition(node, 'exercise'),
@ -26,4 +39,5 @@ def setup(app):
}
admonitionlabels['example'] = 'Example'
admonitionlabels['exercise'] = 'Exercise'

View File

@ -217,6 +217,7 @@ $brand-danger : #D9534F;
$doc_paper_dark: $gray-lighter;
$doc_paper: #ffffff;
$doc_example: #519161;
$doc_exercise: #938E94;
$doc_code-bg: #F8F8F8;
$doc_lime: #CDDC39;
@ -255,4 +256,4 @@ $padding-m: 2rem;
$padding-l: 3rem;
$margin-s: $padding-s;
$margin-m: $padding-m;
$margin-l: $padding-l;
$margin-l: $padding-l;

View File

@ -938,13 +938,28 @@ header.o_main_header {
border-color: $danger;
> .alert-title, > h3 {
color: darken($brand-danger,20%);
color: darken($brand-danger, 20%);
&:before {
content: '#{$i-danger}';
}
}
}
&.alert-example {
border-color: tint-color($doc_example, 30%);
background-color: tint-color($doc_example, 90%);
color: shade-color($doc_example, 35%);
> .alert-title, > h3 {
color: shade-color($doc_example, 35%);
}
> .alert-title:before, > h3:before {
content: '#{$i-knowledge}';
}
}
&.alert-exercise {
border-color: tint-color($doc_exercise, 30%);
background-color: tint-color($doc_exercise, 90%);

View File

@ -34,6 +34,7 @@ ADMONITION_MAPPING = {
'danger': 'alert-danger',
'error': 'alert-danger',
'example': 'alert-example',
'exercise': 'alert-exercise',
}