Итак, вы решили добавить свой модуль в Redsolution CMS.
Первое время мы ещё будем работать над API установщика, поэтому следите за изменениями в документации.
Для того, чтобы ваш модуль распознавался как подключаемый в Redsolution CMS надо, чтобы его название содержало redsolutioncms. Если вы не хотите публиковать модуль с таким названием, то можете опубликовать установщик отдельно, прописав в его зависимостях свой модуль.
В списке все модули поделены на категории. Категорию для своего модуля можно задать, если в его документации встретится ссылка вида:
/classifiers/<classifier>
Пока мы задали лишь несколько категорий:
Приложения для главной страницы и шаблоны особые категории, т.к. при выборе модулей можно выбрать только один шаблон и хотя бы одно приложение для главной страницы.
Как уже упоминалось, для того, чтобы CMS после загрузки модуля поняла, как настраивать модуль, необходимо указать “точку входа”. Сделать это можно в setup.py:
setup(
...
entry_points={
'redsolutioncms': ['myapp = myapp.redsolution_setup', ],
},
...
)
RedsolutionCMS ищет точку входа с названием redsolutioncms. В примере выше CMS попытается импортировать myapp.redsolution_setup. Если в этом модуле есть импортируемый модуль urls, то CMS будет считать модуль настраиваемым, предложит ссылку для настройки на третьем шаге.
Теперь о самом модуле myapp.redsolution_setup. Мы рассмотрим пример с настройщиком для приложения обратной связи redsolutioncms.django-simple-feedback.
Мы сделаем сразу интерфейс для настройки.
Для моделей есть базовый класс redsolutioncms.models.BaseSettings и менеджер redsolutioncms.models.BaseSettingsManager. Метод get_settings у менеджера возвращает или создает настройки по умолчанию. Из модуля настройки можно импортировать настройки с��мой RedsolutionCMS
from redsolutioncms.models import CMSSettings
cms_settings = CMSSettings.objects.get_settings()
Для создания модели настройщика, определитесь, какие настройки вы хотите видеть. Допустим, мы решили добавить одну настройку для модуля обратной связи - это флаг, определяющий отображение отдельной страницы с обратной связью. В модуле это переменная DIRECT_TO_TEMPLATE в settings.py.
Текст модели и её менеджера для настройщика модуля будет выглядеть примерно так
# -*- coding: utf-8 -*-
from django.db import models
from django.utils.translation import ugettext_lazy as _
from redsolutioncms.models import CMSSettings, BaseSettings, BaseSettingsManager
class FeedbackSettingsManager(BaseSettingsManager):
def get_settings(self):
if self.get_query_set().count():
# Если настройки уже есть, возвращаем их
return self.get_query_set()[0]
else:
# если настроек нет, создать со значениями по умолчанию
feedback_settings = self.get_query_set().create()
# а здесь можно интегрироваться с другими настройщиками
# например, добавить SEO поля для новостей можно так:
# django-seo integration
# cms_settings = CMSSettings.objects.get_settings()
#if 'redsolutioncms.django-seo' in cms_settings.installed_packages:
# try:
# from seo.redsolution_setup.models import SeoSettings
# except ImportError:
# pass
#else:
# seo_settings = SeoSettings.objects.get_settings()
# seo_settings.models.get_or_create(model='easy_news.models.News')
return feedback_settings
class FeedbackSettings(BaseSettings):
use_direct_view = models.BooleanField(
verbose_name=_('Use dedicated view to render feedback page'),
default=True
)
objects = FeedbackSettingsManager()
Для интерактивной настройки мы решили использовать уже готовые классы админики Django. Для того, чтобы дать пользователю выбрать в нашем случае значение флага, нужно создать класс ModelAdmin и прписать его в urls.py настройщика.
Текст admin.py
from django.contrib import admin
from feedback.redsolution_setup.models import FeedbackSettings
from redsolutioncms.admin import CMSBaseAdmin
class FeedbackSettingsAdmin(CMSBaseAdmin):
model = FeedbackSettings
Да, такой короткий :) И текст urls.py, в котором создается на лету объект админики и пользователю показывают страницу изменения свойств объекта
# -*- coding: utf-8 -*-
from django.conf.urls.defaults import patterns, url
from feedback.redsolution_setup.admin import FeedbackSettingsAdmin
admin_instance = FeedbackSettingsAdmin()
urlpatterns = patterns('',
url(r'^$', admin_instance.change_view, name='feedback_index'),
)
Однако создание модели - это половина работы. Модели настройщиков хранят знаечния настроек, на этапе создания интегрируются друг с другом и предоставляют интерактивный интерфейс. Конечным же продуктом будут файлы проекта. Зачастую изменения надо вности только в settings.py и urls.py. Изменения вносятся на этапе сборки.
За сборку настроек отвечает файл make.py, он обязательный. Сборка проходит в три этапа.
1. Premake На этом этапе подготавливаются начальные значения переменных, создаются папки, RedsolutionCMS создает базовый шаблон и т.п. В premake располагайте те функции, которые дожлны отработать прежде всех остальных.
2. Make Основной этап сборки. RedsolutionCMS создает проект, рендерит шаблоны, затем остальные модули делают то же самое. Некоторые из модулей копируют медиа-файлы в папку проекта на этой стадии.
3. Postmake Заключительная стадия. Она введена для тех операций, которые предполагают почти собранный проект. На этой стадии RedsolutionCMS генерирует sitemaps для модулей, обрабатывает начальные данные приложений и т.п. Некоторые приложения копируют медиа-файлы и на этой стадии.
Для записи настроек в файлы проекта созданы методы объектов CMSSettings.
Генерирует контент в заданный файл по указанному шаблону
Parameters: |
|
---|
В этой функции file_name может быть списком, при записи этот список будет соединен фкнуцией os.path.join в путь до файла. Например
cms_settings = CMSSettings.objects.get_settings()
feedback_settings = FeedbackSettings.objects.get_settings()
cms_settings.render_to('settings.py', 'feedback/redsolutioncms/settings.pyt', {
'feedback_settings': feedback_settings,
})
Копирует или дописывает контент указанного файла
Parameters: |
|
---|
Эта функция может пригодиться, если вам нужно скопировать, например, начальные данные
cms_settings.copy_file(
join(cms_settings.project_dir, 'fixtures', 'initial_data.json'),
join(dirname(__file__), 'fixtures', 'project_data', 'initial_data.json'),
mode='a',
)
Функция для копирования каталогов
Parameters: |
|
---|
Этой функцией удобно пользоваться для копирования стилей или медиа-файлов
cms_settings = CMSSettings.objects.get_settings()
cms_settings.copy_dir(
os.path.join(cms_settings.project_dir, 'media',),
os.path.join(os.path.dirname(__file__), 'templates', 'classic', 'media'),
merge=True
)
В заключение я приведу пример, который вы сами можете в принципе посмотреть make-класса для одного из последних написанных установщиков:
from redsolutioncms.make import BaseMake
from redsolutioncms.models import CMSSettings
from feedback.redsolution_setup.models import FeedbackSettings
from os.path import dirname, join
import shutil
class Make(BaseMake):
def make(self):
super(Make, self).make()
cms_settings = CMSSettings.objects.get_settings()
feedback_settings = FeedbackSettings.objects.get_settings()
cms_settings.render_to('settings.py', 'feedback/redsolutioncms/settings.pyt', {
'feedback_settings': feedback_settings,
})
cms_settings.render_to('urls.py', 'feedback/redsolutioncms/urls.pyt', {
'feedback_settings': feedback_settings,
})
def postmake(self):
super(Make, self).postmake()
cms_settings = CMSSettings.objects.get_settings()
feedback_settings = FeedbackSettings.objects.get_settings()
feedback_media_dir = join(dirname(dirname(__file__)), 'media')
project_media_dir = join(cms_settings.project_dir, 'media')
# WARNING! Silently delete media dirs
try:
shutil.rmtree(join(project_media_dir, 'feedback'))
# no such directory
except OSError:
pass
if 'redsolutioncms.django-server-config' not in cms_settings.installed_packages:
# copy files to media directory
shutil.copytree(
join(feedback_media_dir, 'feedback'),
join(project_media_dir, 'feedback'),
)
make = Make()