Django i CMSy

Niedawno, zasiadając do realizacji pewnego zadania, stwierdziłem, że potrzebuję użyć jakiegoś CMSa. Niewątpliwie najlepszym systemem tego typu napisanym w Pythonie jest Plone, tyle, że okazał się on być zbyt duży w stosunku do moich potrzeb – szukałem czegoś małego, lekkiego i najchętniej w Django.

Plone

Plone posiada przyjazny interfejs użytkownika i całą masę pluginów, co pozwala na “wyklikanie” nawet dość złożonych rozwiązań. Przy tym jednak oparty jest na Zope, co oprócz wielu zalet związanych z możliwościami samego Zope powoduje, że po pierwsze potrzebny jest ponadstandardowy hosting, a po drugie, w przypadku, gdy zachodzi potrzeba dopisania własnego rozszerzenia trzeba pokonać dość stromą ścieżkę nauki Zope. Szczęśliwie Plone, w odróżnieniu od samego Zope, ma przyzwoitą dokumentację obejmującą także programowanie, ale pomimo tego łatwo nie jest. Podsumowując, dla większych CMS-ów Plone jest rozwiązaniem godnym rozważenia, dla mniejszych niekoniecznie.

CMSy w Django

Jak już powiedziałem, potrzebowałem mniejszego CMSa, najlepiej opartego na moim ulubionym Django. Z pomocą przyszła mi strona z porównaniem djangowych CMSów, dzięki której zdecydowalem się na użycie django CMS 2.0. Najciekawszą alternatywą dla niego był Fein CMS, ale odpadł on z uwagi na to, że jest nieco zbyt magiczny (przynajmniej na pierwszy rzut oka).

Dodam, że istnieje jeszcze jeden ciekawy CMS, nie ujęty we wspomnianym porównaniu. CMS, który wydaje się mieć bardzo duże możliwości, ale niestety praktycznie nie ma dokumentacji. Jest to Ella, stworzona przez naszych sąsiadów zza południowej granicy. Mam nadzieję, że dokumentacja się wkrótce pojawi, zresztą rozmawiałem o tym na Pyconie z jednym z twórców Elli Honzą Kralem i obiecał, że postarają się coś w tym temacie zrobić. Zobaczymy.

django CMS

django CMS ujmuje ładną i przejrzystą stroną domową z dużą ilością dokumentacji. Po prostu od razu chce się go używać. Poniżej przedstawiam proces instalacji django CMS oraz informacje o tym jak wygląda praca z tym narzędziem.

Instalacja

  1. Najpierw należy pobrać źródła django CMS ze strony projektu (lub źródła z githuba). Potem trzeba zainstalować django CMS korzystając na przykład z polecenia
    python setup.py install

    Najlepiej zrobić to w ramach virtualenva, aby nie śmiecić w systemowym Pythonie.U mnie wygląda to następująco (używam virtualenvwrappera):

    e-X:~$ mkvirtualenv djangocms
    (djangocms)e-X:~$ easy_install django
    (djangocms)e-X:~$ easy_install south
    (djangocms)e-X:~$ easy_install django-reversion
    (djangocms)e-X:~$ cd
    (djangocms)e-X:~/$ python setup.py install
  2. W kolejnym etapie należy utworzyć projekt, który będzie bazował na django CMS. Można tu albo utworzyć nowy projekt poleceniem:
    django-admin startproject mycms i skonfigurować go zgodnie z instrukcją, albo użyć przykładowego projektu dołączonego do django CMS. Na potrzeby tego wpisu wykorzystałem tę drugą opcję, czyli skorzystałem z projektu przykładowego “example”.

    (djangocms)e-X:~$ cdvirtualenv
    (djangocms)e-X:~/virtualenvs/djangocms$ mkdir src
    (djangocms)e-X:~/virtualenvs/djangocms$ cd src
    (djangocms)e-X:~/virtualenvs/djangocms/src$cp /example example
  3. Następnie należy utworzyć bazę danych. Ponieważ korzystam z Postgresa, konfigurację bazy zdefiniowałem następująco (w settings.py):
    DATABASE_ENGINE = 'postgresql_psycopg2'
    DATABASE_NAME = 'examplecms'
    DATABASE_USER = 'cms'
    DATABASE_PASSWORD = 'xxx'

    po czym utworzyłem odpowiednią bazę danych w Postgresie i wygenerowałem w niej struktury danych. To ostatnie wykonałem korzystając z syncdb oraz dostarczonych z django CMS migracji obsługiwanych przez South.

    (djangocms)e-X:~/virtualenvs/djangocms/src/example$ ./manage.py syncdb
    (djangocms)e-X:~/virtualenvs/djangocms/src/example$ ./manage.py migrate
  4. Aby CMS mógł działać trzeba poprawnie skonfigurować media, czyli grafikę i javascript. W tym celu wystarczy zrobić link symboliczny do mediów w folderze projektu. U mnie wygląda to tak:
    (djangocms)e-X:~/virtualenvs/djangocms/src/example$
    ln -s ../../lib/python2.6/site-packages/django_cms-2.0.0.alpha-py2.6.egg/cms/media/
                                                                      cms_media

    i w settings.py

    MEDIA_ROOT = os.path.join(PROJECT_DIR, 'cms_media')
  5. Pozostało już tylko uruchomić uruchomić CMSa.Najpierw serwer
    (djangocms)e-X:~/virtualenvs/djangocms/src/example$ ./manage.py runserver

    a potem potem stronę w przeglądarce:

    http://localhost:8000

    Jeśli wszystko jest ok, to powinna się pojawić strona powitalna z widocznym logo django CMS.

Tworzenie stron

Kiedy CMS jest już zainstalowany, skonfigurowany i uruchomiony trzeba wprowadzić do niego trochę contentu. W django CMS zasadniczym contentem są strony (Page) oraz umieszczane w nich pluginy.

Aby stworzyć nową stronę należy przejść do panelu administracyjnego: http://localhost:8000/admin i dodać nową stronę (Page) w sekcji CMS. Po podaniu tytułu strony, wybraniu języka i szablonu warto kliknąć “save and continue editing” po to by określić szczegółowe parametry strony.

Django CMS - nowa strona

Języki jakie ma obsługiwać CMS, dostępne szablony stron, a także wiele innych parametrów CMS konfiguruje się w settings.py. Pełna lista opcji konfiguracyjnych django CMS znajduje się oczywiście w dokumentacji.

  1. Szablony
    Szablon przypisywany do strony określa jej layout. Na przykład mogę stworzyć szablon 1kolumna.html, który będzie używany dla stron z jedną kolumną oraz szablon 2kolumny.html dla stron z dwoma kolumnami itd. Oprócz layoutu w szablonach umieszcza się placeholdery, czyli tagi w formie {% placeholder "right_column %}, {% placeholder "body" %}. Te tagi wskazują miejsca, w które wstawiane będą pluginy. Fragment template z przykładowej aplikacji wygląda następująco:

    <h2>Content</h2>
    {% block content %}
        <div style="width:70%">
            <h3>title placeholder {% page_attribute title %}</h3>
            <div style="float:right;width:25%">
                <h3>Right column placeholder</h3>
                {% placeholder right-column %}
            </div>
            <div>
                <h3>body placeholder</h3>
                {% placeholder "body" %}
            </div>
        </div>
    {% endblock %}

  2. Publikowanie stron
    Strona po utworzeniu nie jest od razu widoczna dla użytkowników. Autor może spokojnie nad stroną popracować, a dopiero potem ją opublikować zaznaczając znacznik Is published. Jeśli dodatkowo strona ma być widoczna w menu nawigacyjnym trzeba zaznaczyć także opcję In navigation.

  3. Pluginy
    Na powyższej ilustracji można zauważyć sekcje Right column oraz Body. Jest to nic innego niż wspomniane wcześniej placeholdery, w których można zamieszczać pluginy. W widocznym na obrazku placeholderze Right column został umieszczony plugin typu Text. Inne dostępne pluginy to między innymi: link, obrazek, mapa google, kontrolka flash.

  4. Uprawnienia
    Dla każdej strony możemy zdefiniować uprawnienia, które określają co dany użytkownik lub grupa użytkowników może ze stroną robić (edytować, usuwać, moderować itp.). Co bardzo przydatne uprawnienia mogą się automatycznie propagować na strony umieszczone niżej w hierarchii. Dla każdej ze stron można także określić, czy dostęp do niej wymaga logowania oraz czy ma się ona pokazywać w menu wszystkim, czy tylko zalogowanym użytkownikom.

Korzystając z przedstawionych opcji można, na bazie własnych szablonów, budować dość złożone strony, w ramach których określa się kto i co może zrobić, jakich pluginów użyć itd. Nadmienię jeszcze, że interfejs django CMS bazuje w dużej mierze na Ajaxie, dzięki czemu hierarchie stron buduje się za pomocą wygodnego mechanizmu przeciągnij-i-upuść.

Własne rozszerzenia

Własne rozszerzenia w django CMS można tworzyć na kilka sposobów. Pierwszy to napisanie własnego pluginu, który będziemy umieszczać w różnych placeholderach. W skrócie plugin to klasa dziedzicząca po CMSPluginBase i posiadająca funkcję render, która odpowiada za wyświetlenie pluginu.

  1. Pluginy
    Przykładowy plugin, który wyświetla formularz wyszukiwania:

    from cms.plugin_base import CMSPluginBase
    from cms.plugin_pool import plugin_pool
    from django.utils.translation import ugettext as _
    from cms.models import CMSPlugin
    from search_engine.forms import DJCMSSearchForm
    
    class CMSSearchPlugin(CMSPluginBase):
        model = CMSPlugin
        name = _("CMS search")
        render_template = "search_engine/cms_search.html"
    
        def render(self, context, instance, placeholder):
            request=context['request']
            if request.GET.get('q', None):
                form = DJCMSSearchForm(request, request.GET)
            else:
                form = DJCMSSearchForm(request, initial={'q':_('enter search query')},)
            context.update({'placeholder':placeholder,
                                    'request':context['request'],
                                    'search_form':form})
            return context
    
    plugin_pool.register_plugin(CMSSearchPlugin)

    oraz jego template:

    <div id="search-panel">
        <p>SZUKAJ</p>
        <form method="get" action="{% page_id_url "search" %}">
        <p>
            {{ search_form.q }}
            <input type="submit" value="szukaj" />
        </p>
        </form>
    </div>

    Tworzenie pluginów jest dość dobrze opisane w dokumentacji, w sekcji custom plugins, więc tam odsyłam po szczegóły.

  2. Własne aplikacje
    Własna aplikacja może zostać wpięta do django CMS w bardzo prosty sposób. Wystarczy zdefiniować w settings.py, że dana aplikacja ma być dla django CMS dostępna:

    CMS_APPLICATIONS_URLS = (
        ('someapp.urls', 'Some application'),
        ('sampleapp.urls_en', 'Sample application English URLs'),
        ('sampleapp.urls_de', 'Sample application German URLs'),
    )

    Potem należy utworzyć nową stronę (lub użyć istniejącej) i w opcjach zaawansowanych wskazać aplikację, z której ta strona skorzysta. Przedstawia to poniższa ilustracja.
    Django CMS - własna aplikacjaJeśli strona, do której została przypięta aplikacja np. obsługująca aktualności nazywa się newsy to każdy url po newsy będzie obsługiwany przez tę aplikację. Co więcej w ramach szablonów aplikacji podpinanych w ten sposób do stron można korzystać z możliwości CMSa (np. placeholderów), dzięki czemu pluginy zdefiniowane na stronach do których podpięto aplikację będą nadal działać. Mechanizm podłączania własnych aplikacji jest prosty i efektywny i bardzo przydał mi się przy realizacji mojego projektu.

Podsumowanie

Po raz kolejny potwierdziła się zasada mówiąca, aby przed rozpoczęciem pisania sprawdzić czy nie ma już gotowego rozwiązania. Django może się pochwalić kilkoma ciekawymi CMSami, wśród których pozytywnie wyróżnia się django CMS posiadający ładną stronę domową, dobrą dokumentację, a przede wszystkim sprawdzający się w rzeczywistym działaniu. Przy wszystkich swoich zaletach jest to jednak zdecydowanie inna klasa rozwiązania niż wspomniany na początku Plone, ale to akurat było dla mnie zaletą – django CMS był właściwym narzędziem do zrealizowania stojącego przede mną zadania.

21. October 2009 by restless_being
Categories: Uncategorized | Tags: , , | Leave a comment

Leave a Reply

Required fields are marked *