Customizing site appearance

Understading layers and skins

Creating a new skin

A Skin is a tagging interface for associating media, javascript and CSS resources to a renderer

1) Create a new Layer to your skin

Build a new interface inherit from ICustomLayer

class ICustomLayer(ICustomLayer):
    """skin layer"""

Define an utility providing ISkin with the custom label and the layer interface

@utility_config(name='Custom skin', provides=ISkin)
class CustomSkin(object):
    """custom root skin"""

    label = _("Custom: skin")
    layer = ICustomLayer

2) Declare the layer adapter

@adapter_config(context=(Interface, ICustomLayer, Interface), provides=IResources)
class CustomSkinResourcesAdapter(ContextRequestViewAdapter):
"""Custom skin resources adapter"""

    def get_resources(self):

We have defined a Multiadapter with context=(context, request, view).


In the ZMI website you can now change the default graphical theme by you custom skin


Adding resources library

from fanstatic import Library, Resource
from pyams_default_theme import pyams_default_theme

#Library(name, folder_path)
library = Library('mycms', 'resources')

#Resource(library, path_to_static)
mycms_css = Resource(library, 'css/mystyle.css',)

mycms_js = Resource(library, 'js/pyams-default.js',
                    depends=(pyams_default_theme, )

Resource can include others resources already defined with depends attribute, here pyams_default_theme.

Overriding templates

The simplest is to create a new class that inherits from the existing Renderer and modify this template. After that all you have to define a new adapter name and a new label.

# New custom contact paragraph renderer

@adapter_config(name='custom', context=(IContactParagraph, IPyAMSLayer), provides=ISharedContentRenderer)
@template_config(template='templates/', layer=IPyAMSLayer)
class ContactParagraphCustomRenderer(ContactParagraphDefaultRenderer):
    """Context paragraph custom renderer"""

    label = _("Custom contact renderer")
    #settings_interface = IContactParagraphDefaultRendererSettings

In this example, we have defined an adapter named ‘custom’ with IContactParagraph, IPyAMSLayer as context and provides ISharedContentRenderer interface.

Using @template_config() decorator, the renderer will be displayed in html container according to the template templates/

The new renderer inherit of ContactParagraphDefaultRenderer, have a new label (line 8) and this associated settings_interface is not modify(line 9)


You can override the template of a renderer easily with the function pyams_template.template.override_template() It’s takes the context and the new template path as params.

Creating custom renderer

We can define a new settings for the renderer, to do that we start by creating an interface:

a) Create setting interface for the renderer

class IPhotoRendererSettings(Interface):
    """Custom renderer settings interface"""

    display_photo = Bool(title=_("Show photo?"),
                         description=_("Display contact photo"),

    can_display_photo = Attribute("Check if photo can be displayed")

We have created an interface with two attributes display_photo and can_display_photo Then we create an implemantation of the interface

class PhotoRendererSettings(Persistent, Location):
    """Custom renderer settings"""

    display_photo = FieldProperty(IPhotoRendererSettings['display_photo'])

    def can_display_photo(self):
        contact = IContactParagraph(self.__parent__)
        if not
            return False
        return self.display_photo

b) Create an adapter for the render setting interface

With @adapter_config() we declare a new adapter that applies to a context and provide the interface of
renderer settings

@adapter_config(context=IContactParagraph, provides=IPhotoRendererSettings)
def custom_renderer_settings_factory(context):
    """Contact paragraph default renderer settings factory"""
    return get_annotation_adapter(context, PHOTO_RENDERER_SETTINGS_KEY,

In this example the settings interface adapter is defined with IContactParagraph as context and provide IPhotoRendererSettings.

c) Create an adapter for the render interface

@adapter_config(context=(IContactParagraph, IPyAMSLayer), provides=ISharedContentRenderer)
@template_config(template='templates/', layer=IPyAMSLayer)
class PhotoRenderer(BaseContentRenderer):
    """Context paragraph custom renderer"""

    label = _("Custom contact renderer")
    settings_interface = IPhotoRendererSettings

Add settings interface to the renderer settings_interface = IPhotoRendererSettings


When a setting_interface is associated to a renderer, you can access to settings attributes through the template

How to define or change a template for a specific skin?

Override the default template for a renderer

If you want to modify the template for a particular rendering mode, you can use the function override_template()

from pyams_template.template import override_template

from import ICustomLayer
from pyams_default_theme.component.keynumber.portlet import KeyNumberPortletHorizontalRenderer


This new template can be applied to a particular Skin by specifying on which layer to use this renderer (ex: layer=IMyWebsiteLayer)

Redefine the default template for a renderer

You must redefine an adapter to add new variables or static resources for your new template,

# import interfaces
from import ICustomLayer

from pyams_content.component.keynumber.portlet.interfaces import IKeyNumberPortletSettings
from pyams_portal.interfaces import IPortletRenderer, IPortalContext

# import packages
from import my_carousel_init ,my_carousel_animation

from pyams_default_theme.component.keynumber.portlet import KeyNumberPortletHorizontalRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
from zope.interface import Interface

@adapter_config(context=(IPortalContext, IBaseLayer, Interface, IKeyNumberPortletSettings),
@template_config(template='templates/', layer=ICustomLayer)
class MyCustomKeyNumberPortletHorizontalRenderer(KeyNumberPortletHorizontalRenderer):
        """Key numbers portlet horizontal renderer"""

        resources = (my_carousel_init, my_carousel_animation)

The attribute resources is used to load in the template static resources. The application will automatically integrate resource content when the template is calling.