--- a/src/pyams_default_theme/features/header/__init__.py Mon Jul 02 17:13:16 2018 +0200
+++ b/src/pyams_default_theme/features/header/__init__.py Tue Jul 03 12:18:33 2018 +0200
@@ -17,11 +17,21 @@
# import interfaces
from pyams_content.features.header.interfaces import IHeaderTarget, IHeaderSettings
+from pyams_content.features.menu.interfaces import IMenuLinksContainerTarget, IMenuLinksContainer
+from pyams_default_theme.features.header.interfaces import ISimpleHeaderRendererSettings, ISimpleHeaderTabsMenu
from pyams_default_theme.layer import IPyAMSDefaultLayer
+from zope.location.interfaces import ISublocations
# import packages
+from persistent import Persistent
+from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
+from pyams_content.features.menu import Menu
+from pyams_file.property import FileProperty
+from pyams_utils.adapter import get_annotation_adapter, adapter_config, ContextAdapter
from pyams_utils.traversing import get_parent
from pyams_viewlet.viewlet import contentprovider_config, ViewContentProvider
+from zope.interface import implementer
+from zope.location import Location, locate
@contentprovider_config(name='pyams.header', layer=IPyAMSDefaultLayer)
@@ -42,3 +52,37 @@
if renderer is None:
return ''
return renderer.render()
+
+
+#
+# Simple header renderer settings
+#
+
+SIMPLE_HEADER_TABS_KEY = '{0}::tabs'.format(ASSOCIATION_CONTAINER_KEY)
+
+
+@implementer(ISimpleHeaderRendererSettings, IMenuLinksContainerTarget)
+class SimpleHeaderRendererSettings(Persistent, Location):
+ """Simple header renderer settings"""
+
+ banner = FileProperty(ISimpleHeaderRendererSettings['banner'])
+ logo = FileProperty(ISimpleHeaderRendererSettings['logo'])
+
+ @property
+ def tabs(self):
+ return get_annotation_adapter(self, SIMPLE_HEADER_TABS_KEY, Menu,
+ markers=ISimpleHeaderTabsMenu, name='++ass++tabs')
+
+
+@adapter_config(name='tabs', context=ISimpleHeaderRendererSettings, provides=IMenuLinksContainer)
+def simple_header_tabs_links_adapter(context):
+ """Simple header tabs links adapter"""
+ return context.tabs
+
+
+@adapter_config(name='links', context=ISimpleHeaderRendererSettings, provides=ISublocations)
+class SimpleHeaderRendererSettingsSublocations(ContextAdapter):
+ """Simple header renderer settings sub-locations adapter"""
+
+ def sublocations(self):
+ return self.context.tabs.values()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/header/interfaces.py Tue Jul 03 12:18:33 2018 +0200
@@ -0,0 +1,43 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.features.header.interfaces import IHeaderRendererSettings
+
+# import packages
+from pyams_file.schema import ImageField
+from zope.interface import Interface, Attribute
+
+from pyams_default_theme import _
+
+
+class ISimpleHeaderRendererSettings(IHeaderRendererSettings):
+ """Simple header renderer settings"""
+
+ banner = ImageField(title=_("Banner image"),
+ description=_("Image displayed as header background"),
+ required=False)
+
+ logo = ImageField(title=_("Logo"),
+ description=_("Logo displayed in header"),
+ required=False)
+
+ tabs = Attribute("Top tabs list")
+
+
+class ISimpleHeaderTabsMenu(Interface):
+ """Simple header menu marker interface"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/header/skin/__init__.py Tue Jul 03 12:18:33 2018 +0200
@@ -0,0 +1,62 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_content.component.association.interfaces import IAssociationInfo
+from pyams_content.features.header.interfaces import IHeaderTarget, IHeaderRenderer, IHeaderSettings, \
+ IHeaderRendererSettings
+from pyams_default_theme.features.header.interfaces import ISimpleHeaderRendererSettings
+from pyams_skin.layer import IPyAMSLayer
+
+# import packages
+from pyams_content.features.header.skin import BaseHeaderRenderer
+from pyams_default_theme.features.header import SimpleHeaderRendererSettings
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+
+from pyams_default_theme import _
+
+
+SIMPLE_HEADER_RENDERER_NAME = 'PyAMS simple header'
+
+
+#
+# Simple header renderer
+#
+
+@adapter_config(name=SIMPLE_HEADER_RENDERER_NAME, context=(IHeaderTarget, IPyAMSLayer), provides=IHeaderRenderer)
+@adapter_config(name=SIMPLE_HEADER_RENDERER_NAME, context=(IHeaderSettings, IPyAMSLayer), provides=IHeaderRenderer)
+@template_config(template='templates/simple-header.pt', layer=IPyAMSLayer)
+class SimpleHeaderRenderer(BaseHeaderRenderer):
+ """Simple header renderer"""
+
+ name = SIMPLE_HEADER_RENDERER_NAME
+ label = _("PyAMS simple header with banner and tabs")
+ weight = 1
+
+ settings_key = 'PyAMS::simple'
+ settings_interface = ISimpleHeaderRendererSettings
+
+ @staticmethod
+ def get_link_info(link):
+ return IAssociationInfo(link)
+
+
+@adapter_config(context=SimpleHeaderRenderer, provides=IHeaderRendererSettings)
+def simple_header_renderer_settings_factory(context):
+ """Simple header renderer settings factory"""
+ return SimpleHeaderRendererSettings()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/header/skin/templates/simple-header.pt Tue Jul 03 12:18:33 2018 +0200
@@ -0,0 +1,24 @@
+<div class="header header-simple"
+ tal:define="settings view.settings" i18n:domain="pyams_default_theme">
+ <div class="banner">
+ <tal:if define="banner settings.banner"
+ condition="banner">
+ <img class="banner"
+ tal:define="src extension:absolute_url(banner)"
+ tal:attributes="src string:${src}?_=${extension:timestamp(banner)}" />
+ </tal:if>
+ <tal:if define="logo settings.logo"
+ condition="logo">
+ <img class="logo"
+ tal:define="src extension:absolute_url(settings.logo, '++thumb++200x200')"
+ tal:attributes="src string:${src}?_=${extension:timestamp(logo)}" />
+ </tal:if>
+ </div>
+ <tal:loop repeat="link settings.tabs.get_visible_items()">
+ <a tal:define="info view.get_link_info(link);
+ href link.get_url(request)"
+ tal:condition="href"
+ tal:content="info.user_title"
+ tal:attributes="href href">Link</a><br />
+ </tal:loop>
+</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/header/zmi/__init__.py Tue Jul 03 12:18:33 2018 +0200
@@ -0,0 +1,84 @@
+#
+# Copyright (c) 2008-2018 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_default_theme.features.header import ISimpleHeaderRendererSettings, ISimpleHeaderTabsMenu
+from pyams_form.interfaces.form import IInnerSubForm
+from pyams_portal.interfaces import MANAGE_TEMPLATE_PERMISSION
+from pyams_skin.layer import IPyAMSLayer
+from transaction.interfaces import ITransactionManager
+
+# import packages
+from pyams_content.features.header.zmi import HeaderSettingsRendererSettingsEditForm
+from pyams_content.features.menu.zmi import LinksTable, IMenuLinksView, MenuLinksView
+from pyams_skin.event import get_json_widget_refresh_event
+from pyams_utils.adapter import adapter_config
+from pyams_zmi.form import InnerAdminEditForm
+from z3c.form import field
+
+from pyams_default_theme import _
+
+
+@adapter_config(name='simple-header-properties',
+ context=(ISimpleHeaderRendererSettings, IPyAMSLayer, HeaderSettingsRendererSettingsEditForm),
+ provides=IInnerSubForm)
+class SimpleHeaderPropertiesEditForm(InnerAdminEditForm):
+ """Simple header properties edit form"""
+
+ legend = None
+ edit_permission = MANAGE_TEMPLATE_PERMISSION
+ weight = 1
+
+ fields = field.Fields(ISimpleHeaderRendererSettings)
+
+ def get_ajax_output(self, changes):
+ output = super(SimpleHeaderPropertiesEditForm, self).get_ajax_output(changes)
+ updated = changes.get(ISimpleHeaderRendererSettings, ())
+ if updated:
+ ITransactionManager(self.context).commit()
+ if 'banner' in updated:
+ output.setdefault('events', []).append(
+ get_json_widget_refresh_event(self.context, self.request,
+ SimpleHeaderPropertiesEditForm, 'banner'))
+ if 'logo' in updated:
+ output.setdefault('events', []).append(
+ get_json_widget_refresh_event(self.context, self.request,
+ SimpleHeaderPropertiesEditForm, 'logo'))
+ return output
+
+
+#
+# Header top tabs table view
+#
+
+class TabsAssociationsTable(LinksTable):
+ """Simple header tabs associations table"""
+
+ associations_name = 'tabs'
+
+
+@adapter_config(name='simple-header-tabs',
+ context=(ISimpleHeaderRendererSettings, IPyAMSLayer, HeaderSettingsRendererSettingsEditForm),
+ provides=IInnerSubForm)
+@adapter_config(name='++ass++tabs', context=(ISimpleHeaderTabsMenu, IPyAMSLayer), provides=IMenuLinksView)
+class SimpleHeaderTabsView(MenuLinksView):
+ """Simple header tabs view"""
+
+ title = _("Top tabs")
+
+ table_class = TabsAssociationsTable
+ weight = 10
Binary file src/pyams_default_theme/locales/fr/LC_MESSAGES/pyams_default_theme.mo has changed
--- a/src/pyams_default_theme/locales/fr/LC_MESSAGES/pyams_default_theme.po Mon Jul 02 17:13:16 2018 +0200
+++ b/src/pyams_default_theme/locales/fr/LC_MESSAGES/pyams_default_theme.po Tue Jul 03 12:18:33 2018 +0200
@@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-06-20 14:40+0200\n"
+"POT-Creation-Date: 2018-07-03 09:32+0200\n"
"PO-Revision-Date: 2017-06-07 12:41+0200\n"
"Last-Translator: Thierry Florac <tflorac@ulthar.net>\n"
"Language-Team: French\n"
@@ -248,6 +248,30 @@
msgid "Label associated with second level options menu"
msgstr "Libellé associé au second niveau de sélection"
+#: src/pyams_default_theme/features/header/interfaces.py:31
+msgid "Banner image"
+msgstr "Bandeau"
+
+#: src/pyams_default_theme/features/header/interfaces.py:32
+msgid "Image displayed as header background"
+msgstr "Image affichée en tête de page"
+
+#: src/pyams_default_theme/features/header/interfaces.py:35
+msgid "Logo"
+msgstr "Logo"
+
+#: src/pyams_default_theme/features/header/interfaces.py:36
+msgid "Logo displayed in header"
+msgstr "Logo superposé au bandeau"
+
+#: src/pyams_default_theme/features/header/zmi/__init__.py:81
+msgid "Top tabs"
+msgstr "Onglets de navigation"
+
+#: src/pyams_default_theme/features/header/skin/__init__.py:48
+msgid "PyAMS simple header with banner and tabs"
+msgstr "PyAMS: en-tête simple avec bandeau et onglets de navigation"
+
#~ msgid "Search..."
#~ msgstr "Chercher..."
--- a/src/pyams_default_theme/locales/pyams_default_theme.pot Mon Jul 02 17:13:16 2018 +0200
+++ b/src/pyams_default_theme/locales/pyams_default_theme.pot Tue Jul 03 12:18:33 2018 +0200
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-06-20 14:40+0200\n"
+"POT-Creation-Date: 2018-07-03 09:32+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -230,3 +230,27 @@
#: ./src/pyams_default_theme/features/menu/portlet/navigation/interfaces.py:35
msgid "Label associated with second level options menu"
msgstr ""
+
+#: ./src/pyams_default_theme/features/header/interfaces.py:31
+msgid "Banner image"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/interfaces.py:32
+msgid "Image displayed as header background"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/interfaces.py:35
+msgid "Logo"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/interfaces.py:36
+msgid "Logo displayed in header"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/zmi/__init__.py:81
+msgid "Top tabs"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/skin/__init__.py:48
+msgid "PyAMS simple header with banner and tabs"
+msgstr ""
--- a/src/pyams_default_theme/resources/css/pyams-default.css Mon Jul 02 17:13:16 2018 +0200
+++ b/src/pyams_default_theme/resources/css/pyams-default.css Tue Jul 03 12:18:33 2018 +0200
@@ -1,3 +1,19 @@
+body {
+ max-width: 950px;
+ margin: 0 auto;
+}
+body .header-simple .banner {
+ position: relative;
+}
+body .header-simple .banner img.banner {
+ width: 100%;
+}
+body .header-simple .banner img.logo {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ max-height: calc(80%);
+}
@media only screen and (min-width: 1200px) {
.portal-page .slot.col-lg-0 {
display: none;
@@ -18,3 +34,4 @@
display: none;
}
}
+/*# sourceMappingURL=pyams-default.css.map */
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/resources/css/pyams-default.css.map Tue Jul 03 12:18:33 2018 +0200
@@ -0,0 +1,1 @@
+{"version":3,"sources":["../less/pyams-default.less"],"names":[],"mappings":"AAAA;EACC,gBAAA;EACA,cAAA;;AAFD,IAIC,eACC;EACC,kBAAA;;AAGC,IALH,eACC,QAGC,IACE;EACA,WAAA;;AAED,IARH,eACC,QAGC,IAIE;EACA,kBAAA;EACA,SAAA;EACA,UAAA;EACA,YAAY,SAAZ;;AAUH,wBAA2C;EAC1C,YAFF,MAEG;IACA,aAAA;;;AAGF,wBAA0C,uBAAwB;EACjE,YAPF,MAOG;IACA,aAAA;;;AAGF,wBAA0C,uBAAuB;EAChE,YAZF,MAYG;IACA,aAAA;;;AAGF,wBAA0C;EACzC,YAjBF,MAiBG;IACA,aAAA","file":"pyams-default.css"}
\ No newline at end of file
--- a/src/pyams_default_theme/resources/css/pyams-default.min.css Mon Jul 02 17:13:16 2018 +0200
+++ b/src/pyams_default_theme/resources/css/pyams-default.min.css Tue Jul 03 12:18:33 2018 +0200
@@ -1,1 +1,1 @@
-@media only screen and (min-width:1200px){.portal-page .slot.col-lg-0{display:none}}@media only screen and (min-width:992px) and (max-width:1199px){.portal-page .slot.col-md-0{display:none}}@media only screen and (min-width:768px) and (max-width:991px){.portal-page .slot.col-sm-0{display:none}}@media only screen and (max-width:767px){.portal-page .slot.col-xs-0{display:none}}
\ No newline at end of file
+body{max-width:950px;margin:0 auto}body .header-simple .banner{position:relative}body .header-simple .banner img.banner{width:100%}body .header-simple .banner img.logo{position:absolute;top:10px;left:10px;max-height:calc(80%)}@media only screen and (min-width:1200px){.portal-page .slot.col-lg-0{display:none}}@media only screen and (min-width:992px) and (max-width:1199px){.portal-page .slot.col-md-0{display:none}}@media only screen and (min-width:768px) and (max-width:991px){.portal-page .slot.col-sm-0{display:none}}@media only screen and (max-width:767px){.portal-page .slot.col-xs-0{display:none}}
--- a/src/pyams_default_theme/resources/less/pyams-default.less Mon Jul 02 17:13:16 2018 +0200
+++ b/src/pyams_default_theme/resources/less/pyams-default.less Tue Jul 03 12:18:33 2018 +0200
@@ -1,3 +1,26 @@
+body {
+ max-width: 950px;
+ margin: 0 auto;
+
+ .header-simple {
+ .banner {
+ position: relative;
+
+ img {
+ &.banner {
+ width: 100%;
+ }
+ &.logo {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ max-height: calc(100% - 20px);
+ }
+ }
+ }
+ }
+}
+
.portal-page {
.slot {