26. i18n-urls
• Language prefix
/de/your_url/
• middleware based
• no changesurls, apps your
templates,
needed to
27. integrating it
• How your own project.
into
to integrate the cms
• It’s just an app.
1. Menus
2. Attach Menus
3. Navigation Modifiers
4. App-hooks
5. Custom Plugins
6. Placeholders
28. menus
• Addmenu own entries to
the
your
• yourapp/menu.py
• entries will be attached to
the root.
29. menus – menu.py
from menus.base import Menu, NavigationNode
from menus.menu_pool import menu_pool
from django.utils.translation import ugettext_lazy as _
class MyMenu(Menu):
def get_nodes(self, request):
nodes = []
n = NavigationNode(_("login"), reverse("auth_login"), 1)
n2 = NavigationNode(_("admin"), reverse("admin:root"), 2)
n3 = NavigationNode(_("My list"), "/mylist/", 3)
n4 = NavigationNode(_("My sublist"), "/mylist/sublist/", 4, 3)
nodes.append(n)
nodes.append(n2)
nodes.append(n3)
nodes.append(n4)
return nodes
menu_pool.register_menu(MyMenu)
30. attach menus
• Inherits from instead of
CMSAttachMenu
Menu
• Selectadvanced settings to
page
your menu in the
attach.
• Needs a name
31. attach menus – menu.py
from menus.base import Menu, NavigationNode
from menus.menu_pool import menu_pool
from django.utils.translation import ugettext_lazy as _
from cms.menu_bases import CMSAttachMenu
class MyMenu(CMSAttachMenu):
name = _("My Menu")
def get_nodes(self, request):
nodes = []
n = NavigationNode(_("login"), reverse("auth_login"), 1)
n2 = NavigationNode(_("admin"), reverse("admin:root"), 2)
n3 = NavigationNode(_("My list"), "/mylist/", 3)
n4 = NavigationNode(_("My sublist"), "/mylist/sublist/", 4, 3)
nodes.append(n)
nodes.append(n2)
nodes.append(n3)
nodes.append(n4)
return nodes
menu_pool.register_menu(MyMenu)
32. menu modifiers
• modify the whole menu
tree
• add or change properties
of NavigationNodes
• rearrange trees
• applied in 3 situations:
• pre cut
• post cut
• breadcrumb
33. menu modifiers
from menus.base import Modifier
from menus.menu_pool import menu_pool
class MyModifier(Modifier):
"""
Counts the nodes
"""
def modify(self, request, nodes, namespace, root_id, post_cut, breadcrumb):
if post_cut or breadcrumb:
return nodes
count = 0
for node in nodes:
node.counter = count
count += 1
return nodes
menu_pool.register_modifier(MyModifier)
34. app-hooks
• attach whole apps to a
page.
• myapp/cms_app.py
• urls.py gets attached to a
page url
• needs server restart after
changes :(
35. app-hooks – cms_app.py
from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
from django.utils.translation import ugettext_lazy as _
from myapp.menu import MyMenu
class MyApphook(CMSApp):
name = _("My App")
urls = ["myapp.urls"]
apphook_pool.register(MyApphook)
36. app-hooks – urls.py
from django.conf.urls.defaults import *
urlpatterns = patterns("myapp.views",
url(r"^$', "main_view", name="app_main"),
url(r"^sublevel/$", "sample_view", name="app_sublevel"),
)
• Page URL: /mypage/
• /mypage/ will be handled by main_view
• /mypage/sublevel/ will be handled by sample_view
• plugins from page are available in app templates
37. app-hooks
• If page has german url as well:
/meine_seite/
• app is available at:
/en/mypage/
/de/meine_seite/
• reverse("main_view") or {% url main_view
%}will choose current language
• to choose manually:
• reverse("de:main_view")
• reverse("en:main_view")
• {% url de:main_view %}
38. app-hooks – cms_app.py
from myapp.menu import CategoryMenu
class MyApphook(CMSApp):
name = _("My App")
urls = ["myapp.urls"]
menus = [CategoryMenu]
apphook_pool.register(MyApphook)
• If your app has a menu, attach it as well
• reverse in menu gets the language namespace as well
39. app-hooks – models.py
from django.db import models
from django.core.urlresolvers import reverse
import mptt
class Category(models.Model):
parent = models.ForeignKey("self", blank=True, null=True)
name = models.CharField(max_length=20)
def __unicode__(self):
return self.name
def get_absolute_url(self):
return reverse("category_view", args=[self.pk])
try:
mptt.register(Category)
except mptt.AlreadyRegistered:
pass
40. app-hooks – menu.py
from menus.base import NavigationNode
from menus.menu_pool import menu_pool
from django.utils.translation import ugettext_lazy as _
from cms.menu_bases import CMSAttachMenu
from myapp.models import Category
class CategoryMenu(CMSAttachMenu):
name = _("My Category Menu")
def get_nodes(self, request):
nodes = []
for category in Category.objects.all().order_by("tree_id", "lft"):
nodes.append(
NavigationNode(
category.name,
category.pk,
category.parent_id
)
)
return nodes
menu_pool.register_menu(CategoryMenu)
41. custom plugins
•your data as a plugin
•teasers for your app data
•yourapp/cms_plugins.py
• model inherits from
CMSPlugin
42. custom plugins – models.py
class Gallery(models.Model):
name = models.CharField(max_length=30)
class Picture(models.Model):
gallery = models.ForeignKey(Gallery)
image = models.ImageField(upload_to="uploads/images/")
description = models.CharField(max_length=60)
43. custom plugins – models.py
from cms.models import CMSPlugin
class GalleryPlugin(CMSPlugin):
gallery = models.ForeignKey(Gallery)
44. custom plugins – cms_plugins.py
from cms.plugin_base import CMSPluginBase
from cms.plugin_pool import plugin_pool
from models import GalleryPlugin
from django.utils.translation import ugettext as _
class CMSGalleryPlugin(CMSPluginBase):
model = GalleryPlugin
name = _("Gallery")
render_template = "cms/plugins/gallery.html"
def render(self, context, instance, placeholder):
context.update({
"gallery":instance.gallery,
"object":instance,
"placeholder":placeholder
})
return context
plugin_pool.register_plugin(CMSGalleryPlugin)
45. custom plugins
• CMSPluginBase extends
from ModelAdmin
• text enabled plugins
• plugins are a tree (mptt)
• plugin media
• plugin rules in your
settings.py
• Plugin Context Processors
(add Context to render)
• Plugin Processors (Modify
output of plugins)
46. placeholders
• use the plugin system in
your own apps.
• works with frontedit :)
47. placeholders - models.py
from django.db import models
from cms.models.fields import PlaceholderField
class MyBlog(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
content = PlaceholderField("blog_content")
48. placeholders - admin.py
from django.contrib import admin
from cms.admin.placeholderadmin import PlaceholderAdmin
from models import MyBlog
class MyBlogAdmin(PlaceholderAdmin):
prepopulated_fields = {"slug": ("title",)} #just for the slug field
admin.site.register(MyBlog, MyBlogAdmin)