Skip to content

Commit

Permalink
Fixes/improves introductory tutorial (#6390)
Browse files Browse the repository at this point in the history
* introduces numbering of sections
* fixes #6359
  • Loading branch information
evildmp committed May 31, 2018
1 parent 591efd6 commit 32d9b73
Show file tree
Hide file tree
Showing 12 changed files with 222 additions and 350 deletions.
23 changes: 12 additions & 11 deletions docs/introduction/install.rst → docs/introduction/01-install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ We'll get started by setting up our environment.
Requirements
************

django CMS requires Django 1.8, 1.9 or 1.10 and Python 2.7, 3.3 or 3.4.
django CMS requires Django 1.8 or newer, and Python 2.7 or 3.3 or newer. This tutorial assumes
you are using Python 3.

************************
Your working environment
Expand All @@ -20,21 +21,21 @@ We're going to assume that you have a reasonably recent version of virtualenv
installed and that you have some basic familiarity with it.


Create and activate a virtual env
=================================
Create and activate a virtual environment
=========================================

::

virtualenv env
python3.6 -m venv env # Python 2 usage: virtualenv env
source env/bin/activate

Note that if you're using Windows, to activate the virtualenv you'll need::

env\Scripts\activate


Update pip
==========
Update pip inside the virtual environment
=========================================

``pip`` is the Python installer. Make sure yours is up-to-date, as earlier versions can be less reliable::

Expand Down Expand Up @@ -107,8 +108,8 @@ Start up the runserver

python manage.py runserver

Open http://localhost:8000/ in your browser, where you should be presented with
your brand new django CMS homepage.
Open http://localhost:8000/ in your browser, where you should be invited to login, and then create
a new page.

.. image:: /introduction/images/welcome.png
:alt: a django CMS home page
Expand All @@ -117,8 +118,8 @@ your brand new django CMS homepage.

Congratulations, you now have installed a fully functional CMS.

To log in, append ``?edit`` to the URL and hit enter. This will enable the
If you need to log in at any time, append ``?edit`` to the URL and hit Return. This will enable the
toolbar, from where you can log in and manage your website.

If you are not already familiar with django CMS, take a few minutes to run through the basics of
the :ref:`django CMS tutorial for users <user-tutorial>`.
If you are not already familiar with django CMS, you can take a few minutes to run through the
basics of the :ref:`django CMS tutorial for users <user-tutorial>`.
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ can be switched for another at any time.

You'll find the site's templates in ``mysite/templates``.

If you didn't change the automatically-created home page's template, it's ``fullwidth.html``, the first one listed in
By default, pages in your site will use the ``fullwidth.html`` template, the first one listed in
the project's ``settings.py`` ``CMS_TEMPLATES`` tuple:

.. code-block:: python
Expand Down Expand Up @@ -51,8 +51,8 @@ required template tag library.
If you're not already familiar with Django template tags, you can find out more in the `Django documentation
<https://docs.djangoproject.com/en/dev/topics/templates/>`_.

Add a couple of new placeholders, ``{% placeholder "feature" %}`` and ``{% placeholder "splashbox" %}`` to the
template's HTML structure. You can add them anywhere, for example:
Add a couple of new placeholders to ``fullwidth.html``, ``{% placeholder "feature" %}`` and ``{%
placeholder "splashbox" %}`` inside the ``{% block content %}`` section. For example:

.. code-block:: html+django
:emphasize-lines: 2,4
Expand Down Expand Up @@ -88,14 +88,19 @@ you added content to it, it will be saved globally. Even when you remove the
static placeholders from a template, you can reuse them later.

So let's add a footer to all our pages. Since we want our footer on every
single page, we should add it to our base template
(``mysite/templates/base.html``). Place it at the bottom of the HTML ``<body>``:
single page, we should add it to our **base template**
(``mysite/templates/base.html``). Place it near the end of the HTML ``<body>`` element:

.. code-block:: html+django
:emphasize-lines: 1-3

<footer>
{% static_placeholder 'footer' %}
</footer>
<footer>
{% static_placeholder 'footer' %}
</footer>


{% render_block "js" %}
</body>

Save the template and return to your browser. Refresh any page in Structure mode, and you'll
see the new static placeholder.
Expand All @@ -120,23 +125,21 @@ Rendering Menus
In order to render the CMS's menu in your template you can use the :doc:`show_menu
</reference/navigation>` tag.

The example we use in ``mysite/templates/base.html`` is:
Any template that uses ``show_menu`` must load the CMS's ``menu_tags`` library
first:

.. code-block:: html+django

<ul class="nav navbar-nav">
{% show_menu 0 1 100 100 "menu.html" %}
</ul>
{% load menu_tags %}

Any template that uses ``show_menu`` must load the CMS's ``menu_tags`` library
first:
The menu we use in ``mysite/templates/base.html`` is:

.. code-block:: html+django

{% load menu_tags %}
<ul class="nav navbar-nav">
{% show_menu 0 100 100 100 "menu.html" %}
</ul>

If you chose "bootstrap" while setting up with djangocms-installer, the menu
will already be there and ``templates/menu.html`` will already contain a
version that uses bootstrap compatible markup.
The options control the levels of the site hierarchy that are displayed in the menu tree - but you don't need to worry about exactly what they do at this stage.

Next we'll look at :ref:`integrating_applications`.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@
Integrating applications
########################

All the following sections of this tutorial are concerned with integrating other applications into django CMS, which is
where a vast part of its power comes from.
All the following sections of this tutorial are concerned with different ways of integrating other
applications into django CMS. The ease with which other applications can be built into django CMS
sites is an important feature of the system.

Integrating applications doesn't just mean installing them alongside django CMS, so that they peacefully co-exist. It
Integrating applications doesn't merely mean installing them alongside django CMS, so that they peacefully co-exist. It
means using django CMS's features to build them into a single coherent web project that speeds up the work of managing
the site, and makes possible richer and more automated publishing.

Expand All @@ -18,13 +19,22 @@ directly into the applications themselves, for example when using :ref:`placehol
<placeholders_outside_cms>`.)

For this tutorial, we're going to take a basic Django `opinion poll application
<https://github.com/divio/django-polls>`_ and integrate it into the CMS. So we'll install that, and create a second,
independent, *Polls/CMS Integration* application to manage the integration, leaving the first untouched.
<https://github.com/divio/django-polls>`_ and integrate it into the CMS.

So we will:

*********************************
Install the ``polls`` application
*********************************
* incorporate the Polls application into the project
* create a second, independent, *Polls/CMS Integration* application to manage the integration

This way we can integrate the Polls application without having to change anything in it.


*************************************
Incorporate the ``polls`` application
*************************************

Install ``polls``
=================

Install the application from its GitHub repository using ``pip``::

Expand All @@ -33,20 +43,20 @@ Install the application from its GitHub repository using ``pip``::
Let's add this application to our project. Add ``'polls'`` to the end of ``INSTALLED_APPS`` in
your project's `settings.py` (see the note on :ref:`installed_apps` about ordering ).

Add the following line to ``urlpatterns`` in the project's ``urls.py``:

.. code-block:: python
url(r'^polls/', include('polls.urls', namespace='polls')),
Make sure this line is included **before** the line for the django-cms urls:
Add the ``poll`` URL configuration to ``urlpatterns`` in the project's ``urls.py``:

.. code-block:: python
.. code-block:: python
:emphasize-lines: 3
url(r'^', include('cms.urls')),
urlpatterns += i18n_patterns(
url(r'^admin/', include(admin.site.urls)),
url(r'^polls/', include('polls.urls', namespace='polls'))
url(r'^', include('cms.urls')),
)
django CMS's URL pattern needs to be last, because it "swallows up" anything
that hasn't already been matched by a previous pattern.
Note that it must be included **before** the line for the django CMS URLs. django CMS's URL pattern
needs to be last, because it "swallows up" anything that hasn't already been matched by a previous
pattern.

Now run the application's migrations:

Expand Down Expand Up @@ -128,34 +138,35 @@ Create a new package at the project root called ``polls_cms_integration``::

python manage.py startapp polls_cms_integration

So our workspace looks like this::
Our workspace now looks like this::

env/
src/ # the django polls application is in here
polls_cms_integration/ # the newly-created application
__init__.py
admin.py
models.py
migrations.py
tests.py
views.py
mysite/
static/
project.db
requirements.txt
tutorial-project/
media/
mysite/
polls_cms_integration/ # the newly-created application
__init__.py
admin.py
models.py
migrations.py
tests.py
views.py
static/
manage.py
project.db
requirements.txt


Add it to ``INSTALLED_APPS``
============================

Next is to integrate the ``polls_cms_integration`` application into the project.

Add ``polls_cms_integration`` to ``INSTALLED_APPS`` in ``settings.py`` - and now we're ready to use it to being
Add ``polls_cms_integration`` to ``INSTALLED_APPS`` in ``settings.py`` - and now we're ready to use it to begin
integrating Polls with django CMS. We'll start by :ref:`developing a Polls plugin <plugins_tutorial>`.

.. note::

**The project or the application?**
**Adding templates to the project or to the application?**

Earlier, we added new templates to the project. We could equally well have have added ``templates/polls/base.html``
inside ``polls_cms_integration``. After all, that's where we're going to be doing all the other integration work.
Expand Down
132 changes: 132 additions & 0 deletions docs/introduction/04-plugins.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
.. _plugins_tutorial:

#######
Plugins
#######

In this tutorial we're going to take a basic Django opinion poll application and integrate it into
the CMS.


*********************************
Create a plugin model
*********************************

In your the ``models.py`` of ``polls_cms_integration`` add the following:

.. code-block:: python
from django.db import models
from cms.models import CMSPlugin
from polls.models import Poll
class PollPluginModel(CMSPlugin):
poll = models.ForeignKey(Poll)
def __str__(self):
return self.poll.question
This creates a plugin model class; these all inherit from the
:class:`cms.models.pluginmodel.CMSPlugin` base class.

.. note::

django CMS plugins inherit from :class:`cms.models.pluginmodel.CMSPlugin` (or a
sub-class thereof) and not :class:`models.Model <django.db.models.Model>`.

Create and run migrations:

.. code-block:: bash
python manage.py makemigrations polls_cms_integration
python manage.py migrate polls_cms_integration
The Plugin Class
================

Now create a new file ``cms_plugins.py`` in the same folder your ``models.py`` is in.
The plugin class is responsible for providing django CMS with the necessary
information to render your plugin.

For our poll plugin, we're going to write the following plugin class:

.. code-block:: python
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from polls_cms_integration.models import PollPluginModel
from django.utils.translation import ugettext as _
@plugin_pool.register_plugin # register the plugin
class PollPluginPublisher(CMSPluginBase):
model = PollPluginModel # model where plugin data are saved
module = _("Polls")
name = _("Poll Plugin") # name of the plugin in the interface
render_template = "polls_cms_integration/poll_plugin.html"
def render(self, context, instance, placeholder):
context.update({'instance': instance})
return context
.. note::

All plugin classes must inherit from :class:`cms.plugin_base.CMSPluginBase`
and must register themselves with the :class:`plugin_pool <cms.plugin_pool.PluginPool>`.

A reasonable convention for plugin naming is:

* ``PollPluginModel``: the *model* class
* ``PollPluginPublisher``: the *plugin* class

You don't need to follow this convention, but choose one that makes sense and stick to it.


The template
============

The ``render_template`` attribute in the plugin class is required, and tells the plugin which
:attr:`render_template <cms.plugin_base.CMSPluginBase.render_template>` to use when rendering.

In this case the template needs to be at ``polls_cms_integration/templates/polls_cms_integration/poll_plugin.html`` and should look something like this:

.. code-block:: html+django

<h1>{{ instance.poll.question }}</h1>

<form action="{% url 'polls:vote' instance.poll.id %}" method="post">
{% csrf_token %}
<div class="form-group">
{% for choice in instance.poll.choice_set.all %}
<div class="radio">
<label>
<input type="radio" name="choice" value="{{ choice.id }}">
{{ choice.choice_text }}
</label>
</div>
{% endfor %}
</div>
<input type="submit" value="Vote" />
</form>


***************************************************
Test the plugin
***************************************************

Now you can restart the runserver (required because you added the new ``cms_plugins.py`` file, and
visit http://localhost:8000/.

You can now drop the ``Poll Plugin`` into any placeholder on any page, just as
you would any other plugin.

.. image:: /introduction/images/poll-plugin-in-menu.png
:alt: the 'Poll plugin' in the plugin selector
:width: 400
:align: center

Next we'll integrate the Polls application more fully into our django CMS
project.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file modified docs/introduction/images/welcome.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 32d9b73

Please sign in to comment.