--- a/.hgtags Tue Nov 20 15:19:28 2018 +0100
+++ b/.hgtags Tue Dec 04 15:53:25 2018 +0100
@@ -15,3 +15,5 @@
fe7f30ba737d6790b949bac378f8539dcb3ab62f 0.1.14
57a4e27aa1c4c87748db4caff29068e5905e0497 0.1.15
d93f3085e2616c3e0f6499925b3ce056e8f4f08f 0.1.16
+cb03816a641948ec23bac912cdc7c6f56e44f004 0.1.17
+41f43b3456db36f329fba0bed098449c98f4b55d 0.1.18
--- a/buildout.cfg Tue Nov 20 15:19:28 2018 +0100
+++ b/buildout.cfg Tue Dec 04 15:53:25 2018 +0100
@@ -79,4 +79,4 @@
eggs = pyams_default_theme [test]
[versions]
-pyams_default_theme = 0.1.16
+pyams_default_theme = 0.1.18
--- a/docs/HISTORY.txt Tue Nov 20 15:19:28 2018 +0100
+++ b/docs/HISTORY.txt Tue Dec 04 15:53:25 2018 +0100
@@ -1,6 +1,18 @@
History
=======
+0.1.18
+------
+ - added renderers to simple navigation and site summary portlets
+ - added search results portlet
+ - updated breadcrumbs and tags content providers
+ - updated renderers templates
+ - updated CSS
+
+0.1.17
+------
+ - added customizable label to contact button
+
0.1.16
------
- added results internal OID into view's preview
--- a/setup.py Tue Nov 20 15:19:28 2018 +0100
+++ b/setup.py Tue Dec 04 15:53:25 2018 +0100
@@ -22,7 +22,7 @@
README = os.path.join(DOCS, 'README.txt')
HISTORY = os.path.join(DOCS, 'HISTORY.txt')
-version = '0.1.16'
+version = '0.1.18'
long_description = open(README).read() + '\n\n' + open(HISTORY).read()
tests_require = []
--- a/src/pyams_default_theme.egg-info/PKG-INFO Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme.egg-info/PKG-INFO Tue Dec 04 15:53:25 2018 +0100
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: pyams-default-theme
-Version: 0.1.16
+Version: 0.1.18
Summary: PyAMS default theme
Home-page: http://hg.ztfy.org/pyams/pyams_default_theme
Author: Thierry Florac
@@ -11,6 +11,18 @@
History
=======
+ 0.1.18
+ ------
+ - added renderers to simple navigation and site summary portlets
+ - added search results portlet
+ - updated breadcrumbs and tags content providers
+ - updated renderers templates
+ - updated CSS
+
+ 0.1.17
+ ------
+ - added customizable label to contact button
+
0.1.16
------
- added results internal OID into view's preview
--- a/src/pyams_default_theme.egg-info/SOURCES.txt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme.egg-info/SOURCES.txt Tue Dec 04 15:53:25 2018 +0100
@@ -68,6 +68,7 @@
src/pyams_default_theme/component/paragraph/templates/milestone-default.pt
src/pyams_default_theme/component/paragraph/templates/pictogram-default.pt
src/pyams_default_theme/component/paragraph/templates/raw-default.pt
+src/pyams_default_theme/component/paragraph/templates/raw-source-code.pt
src/pyams_default_theme/component/paragraph/templates/verbatim-default.pt
src/pyams_default_theme/component/paragraph/templates/verbatim-left.pt
src/pyams_default_theme/component/paragraph/templates/verbatim-right.pt
@@ -99,10 +100,18 @@
src/pyams_default_theme/features/menu/portlet/navigation/interfaces.py
src/pyams_default_theme/features/menu/portlet/navigation/templates/double-select.pt
src/pyams_default_theme/features/menu/portlet/navigation/templates/double-vertical.pt
+src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-carousel.pt
src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-horizontal-tabs.pt
src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-horizontal.pt
+src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-panels.pt
src/pyams_default_theme/features/renderer/__init__.py
src/pyams_default_theme/features/search/__init__.py
+src/pyams_default_theme/features/search/portlet/__init__.py
+src/pyams_default_theme/features/search/portlet/interfaces.py
+src/pyams_default_theme/features/search/portlet/templates/search-results.pt
+src/pyams_default_theme/features/share/__init__.py
+src/pyams_default_theme/features/share/portlet/__init__.py
+src/pyams_default_theme/features/share/portlet/templates/toolbox.pt
src/pyams_default_theme/features/sitemap/__init__.py
src/pyams_default_theme/features/sitemap/templates/humans.pt
src/pyams_default_theme/features/sitemap/templates/robots.pt
@@ -118,6 +127,7 @@
src/pyams_default_theme/resources/css/ext/ekko-lightbox.css
src/pyams_default_theme/resources/css/ext/ekko-lightbox.min.css
src/pyams_default_theme/resources/img/dot.png
+src/pyams_default_theme/resources/img/print-button.svg
src/pyams_default_theme/resources/js/pyams-default.js
src/pyams_default_theme/resources/js/pyams-default.min.js
src/pyams_default_theme/resources/js/ext/ekko-lightbox.js
@@ -148,9 +158,11 @@
src/pyams_default_theme/shared/site/folder.py
src/pyams_default_theme/shared/site/link.py
src/pyams_default_theme/shared/site/portlet/__init__.py
+src/pyams_default_theme/shared/site/portlet/templates/site-panels.pt
src/pyams_default_theme/shared/site/portlet/templates/site-summary.pt
src/pyams_default_theme/shared/view/__init__.py
src/pyams_default_theme/shared/view/portlet/__init__.py
+src/pyams_default_theme/shared/view/portlet/interfaces.py
src/pyams_default_theme/shared/view/portlet/templates/view-items-list.pt
src/pyams_default_theme/shared/view/templates/render.pt
src/pyams_default_theme/templates/index.pt
--- a/src/pyams_default_theme/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -15,7 +15,7 @@
from fanstatic import Resource, Library
from pyramid.i18n import TranslationStringFactory
-from pyams_skin import bootstrap_css, bootstrap, bootstrap_modal_css, myams_js
+from pyams_skin import bootstrap_css, bootstrap, bootstrap_modal_css, myams_js_core
from pyams_utils.fanstatic import ExternalResource
_ = TranslationStringFactory('pyams_default_theme')
@@ -23,7 +23,8 @@
library = Library('pyams_default_theme', 'resources')
-pyams_default_theme_fonts = ExternalResource(library, 'https://fonts.googleapis.com/css?family=Lato:300|Oswald',
+pyams_default_theme_fonts = ExternalResource(library,
+ 'https://fonts.googleapis.com/css?family=Lato:300|Oswald|Source+Code+Pro',
resource_type='css')
pyams_default_theme_css = Resource(library, 'css/pyams-default.css',
@@ -32,7 +33,7 @@
pyams_default_theme = Resource(library, 'js/pyams-default.js',
minified='js/pyams-default.min.js',
- depends=(bootstrap, myams_js, pyams_default_theme_css),
+ depends=(bootstrap, myams_js_core, pyams_default_theme_css),
bottom=True)
#
--- a/src/pyams_default_theme/component/association/templates/association-remote-content.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/association/templates/association-remote-content.pt Tue Dec 04 15:53:25 2018 +0100
@@ -1,5 +1,7 @@
<tal:var i18n:domain="pyams_default_theme"
- define="settings view.settings">
+ define="settings view.settings">
+ <h2 tal:define="title i18n:context.title"
+ tal:condition="title">${title}</h2>
<tal:loop repeat="link view.links">
<tal:var define="target link.target"
condition="target is not None">
--- a/src/pyams_default_theme/component/illustration/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/illustration/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -24,7 +24,7 @@
from pyams_content.interfaces import IBaseContent
from pyams_content.root import ISiteRoot
from pyams_content.shared.common import ISharedContent
-from pyams_content.shared.site.interfaces import IContentLink
+from pyams_default_theme import lightbox
from pyams_default_theme.component.illustration.interfaces import IIllustrationRenderer, IIllustrationWithZoomSettings, \
ILLUSTRATION_AFTER_BODY, ILLUSTRATION_BEFORE_BODY
from pyams_default_theme.features.renderer import BaseContentRenderer
@@ -35,7 +35,7 @@
from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config, get_annotation_adapter
from pyams_utils.interfaces.tales import ITALESExtension
-from pyams_default_theme import _, lightbox
+from pyams_default_theme import _
#
@@ -84,14 +84,6 @@
return request.registry.queryMultiAdapter((version, request), IContentNavigationIllustration)
-@adapter_config(context=(IContentLink, IPyAMSLayer), provides=IContentNavigationIllustration)
-def content_link_illustration_factory(context, request):
- """Content link illustration factory"""
- target = context.target
- if target is not None:
- return request.registry.queryMultiAdapter((target, request), IContentNavigationIllustration)
-
-
@adapter_config(name='pyams_illustration',
context=(Interface, Interface, Interface),
provides=ITALESExtension)
--- a/src/pyams_default_theme/component/paragraph/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,19 +12,14 @@
__docformat__ = 'restructuredtext'
+from zope.interface import implementer
-# import standard library
-
-# import interfaces
from pyams_content.component.paragraph.interfaces import IBaseParagraph
from pyams_content.features.preview.interfaces import IPreviewView
from pyams_default_theme.layer import IPyAMSDefaultLayer
-from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
-
-# import packages
from pyams_default_theme.page import BasePreviewPage
from pyams_pagelet.pagelet import pagelet_config
-from zope.interface import implementer
+from pyams_utils.interfaces import VIEW_SYSTEM_PERMISSION
@pagelet_config(name='preview.html', context=IBaseParagraph, layer=IPyAMSDefaultLayer,
@@ -46,6 +41,6 @@
def render(self):
if self.renderer is not None:
- return self.renderer.render()
+ return '<div class="edito">{}</div>'.format(self.renderer.render())
else:
return ''
--- a/src/pyams_default_theme/component/paragraph/contact.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/contact.py Tue Dec 04 15:53:25 2018 +0100
@@ -21,6 +21,7 @@
from pyams_content.features.renderer.interfaces import IContentRenderer
from pyams_default_theme.component.paragraph.interfaces.contact import IContactParagraphDefaultRendererSettings
from pyams_default_theme.features.renderer import BaseContentRenderer
+from pyams_i18n.interfaces import II18n
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config, get_annotation_adapter
@@ -87,3 +88,10 @@
else:
context_attrs = ('name', 'photo', 'company', 'address', 'phone_number', 'contact_email')
i18n_context_attrs = ('title', 'charge',)
+
+ @property
+ def button_label(self):
+ label = II18n(self.settings).query_attribute('button_label', request=self.request)
+ if not label:
+ label = self.request.localizer.translate(_("contact-button-label", default="Contact"))
+ return label
--- a/src/pyams_default_theme/component/paragraph/html.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/html.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,13 +12,18 @@
__docformat__ = 'restructuredtext'
+from fanstatic import ConfigurationError
+
from pyams_content.component.illustration import IIllustration
from pyams_content.component.paragraph.interfaces.html import IHTMLParagraph, IRawParagraph
from pyams_content.features.renderer.interfaces import IContentRenderer
+from pyams_default_theme import library
from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
-from pyams_utils.adapter import adapter_config
+from pyams_utils.adapter import adapter_config, get_annotation_adapter
+from pyams_utils.fanstatic import ExternalResource
+from pyams_utils.pygments import IPygmentsCodeConfiguration, PygmentsCodeRendererSettings, render_source
from pyams_default_theme import _
@@ -33,8 +38,51 @@
"""Raw paragraph default renderer"""
label = _("Default raw HTML renderer")
+ weight = 1
- i18n_context_attrs = ('title', 'body',)
+ i18n_context_attrs = ('title', 'body')
+
+
+#
+# Raw paragraph source code renderer
+#
+
+RAW_PARAGRAPH_SOURCE_CODE_RENDERER_SETTINGS_KEY = 'pyams_content.raw.renderer:source-code'
+
+
+@adapter_config(context=IRawParagraph, provides=IPygmentsCodeConfiguration)
+def raw_paragraph_source_code_renderer_settings_factory(context):
+ """Raw paragraph source code renderer settings factory"""
+ return get_annotation_adapter(context, RAW_PARAGRAPH_SOURCE_CODE_RENDERER_SETTINGS_KEY,
+ PygmentsCodeRendererSettings)
+
+
+@adapter_config(name='source-code', context=(IRawParagraph, IPyAMSLayer), provides=IContentRenderer)
+@template_config(template='templates/raw-source-code.pt', layer=IPyAMSLayer)
+class RawParagraphSourceCodeRenderer(BaseContentRenderer):
+ """Raw paragraph source code renderer"""
+
+ label = _("Formatted source code renderer")
+ weight = 10
+
+ settings_interface = IPygmentsCodeConfiguration
+
+ i18n_context_attrs = ('title', 'body')
+
+ @property
+ def resources(self):
+ path = 'get-pygments-style.css?style={}'.format(self.settings.style)
+ try:
+ yield ExternalResource(library, path, resource_type='css')
+ except ConfigurationError:
+ yield library.known_resources[path]
+
+ @property
+ def source(self):
+ code = self.body
+ if code:
+ return render_source(code, self.settings)
+ return ''
#
--- a/src/pyams_default_theme/component/paragraph/interfaces/contact.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/interfaces/contact.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,17 +12,12 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
-# import interfaces
-
-# import packages
-from zope.interface import Interface, Attribute
+from zope.interface import Attribute, Interface
from zope.schema import Bool, Choice
-from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
+from zope.schema.vocabulary import SimpleTerm, SimpleVocabulary
from pyams_i18n.schema import I18nTextLineField
+
from pyams_default_theme import _
@@ -62,7 +57,7 @@
can_display_map = Attribute("Check if location map can be displayed")
- button_label = I18nTextLineField(title=_("Button label"),
- description=_("Label of the navigation button displayed by "
+ button_label = I18nTextLineField(title=_("Contact button label"),
+ description=_("Custom label of the contact button displayed by "
"front-office template"),
required=False)
--- a/src/pyams_default_theme/component/paragraph/portlet/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/portlet/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,24 +12,23 @@
__docformat__ = 'restructuredtext'
-
-# import standard library
-
from zope.interface import Interface
-# import interfaces
from pyams_content.component.paragraph.interfaces import IParagraphContainer
from pyams_content.component.paragraph.portlet.interfaces import IParagraphContainerPortletSettings, \
IParagraphNavigationPortletSettings
from pyams_content.features.renderer.interfaces import ISharedContentRenderer
-from pyams_default_theme import _
+from pyams_content.shared.site.interfaces import ISiteContainer
+from pyams_default_theme.interfaces import IContentSummaryInfo
from pyams_portal.interfaces import IPortalContext, IPortletRenderer
-# import packages
from pyams_portal.portlet import PortletRenderer
+from pyams_sequence.interfaces import IInternalReference, ISequentialIdInfo
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
+from pyams_default_theme import _
+
@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, IParagraphContainerPortletSettings),
provides=IPortletRenderer)
@@ -57,6 +56,36 @@
self.renderers = list(filter(lambda x: x is not None, renderers))
[renderer.update() for renderer in self.renderers]
+ def get_navigation_links(self):
+
+ def test_item(nav_item):
+ item_sequence = ISequentialIdInfo(nav_item, None)
+ if (item_sequence is not None) and (item_sequence.oid == context_sequence.oid):
+ return True
+ if IInternalReference.providedBy(nav_item) and (nav_item.reference == context_sequence.hex_oid):
+ return True
+
+ prev_nav, next_nav = None, None
+ context_sequence = ISequentialIdInfo(self.context, None)
+ if context_sequence is not None:
+ display_context = self.request.display_context
+ if ISiteContainer.providedBy(display_context):
+ registry = self.request.registry
+ previous_item = None
+ items = display_context.get_visible_items(self.request)
+ for item in items:
+ if test_item(item):
+ prev_nav = registry.queryMultiAdapter((previous_item, self.request), IContentSummaryInfo)
+ break
+ previous_item = item
+ try:
+ next_item = next(items)
+ except StopIteration:
+ pass
+ else:
+ next_nav = registry.queryMultiAdapter((next_item, self.request), IContentSummaryInfo)
+ return prev_nav, next_nav
+
@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, IParagraphNavigationPortletSettings),
provides=IPortletRenderer)
--- a/src/pyams_default_theme/component/paragraph/portlet/templates/content.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/portlet/templates/content.pt Tue Dec 04 15:53:25 2018 +0100
@@ -6,4 +6,28 @@
${structure:renderer.render()}
</tal:if>
</tal:loop>
+ <tal:if define="settings view.settings"
+ condition="settings.display_navigation_links">
+ <tal:var define="(previous, next) view.get_navigation_links()"
+ condition="(previous is not None) or (next is not None)">
+ <nav aria-label="Previous and next topics" i18n:attributes="aria-label">
+ <ul class="pager">
+ <li class="previous"
+ tal:condition="previous is not None">
+ <a href="${tales:relative_url(previous.context)}">
+ <span aria-hidden="true">←</span>
+ ${i18n:previous.title}
+ </a>
+ </li>
+ <li class="next"
+ tal:condition="next is not None">
+ <a href="${tales:relative_url(next.context)}">
+ ${i18n:next.title}
+ <span aria-hidden="true">→</span>
+ </a>
+ </li>
+ </ul>
+ </nav>
+ </tal:var>
+ </tal:if>
</div>
--- a/src/pyams_default_theme/component/paragraph/templates/contact-default.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/component/paragraph/templates/contact-default.pt Tue Dec 04 15:53:25 2018 +0100
@@ -23,8 +23,9 @@
</div>
<tal:if condition="view.contact_email">
<span i18n:translate="">Contact email:</span>
- <a href="mailto:${view.contact_email}">
- ${view.contact_email}
+ <a tal:define="button_label view.button_label"
+ href="mailto:${view.contact_email}?subject=${view.title}">
+ ${button_label}
</a><br />
</tal:if>
<tal:if condition="view.phone_number">
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/component/paragraph/templates/raw-source-code.pt Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,9 @@
+<h3>${view.title}</h3>
+<tal:var define="settings view.settings">
+ <div class="source"
+ tal:omit-tag="not settings.disable_wrap">
+ <pre tal:omit-tag="not settings.disable_wrap">
+ ${structure:view.source}
+ </pre>
+ </div>
+</tal:var>
--- a/src/pyams_default_theme/features/header/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/features/header/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -16,6 +16,7 @@
from zope.interface import implementer
from zope.location import Location
from zope.location.interfaces import ISublocations
+from zope.schema.fieldproperty import FieldProperty
from pyams_content.component.association.interfaces import ASSOCIATION_CONTAINER_KEY
from pyams_content.features.header.interfaces import IHeaderSettings, IHeaderTarget
@@ -62,8 +63,14 @@
class SimpleHeaderRendererSettings(Persistent, Location):
"""Simple header renderer settings"""
+ apply_on_root = FieldProperty(ISimpleHeaderRendererSettings['apply_on_root'])
banner = FileProperty(ISimpleHeaderRendererSettings['banner'])
logo = FileProperty(ISimpleHeaderRendererSettings['logo'])
+ search_target = FieldProperty(ISimpleHeaderRendererSettings['search_target'])
+
+ @property
+ def can_apply_on_root(self):
+ return self.apply_on_root
@property
def menus(self):
--- a/src/pyams_default_theme/features/header/interfaces.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/features/header/interfaces.py Tue Dec 04 15:53:25 2018 +0100
@@ -13,9 +13,11 @@
__docformat__ = 'restructuredtext'
from zope.interface import Interface, Attribute
+from zope.schema import Bool
from pyams_content.features.header.interfaces import IHeaderRendererSettings
from pyams_file.schema import ImageField
+from pyams_sequence.schema import InternalReferenceField
from pyams_default_theme import _
@@ -23,6 +25,12 @@
class ISimpleHeaderRendererSettings(IHeaderRendererSettings):
"""Simple header renderer settings"""
+ apply_on_root = Bool(title=_("Apply on root?"),
+ description=_("If 'no', header settings will not be applied on site root but only "
+ "on inner sites"),
+ required=True,
+ default=True)
+
banner = ImageField(title=_("Banner image"),
description=_("Image displayed as header background"),
required=False)
@@ -31,6 +39,10 @@
description=_("Logo displayed in header"),
required=False)
+ search_target = InternalReferenceField(title=_("Search form target"),
+ description=_("Site or folder handling site search"),
+ required=False)
+
tabs = Attribute("Top tabs list")
menus = Attribute("Top tabs menus list")
--- a/src/pyams_default_theme/features/header/skin/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/features/header/skin/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -13,7 +13,6 @@
__docformat__ = 'restructuredtext'
import logging
-logger = logging.getLogger('PyAMS (content)')
from pyramid.decorator import reify
from pyramid.location import lineage
@@ -21,16 +20,18 @@
from pyams_cache.beaker import get_cache
from pyams_content.component.association.interfaces import IAssociationInfo
-from pyams_content.component.links.interfaces import IInternalLink
from pyams_content.features.header.interfaces import IHeaderRenderer, IHeaderRendererSettings, IHeaderSettings, \
IHeaderTarget
from pyams_content.features.renderer.interfaces import HIDDEN_RENDERER_NAME
+from pyams_content.root import ISiteRoot
from pyams_default_theme.features.header import SimpleHeaderRendererSettings
from pyams_default_theme.features.header.interfaces import ISimpleHeaderRendererSettings
from pyams_default_theme.features.header.skin.interfaces import IHeaderClass
from pyams_default_theme.features.renderer import BaseContentRenderer
from pyams_portal.interfaces import PREVIEW_MODE
from pyams_portal.portlet import PORTLETS_CACHE_KEY, PORTLETS_CACHE_NAME, PORTLETS_CACHE_REGION
+from pyams_sequence.interfaces import IInternalReference
+from pyams_sequence.reference import get_reference_target
from pyams_skin.layer import IPyAMSLayer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
@@ -39,6 +40,8 @@
from pyams_default_theme import _
+logger = logging.getLogger('PyAMS (content)')
+
#
# Base header renderer
@@ -80,7 +83,13 @@
request = self.request
return request.registry.queryMultiAdapter((request.context, request), IHeaderClass, default='')
+ @property
+ def search_target(self):
+ return get_reference_target(self.settings.search_target, request=self.request)
+
def render(self):
+ if ISiteRoot.providedBy(self.request.context) and not self.settings.can_apply_on_root:
+ return ''
preview_mode = self.request.annotations.get(PREVIEW_MODE, False)
if preview_mode:
return super(BaseHeaderRenderer, self).render()
@@ -146,7 +155,7 @@
return IAssociationInfo(link)
def is_active(self, link):
- if IInternalLink.providedBy(link):
+ if IInternalReference.providedBy(link):
target = link.get_target()
if target is not None:
return target in self.request.annotations['REQUEST_PATH']
--- a/src/pyams_default_theme/features/header/skin/templates/simple-header.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/features/header/skin/templates/simple-header.pt Tue Dec 04 15:53:25 2018 +0100
@@ -19,16 +19,45 @@
</div>
<div class="collapse navbar-collapse" id="navbar-collapser">
<ul class="nav navbar-nav" role="tablist">
- <tal:loop repeat="link settings.tabs.get_visible_items(request)">
- <li role="presentation"
- tal:attributes="class 'active' if view.is_active(link) else ''">
- <a tal:define="info view.get_link_info(link);
- href link.get_url(request);"
+ <tal:loop repeat="menu settings.menus.get_visible_items(request)">
+ <li tal:condition="menu.reference and not menu.dynamic_menu"
+ tal:attributes="class 'active' if view.is_active(menu) else ''">
+ <a tal:define="info view.get_link_info(menu);
+ href menu.get_url(request);"
tal:condition="href"
href="${href}">${info.user_title}</a>
</li>
+ <li class="dropdown"
+ tal:condition="(not menu.reference) or menu.dynamic_menu">
+ <a href="#" class="dropdown-toggle"
+ data-toggle="dropdown" role="button"
+ aria-haspopup="true" aria-expanded="false">
+ ${i18n:menu.title}
+ <span class="caret"></span>
+ </a>
+ <ul class="dropdown-menu">
+ <tal:loop repeat="link menu.get_visible_items(request)">
+ <li>
+ <a tal:define="info view.get_link_info(link);
+ href link.get_url(request);"
+ tal:condition="href"
+ href="${href}">${info.user_title}</a>
+ </li>
+ </tal:loop>
+ </ul>
+ </li>
</tal:loop>
</ul>
+ <form class="navbar-form navbar-right"
+ tal:define="target view.search_target"
+ tal:condition="target is not None"
+ action="${tales:absolute_url(target)}">
+ <div class="form-group">
+ <input type="text" class="form-control" name="user_search"
+ placeholder="Search..." i18n:attributes="placeholder">
+ </div>
+ <button type="submit" class="btn btn-default" i18n:translate="">Search</button>
+ </form>
</div>
</div>
</nav>
--- a/src/pyams_default_theme/features/menu/portlet/navigation/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/features/menu/portlet/navigation/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,30 +12,34 @@
__docformat__ = 'restructuredtext'
+from persistent import Persistent
+from zope.interface import implementer, Interface
+from zope.location.location import Location
+from zope.schema.fieldproperty import FieldProperty
-# import standard library
-
-# import interfaces
+from pyams_content.component.association.interfaces import IAssociationInfo
from pyams_content.features.menu.portlet.navigation.interfaces.double import IDoubleNavigationPortletSettings
from pyams_content.features.menu.portlet.navigation.interfaces.simple import ISimpleNavigationPortletSettings
from pyams_default_theme.features.menu.portlet.navigation.interfaces import \
IDoubleNavigationPortletSelectMenusRendererSettings
-from pyams_portal.interfaces import IPortalContext, IPortletRenderer, PORTLET_RENDERER_SETTINGS_KEY
+from pyams_portal.interfaces import IPortalContext, IPortletRenderer
+from pyams_portal.portlet import PortletRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from persistent import Persistent
-from pyams_portal.portlet import PortletRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
from pyams_utils.factory import factory_config
-from zope.interface import implementer, Interface
-from zope.location.location import Location
-from zope.schema.fieldproperty import FieldProperty
from pyams_default_theme import _
+class BaseNavigationRenderer(PortletRenderer):
+ """Base navigation portlet renderer"""
+
+ @staticmethod
+ def get_link_info(link):
+ return IAssociationInfo(link)
+
+
#
# Simple navigation portlet renderers
#
@@ -43,20 +47,44 @@
@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, ISimpleNavigationPortletSettings),
provides=IPortletRenderer)
@template_config(template='templates/simple-horizontal.pt', layer=IPyAMSLayer)
-class SimpleNavigationPortletHorizontalRenderer(PortletRenderer):
+class SimpleNavigationPortletHorizontalRenderer(BaseNavigationRenderer):
"""Simple navigation horizontal portlet renderer"""
label = _("Horizontal list with vertical illustrations")
+ weight = 1
@adapter_config(name='horizontal-tabs',
context=(IPortalContext, IPyAMSLayer, Interface, ISimpleNavigationPortletSettings),
provides=IPortletRenderer)
@template_config(template='templates/simple-horizontal-tabs.pt', layer=IPyAMSLayer)
-class SimpleNavigationPortletHorizontalTabsRenderer(PortletRenderer):
+class SimpleNavigationPortletHorizontalTabsRenderer(BaseNavigationRenderer):
"""Simple navigation horizontal portlet renderer with tabs"""
label = _("Horizontal list with tabs and horizontal illustrations")
+ weight = 2
+
+
+@adapter_config(name='carousel',
+ context=(IPortalContext, IPyAMSLayer, Interface, ISimpleNavigationPortletSettings),
+ provides=IPortletRenderer)
+@template_config(template='templates/simple-carousel.pt', layer=IPyAMSLayer)
+class SimpleNavigationPortletCarouselRenderer(BaseNavigationRenderer):
+ """Simple navigation portlet carousel renderer"""
+
+ label = _("Horizontal carousel with full width illustrations")
+ weight = 3
+
+
+@adapter_config(name='vertical-panels',
+ context=(IPortalContext, IPyAMSLayer, Interface, ISimpleNavigationPortletSettings),
+ provides=IPortletRenderer)
+@template_config(template='templates/simple-panels.pt', layer=IPyAMSLayer)
+class SimpleNavigationPortletVerticalPanelsRenderer(BaseNavigationRenderer):
+ """Simple navigation portlet vertical panels renderer"""
+
+ label = _("Vertical panels with panoramic illustrations")
+ weight = 4
#
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-carousel.pt Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,40 @@
+<section class="wrapper" i18n:domain="pyams_default_theme"
+ tal:define="settings view.settings;
+ cache_key tales:cache_key(settings);">
+ <div id="carousel-${cache_key}"
+ class="carousel slide"
+ data-ride="carousel">
+ <ol class="carousel-indicators">
+ <li tal:repeat="link settings.links.get_visible_items()"
+ class="${'active' if repeat.link.start() else None}"
+ data-target="#carousel-${cache_key}"
+ data-slide-to="${repeat.link.index}"></li>
+ </ol>
+ <div class="carousel-inner">
+ <div tal:repeat="link settings.links.get_visible_items()"
+ class="item ${'active' if repeat.link.start() else None}">
+ <tal:var define="illustration tales:pyams_illustration(link);
+ img_data i18n:illustration.data;
+ alt i18n:illustration.alt_title;
+ link_info view.get_link_info(link);">
+ ${structure:tales:picture(img_data, lg_thumb='pano', md_thumb='pano',
+ sm_thumb='pano', xs_thumb='pano', alt=alt)}
+ <a class="carousel-caption"
+ href="${link.get_url(request)}">
+ <h3>${link_info.user_title}</h3>
+ </a>
+ </tal:var>
+ </div>
+ </div>
+ <a class="left carousel-control" role="button"
+ data-target="#carousel-${cache_key}" data-slide="prev">
+ <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
+ <span class="sr-only" i18n:translate="">Previous</span>
+ </a>
+ <a class="right carousel-control" role="button"
+ data-target="#carousel-${cache_key}" data-slide="next">
+ <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
+ <span class="sr-only" i18n:translate="">Next</span>
+ </a>
+ </div>
+</section>
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-panels.pt Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,24 @@
+<div class="panels" i18n:domain="pyams_default_theme"
+ tal:define="settings view.settings">
+ <h2>${i18n:settings.title}</h2>
+ <div tal:repeat="link settings.links.get_visible_items()"
+ class="col-sm-4">
+ <tal:var define="illustration tales:pyams_illustration(link);
+ img_data i18n:illustration.data;
+ alt i18n:illustration.alt_title;
+ link_info view.get_link_info(link);">
+ <a href="${link.get_url(request)}">
+ ${structure:tales:picture(img_data, lg_thumb='pano', lg_width=4, md_thumb='pano', md_width=4,
+ sm_thumb='pano', sm_width=4, xs_thumb='pano', xs_width=4, alt=alt)}
+ </a>
+ <a class="caption"
+ href="${link.get_url(request)}">
+ <h3>${link_info.user_title}</h3>
+ </a>
+ <tal:var define="description i18n:link.description">
+ ${structure:tales:html(description)}
+ </tal:var>
+ </tal:var>
+ </div>
+ <div class="clearfix"></div>
+</div>
\ No newline at end of file
--- a/src/pyams_default_theme/features/search/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/features/search/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -13,10 +13,12 @@
__docformat__ = 'restructuredtext'
from pyams_content.features.search.interfaces import ISearchFolder
+from pyams_content.shared.site import ISiteElementNavigation
from pyams_default_theme.interfaces import IContentSummaryInfo
-from pyams_content.shared.site import ISiteElementNavigation
from pyams_i18n.interfaces import II18n
+from pyams_skin.interfaces.viewlet import IBreadcrumbItem
from pyams_skin.layer import IPyAMSUserLayer
+from pyams_skin.viewlet.breadcrumb import BreadcrumbItem
from pyams_utils.adapter import ContextRequestAdapter, adapter_config
from pyams_utils.interfaces.url import IRelativeURL
from pyams_utils.url import absolute_url
@@ -44,6 +46,17 @@
return IWorkflowPublicationInfo(self.context).is_visible(self.request)
+@adapter_config(context=(ISearchFolder, IPyAMSUserLayer), provides=IBreadcrumbItem)
+class SearchFolderBreadcumbAdapter(BreadcrumbItem):
+ """Search folder breadcrumb adapter"""
+
+ @property
+ def label(self):
+ return II18n(self.context).query_attribute('short_name', request=self.request)
+
+ url = None
+
+
@adapter_config(context=(ISearchFolder, IPyAMSUserLayer), provides=IContentSummaryInfo)
class SearchFolderSummaryAdapter(ContextRequestAdapter):
"""Search folder summary adapter"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/search/portlet/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,65 @@
+#
+# 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'
+
+from persistent import Persistent
+from zope.container.contained import Contained
+from zope.interface import Interface, implementer
+from zope.location import ILocation
+from zope.schema.fieldproperty import FieldProperty
+
+from pyams_content.features.search.portlet import ISearchResultsPortletSettings
+from pyams_default_theme.features.search.portlet.interfaces import ISearchResultsPortletDefaultRendererSettings
+from pyams_default_theme.interfaces import ISearchResultsView
+from pyams_portal.interfaces import IPortalContext, IPortletRenderer
+from pyams_portal.portlet import PortletRenderer
+from pyams_skin.interfaces.viewlet import IBreadcrumbs
+from pyams_skin.layer import IPyAMSLayer, IPyAMSUserLayer
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config, NullAdapter
+from pyams_utils.factory import factory_config
+
+from pyams_default_theme import _
+
+
+@implementer(ISearchResultsPortletDefaultRendererSettings)
+@factory_config(provided=ISearchResultsPortletDefaultRendererSettings)
+class SearchResultsPortletDefaultRendererSettings(Persistent, Contained):
+ """Search results portlet default renderer settings"""
+
+ display_results_count = FieldProperty(ISearchResultsPortletDefaultRendererSettings['display_results_count'])
+ allow_sorting = FieldProperty(ISearchResultsPortletDefaultRendererSettings['allow_sorting'])
+ allow_pagination = FieldProperty(ISearchResultsPortletDefaultRendererSettings['allow_pagination'])
+
+
+@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, ISearchResultsPortletSettings),
+ provides=IPortletRenderer)
+@template_config(template='templates/search-results.pt', layer=IPyAMSLayer)
+@implementer(ISearchResultsView)
+class SearchResultsPortletDefaultRenderer(PortletRenderer):
+ """Search results portlet default renderer"""
+
+ label = _("Default search results")
+
+ settings_interface = ISearchResultsPortletDefaultRendererSettings
+
+ def update(self):
+ settings = self.renderer_settings
+ if not settings.allow_pagination:
+ self.request.GET['length'] = '999'
+ super(SearchResultsPortletDefaultRenderer, self).update()
+
+
+@adapter_config(context=(ILocation, IPyAMSUserLayer, ISearchResultsView), provides=IBreadcrumbs)
+class BreadcrumbsAdapter(NullAdapter):
+ """Disable breadcrumbs in search results view"""
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/search/portlet/interfaces.py Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,37 @@
+#
+# 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'
+
+from zope.interface import Interface
+from zope.schema import Bool
+
+from pyams_default_theme import _
+
+
+class ISearchResultsPortletDefaultRendererSettings(Interface):
+ """Search results portlet default renderer settings interface"""
+
+ display_results_count = Bool(title=_("Display results count?"),
+ description=_("If 'no', results count will not be displayed"),
+ required=True,
+ default=True)
+
+ allow_sorting = Bool(title=_("Allow results sorting?"),
+ description=_("If 'no', results will not be sortable"),
+ required=True,
+ default=True)
+
+ allow_pagination = Bool(title=_("Allow pagination?"),
+ description=_("If 'no', results will not be paginated"),
+ required=True,
+ default=True)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/search/portlet/templates/search-results.pt Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,49 @@
+<div tal:define="settings view.settings;
+ renderer_settings view.renderer_settings;"
+ i18n:domain="pyams_default_theme">
+ <h2>${i18n:settings.title}</h2>
+ <div class="search-results"
+ tal:define="(items, count) settings.get_items(request)">
+ <header>
+ <tal:if condition="renderer_settings.display_results_count">
+ <div>
+ <tal:if condition="count" i18n:translate="">
+ <i18n:var name="count">${count}</i18n:var> result(s) found
+ </tal:if>
+ <tal:if condition="not:count" i18n:translate="">
+ No result found!
+ </tal:if>
+ </div>
+ </tal:if>
+ <hr />
+ </header>
+ <tal:loop repeat="item items">
+ <tal:var define="target tales:relative_url(item)">
+ <div class="thumbnail pull-left col-lg-3 col-md-3 col-sm-4 hidden-xs"
+ tal:define="illustration tales:pyams_illustration(item)"
+ tal:condition="illustration">
+ <a href="${target}">
+ <tal:if define="image i18n:illustration.data;
+ alt i18n:illustration.alt_title;"
+ condition="image">
+ ${structure:tales:picture(image, lg_thumb='pano', lg_width=3, md_thumb='pano', md_width=3, sm_thumb='pano',
+ sm_width=4, xs_thumb='pano', xs_width=12, alt=alt, css_class='result_media')}
+ </tal:if>
+ </a>
+ </div>
+ <div>
+ <a href="${target}">
+ <h3>${i18n:item.title}</h3>
+ </a>
+ <div class="breadcrumbs">${structure:tales:breadcrumbs(item)}</div>
+ <div class="tags">${structure:tales:tags(item)}</div>
+ <div class="header"
+ tal:define="header i18n:item.header">
+ ${structure:tales:html(header)}
+ </div>
+ </div>
+ </tal:var>
+ <div class="clearfix"></div>
+ </tal:loop>
+ </div>
+</div>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/share/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,15 @@
+#
+# 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'
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/share/portlet/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -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'
+
+from zope.interface import Interface
+
+from pyams_content.features.share.interfaces import ISocialShareManager
+from pyams_content.features.share.portlet import IToolboxPortletSettings
+from pyams_portal.interfaces import IPortalContext, IPortletRenderer
+from pyams_portal.portlet import PortletRenderer
+from pyams_skin import awesomefonts_css
+from pyams_skin.layer import IPyAMSLayer
+from pyams_template.template import template_config
+from pyams_utils.adapter import adapter_config
+
+from pyams_default_theme import _
+
+
+@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, IToolboxPortletSettings),
+ provides=IPortletRenderer)
+@template_config(template='templates/toolbox.pt', layer=IPyAMSLayer)
+class ToolboxPortletDefaultRenderer(PortletRenderer):
+ """Toolbox portlet renderer"""
+
+ label = _("Default toolbox")
+
+ resources = (awesomefonts_css,)
+
+ @property
+ def social_items(self):
+ manager = ISocialShareManager(self.request.root, None)
+ if manager is not None:
+ yield from manager.get_active_items()
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/features/share/portlet/templates/toolbox.pt Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,28 @@
+<div class="toolbox btn-group btn-group-vertical" i18n:domain="pyams_default_theme"
+ tal:define="settings view.settings">
+
+ <button tal:condition="settings.allow_printing"
+ type="button" class="btn btn-default hidden-xs hidden-sm"
+ onclick="javascript:window.print();"
+ title="Print page" i18n:attributes="title">
+ <i class="fa fa-fw fa-print"></i>
+ <span i18n:translate="">Print page</span>
+ </button>
+
+ <tal:if condition="settings.allow_sharing">
+ <tal:loop repeat="item view.social_items">
+ <tal:var define="url item.get_url(context, request)">
+ <button type="button" class="btn btn-default hidden-xs hidden-sm"
+ title="${i18n:item.label}"
+ onclick="javascript:window.location.href='${url}';">
+ <i class="fa fa-fw"
+ tal:define="pictogram i18n:item.pictogram.image">
+ ${structure:tales:thumbnail(pictogram, '2rem', '2rem')}
+ </i>
+ <span>${i18n:item.label}</span>
+ </button>
+ </tal:var>
+ </tal:loop>
+ </tal:if>
+
+</div>
\ No newline at end of file
--- a/src/pyams_default_theme/interfaces/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/interfaces/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -49,3 +49,7 @@
header = Attribute("Header")
button_title = Attribute("Button's target")
+
+
+class ISearchResultsView(Interface):
+ """Search results view marker interface"""
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 Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/locales/fr/LC_MESSAGES/pyams_default_theme.po Tue Dec 04 15:53:25 2018 +0100
@@ -5,7 +5,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-11-16 10:59+0100\n"
+"POT-Creation-Date: 2018-11-30 11:12+0100\n"
"PO-Revision-Date: 2017-06-07 12:41+0200\n"
"Last-Translator: Thierry Florac <tflorac@ulthar.net>\n"
"Language-Team: French\n"
@@ -24,15 +24,19 @@
msgid "Default grid gallery renderer"
msgstr "Par défaut"
-#: src/pyams_default_theme/component/gallery/__init__.py:43
+#: src/pyams_default_theme/component/gallery/__init__.py:46
msgid "Carousel gallery renderer"
msgstr "Carousel horizontal"
-#: src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:31
+#: src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:32
+#: src/pyams_default_theme/shared/view/portlet/templates/view-items-list.pt:47
+#: src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-carousel.pt:32
msgid "Previous"
msgstr "Précédent"
-#: src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:35
+#: src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:36
+#: src/pyams_default_theme/shared/view/portlet/templates/view-items-list.pt:53
+#: src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-carousel.pt:37
msgid "Next"
msgstr "Suivant"
@@ -48,19 +52,19 @@
msgid "Vertical list"
msgstr "Liste verticale"
-#: src/pyams_default_theme/component/illustration/__init__.py:170
+#: src/pyams_default_theme/component/illustration/__init__.py:162
msgid "Centered illustration before text"
msgstr "Illustration centrée avant le texte"
-#: src/pyams_default_theme/component/illustration/__init__.py:181
+#: src/pyams_default_theme/component/illustration/__init__.py:173
msgid "Small illustration on the left"
msgstr "Illustration sur la gauche"
-#: src/pyams_default_theme/component/illustration/__init__.py:193
+#: src/pyams_default_theme/component/illustration/__init__.py:187
msgid "Small illustration on the right"
msgstr "Illustration sur la droite"
-#: src/pyams_default_theme/component/illustration/__init__.py:205
+#: src/pyams_default_theme/component/illustration/__init__.py:201
msgid "Centered illustration after text"
msgstr "Illustration centrée après le texte"
@@ -117,30 +121,43 @@
msgid "Default verbatim renderer"
msgstr "Encadré en pleine largeur (par défaut)"
-#: src/pyams_default_theme/component/paragraph/html.py:35
+#: src/pyams_default_theme/component/paragraph/html.py:40
msgid "Default raw HTML renderer"
-msgstr "Par défaut"
+msgstr "Code HTML brut (par défaut)"
-#: src/pyams_default_theme/component/paragraph/html.py:49
+#: src/pyams_default_theme/component/paragraph/html.py:65
+msgid "Formatted source code renderer"
+msgstr "Code source formatté"
+
+#: src/pyams_default_theme/component/paragraph/html.py:97
msgid "Default rich text renderer"
msgstr "Par défaut"
-#: src/pyams_default_theme/component/paragraph/contact.py:80
+#: src/pyams_default_theme/component/paragraph/contact.py:82
msgid "Default contact renderer"
msgstr "Encadré en pleine largeur (par défaut)"
+#. Default: Contact
+#: src/pyams_default_theme/component/paragraph/contact.py:96
+msgid "contact-button-label"
+msgstr "Contacter"
+
#: src/pyams_default_theme/component/paragraph/zmi/map.py:62
msgid "Don't use default map configuration"
msgstr "Ne pas utiliser la configuration de carte par défaut"
-#: src/pyams_default_theme/component/paragraph/portlet/__init__.py:40
+#: src/pyams_default_theme/component/paragraph/portlet/__init__.py:39
msgid "Default paragraphs renderer"
msgstr "Par défaut"
-#: src/pyams_default_theme/component/paragraph/portlet/__init__.py:67
+#: src/pyams_default_theme/component/paragraph/portlet/__init__.py:96
msgid "Default paragraphs navigation"
msgstr "Par défaut"
+#: src/pyams_default_theme/component/paragraph/portlet/templates/content.pt:13
+msgid "Previous and next topics"
+msgstr "Contenus précédent et suivant"
+
#: src/pyams_default_theme/component/paragraph/interfaces/map.py:34
msgid "Don't use default configuration?"
msgstr "Ne pas utiliser la configuration par défaut ?"
@@ -151,13 +168,13 @@
#: src/pyams_default_theme/component/paragraph/interfaces/frame.py:25
#: src/pyams_default_theme/component/paragraph/interfaces/verbatim.py:22
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:29
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:25
msgid "Left"
msgstr "Gauche"
#: src/pyams_default_theme/component/paragraph/interfaces/frame.py:26
#: src/pyams_default_theme/component/paragraph/interfaces/verbatim.py:23
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:30
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:26
msgid "Right"
msgstr "Droite"
@@ -207,34 +224,44 @@
"Cette largeur est indiquée en nombre de colonnes, la largeur totale étant de "
"12 colonnes."
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:40
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:36
msgid "Show photo?"
msgstr "Afficher la photo ?"
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:41
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:37
msgid "Display contact photo"
msgstr ""
"Si 'non', la photo du contact ne sera pas affichée même si elle est "
"disponible"
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:45
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:41
msgid "Photo position"
msgstr "Position de la photo"
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:52
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:48
msgid "Show location map?"
msgstr "Afficher la carte ?"
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:53
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:49
msgid "If 'no', location map will not be displayed"
msgstr ""
"Si 'non', la carte de situation ne sera pas affichée même si des coordonnées "
"GPS ont été indiquées"
-#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:57
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:53
msgid "Map position"
msgstr "Position de la carte"
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:60
+msgid "Contact button label"
+msgstr "Libellé du bouton de contact"
+
+#: src/pyams_default_theme/component/paragraph/interfaces/contact.py:61
+msgid "Custom label of the contact button displayed by front-office template"
+msgstr ""
+"Vous pouvez remplacer le libellé par défaut du bouton de contact qui sera "
+"affiché en front-office en l'indiquant ici"
+
#: src/pyams_default_theme/component/association/__init__.py:44
msgid "Default associations renderer"
msgstr "Par défaut"
@@ -282,7 +309,8 @@
"sélectionnés"
#: src/pyams_default_theme/shared/common/summary.py:38
-#: src/pyams_default_theme/shared/site/link.py:64
+#: src/pyams_default_theme/shared/site/link.py:70
+#: src/pyams_default_theme/shared/site/link.py:108
msgid "Consult content"
msgstr "Accéder au contenu"
@@ -290,7 +318,7 @@
msgid "Default title renderer"
msgstr "Par défaut"
-#: src/pyams_default_theme/shared/common/portlet/head.py:38
+#: src/pyams_default_theme/shared/common/portlet/head.py:33
msgid "Default header renderer"
msgstr "Par défaut"
@@ -304,10 +332,35 @@
"ATTENTION : la sélection des éléments affichés dans cet aperçu ne tient pas "
"compte du contexte éventuellement paramétré dans la vue"
-#: src/pyams_default_theme/shared/view/portlet/__init__.py:38
+#: src/pyams_default_theme/shared/view/portlet/__init__.py:48
msgid "Simple vertical view"
msgstr "Liste verticale simple"
+#: src/pyams_default_theme/shared/view/portlet/interfaces.py:24
+msgid "Display illustrations?"
+msgstr "Afficher les illustrations ?"
+
+#: src/pyams_default_theme/shared/view/portlet/interfaces.py:25
+msgid "If 'no', view contents will not display illustrations"
+msgstr "Si 'non', l'illustration associée aux contenus ne sera pas affichée"
+
+#: src/pyams_default_theme/shared/view/portlet/interfaces.py:29
+msgid "Paginate?"
+msgstr "Pagination ?"
+
+#: src/pyams_default_theme/shared/view/portlet/interfaces.py:30
+msgid "If 'no', results pagination will be disabled"
+msgstr ""
+"Si 'non', les résultats de la recherche ne seront pas oraganisés par pages"
+
+#: src/pyams_default_theme/shared/view/portlet/interfaces.py:34
+msgid "Page size"
+msgstr "Taille des pages"
+
+#: src/pyams_default_theme/shared/view/portlet/interfaces.py:35
+msgid "Number of items per page, if pagination is enabled"
+msgstr "Nombre de résultats par page, si la pagination est activée"
+
#: src/pyams_default_theme/shared/imagemap/__init__.py:52
msgid "Default imagemap renderer"
msgstr "Par défaut"
@@ -317,14 +370,19 @@
msgstr "Aperçu des zones cliquables"
#: src/pyams_default_theme/shared/site/folder.py:60
-#: src/pyams_default_theme/features/search/__init__.py:64
+#: src/pyams_default_theme/features/search/__init__.py:77
msgid "Consult folder"
msgstr "Consulter la rubrique"
-#: src/pyams_default_theme/shared/site/portlet/__init__.py:35
+#: src/pyams_default_theme/shared/site/portlet/__init__.py:48
msgid "Site container summary"
msgstr "Par défaut"
+#: src/pyams_default_theme/shared/site/portlet/__init__.py:58
+#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:86
+msgid "Vertical panels with panoramic illustrations"
+msgstr "Panneaux verticaux avec illustrations panoramiques"
+
#: src/pyams_default_theme/shared/logo/__init__.py:34
msgid "Default logos renderer"
msgstr "Par défaut"
@@ -337,19 +395,32 @@
msgid "Hidden content"
msgstr "NON affiché"
-#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:49
+#: src/pyams_default_theme/features/share/portlet/__init__.py:35
+msgid "Default toolbox"
+msgstr "Par défaut"
+
+#: src/pyams_default_theme/features/share/portlet/templates/toolbox.pt:7
+#: src/pyams_default_theme/features/share/portlet/templates/toolbox.pt:9
+msgid "Print page"
+msgstr "Imprimer la page"
+
+#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:53
msgid "Horizontal list with vertical illustrations"
msgstr "Liste horizontale avec illustrations verticales (par défaut)"
-#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:59
+#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:64
msgid "Horizontal list with tabs and horizontal illustrations"
msgstr "Liste horizontale avec onglets et illustrations panoramiques"
-#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:72
+#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:75
+msgid "Horizontal carousel with full width illustrations"
+msgstr "Carousel horizontal avec illustrations en pleine largeur"
+
+#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:100
msgid "Vertical list with small horizontal menus illustrations"
msgstr "Liste verticale avec illustrations horizontales"
-#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:95
+#: src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:123
msgid "Double-level selection navigation"
msgstr "Navigation par sélection à deux niveaux"
@@ -389,31 +460,87 @@
msgid "PyAMS simple footer with links"
msgstr "PyAMS: pied de page simple avec liens"
-#: src/pyams_default_theme/features/header/interfaces.py:31
+#: src/pyams_default_theme/features/search/portlet/__init__.py:52
+msgid "Default search results"
+msgstr "Affichage des résultats, sans facette (par défaut)"
+
+#: src/pyams_default_theme/features/search/portlet/interfaces.py:24
+msgid "Display results count?"
+msgstr "Afficher le nombre de résultats ?"
+
+#: src/pyams_default_theme/features/search/portlet/interfaces.py:25
+msgid "If 'no', results count will not be displayed"
+msgstr "Si 'non', le nombre de résultats ne sera pas affiché"
+
+#: src/pyams_default_theme/features/search/portlet/interfaces.py:29
+msgid "Allow results sorting?"
+msgstr "Autoriser le tri ?"
+
+#: src/pyams_default_theme/features/search/portlet/interfaces.py:30
+msgid "If 'no', results will not be sortable"
+msgstr "Si 'non', les résultats ne pourront pas être triés par l'utilisateur"
+
+#: src/pyams_default_theme/features/search/portlet/interfaces.py:34
+msgid "Allow pagination?"
+msgstr "Autoriser la pagination ?"
+
+#: src/pyams_default_theme/features/search/portlet/interfaces.py:35
+msgid "If 'no', results will not be paginated"
+msgstr "Si 'non', les résultats seront affichés sur une seule page"
+
+#: src/pyams_default_theme/features/search/portlet/templates/search-results.pt:10
+msgid "${count} result(s) found"
+msgstr "${count} résultat(s) trouvé(s)"
+
+#: src/pyams_default_theme/features/search/portlet/templates/search-results.pt:13
+msgid "No result found!"
+msgstr "Aucun résultat."
+
+#: src/pyams_default_theme/features/header/interfaces.py:28
+msgid "Apply on root?"
+msgstr "Appliquer sur l'accueil ?"
+
+#: src/pyams_default_theme/features/header/interfaces.py:29
+msgid ""
+"If 'no', header settings will not be applied on site root but only on inner "
+"sites"
+msgstr ""
+"Si 'non', l'en-tête de page ne sera pas utilisé à l'accueil du site, mais "
+"pourra être hérité dans les pages intérieures"
+
+#: src/pyams_default_theme/features/header/interfaces.py:34
msgid "Banner image"
msgstr "Bandeau"
-#: src/pyams_default_theme/features/header/interfaces.py:32
+#: src/pyams_default_theme/features/header/interfaces.py:35
msgid "Image displayed as header background"
msgstr "Image affichée en tête de page"
-#: src/pyams_default_theme/features/header/interfaces.py:35
+#: src/pyams_default_theme/features/header/interfaces.py:38
msgid "Logo"
msgstr "Logo"
-#: src/pyams_default_theme/features/header/interfaces.py:36
+#: src/pyams_default_theme/features/header/interfaces.py:39
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/interfaces.py:42
+msgid "Search form target"
+msgstr "Cible de la recherche"
-#: src/pyams_default_theme/features/header/skin/__init__.py:111
+#: src/pyams_default_theme/features/header/interfaces.py:43
+msgid "Site or folder handling site search"
+msgstr "Site ou rubrique qui prend en charge la recherche"
+
+#: src/pyams_default_theme/features/header/zmi/__init__.py:70
+msgid "Top menus"
+msgstr "Menus de navigation"
+
+#: src/pyams_default_theme/features/header/skin/__init__.py:120
msgid "Hidden header"
msgstr "NON affiché"
-#: src/pyams_default_theme/features/header/skin/__init__.py:134
+#: src/pyams_default_theme/features/header/skin/__init__.py:143
msgid "PyAMS simple header with banner and tabs"
msgstr "PyAMS: en-tête simple avec bandeau et onglets de navigation"
@@ -421,17 +548,22 @@
msgid "Toggle navigation"
msgstr "Menu de navigation"
-#~ msgid "Show illustration?"
-#~ msgstr "Afficher l'illustration ?"
+#: src/pyams_default_theme/features/header/skin/templates/simple-header.pt:57
+msgid "Search..."
+msgstr "Recherche..."
+
+#: src/pyams_default_theme/features/header/skin/templates/simple-header.pt:59
+msgid "Search"
+msgstr "Chercher"
+
+#~ msgid "Top tabs"
+#~ msgstr "Onglets de navigation"
#~ msgid "If 'no', illustration will not be displayed"
#~ msgstr ""
#~ "Si 'non', l'illustration ne sera pas affichée même si un contenu a été "
#~ "fourni"
-#~ msgid "Search..."
-#~ msgstr "Chercher..."
-
#~ msgid "Hide menu"
#~ msgstr "Masquer le menu"
--- a/src/pyams_default_theme/locales/pyams_default_theme.pot Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/locales/pyams_default_theme.pot Tue Dec 04 15:53:25 2018 +0100
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE 1.0\n"
-"POT-Creation-Date: 2018-11-16 10:59+0100\n"
+"POT-Creation-Date: 2018-11-30 11:12+0100\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"
@@ -24,15 +24,19 @@
msgid "Default grid gallery renderer"
msgstr ""
-#: ./src/pyams_default_theme/component/gallery/__init__.py:43
+#: ./src/pyams_default_theme/component/gallery/__init__.py:46
msgid "Carousel gallery renderer"
msgstr ""
-#: ./src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:31
+#: ./src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:32
+#: ./src/pyams_default_theme/shared/view/portlet/templates/view-items-list.pt:47
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-carousel.pt:32
msgid "Previous"
msgstr ""
-#: ./src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:35
+#: ./src/pyams_default_theme/component/gallery/templates/renderer-carousel.pt:36
+#: ./src/pyams_default_theme/shared/view/portlet/templates/view-items-list.pt:53
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/templates/simple-carousel.pt:37
msgid "Next"
msgstr ""
@@ -48,19 +52,19 @@
msgid "Vertical list"
msgstr ""
-#: ./src/pyams_default_theme/component/illustration/__init__.py:170
+#: ./src/pyams_default_theme/component/illustration/__init__.py:162
msgid "Centered illustration before text"
msgstr ""
-#: ./src/pyams_default_theme/component/illustration/__init__.py:181
+#: ./src/pyams_default_theme/component/illustration/__init__.py:173
msgid "Small illustration on the left"
msgstr ""
-#: ./src/pyams_default_theme/component/illustration/__init__.py:193
+#: ./src/pyams_default_theme/component/illustration/__init__.py:187
msgid "Small illustration on the right"
msgstr ""
-#: ./src/pyams_default_theme/component/illustration/__init__.py:205
+#: ./src/pyams_default_theme/component/illustration/__init__.py:201
msgid "Centered illustration after text"
msgstr ""
@@ -115,30 +119,43 @@
msgid "Default verbatim renderer"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/html.py:35
+#: ./src/pyams_default_theme/component/paragraph/html.py:40
msgid "Default raw HTML renderer"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/html.py:49
+#: ./src/pyams_default_theme/component/paragraph/html.py:65
+msgid "Formatted source code renderer"
+msgstr ""
+
+#: ./src/pyams_default_theme/component/paragraph/html.py:97
msgid "Default rich text renderer"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/contact.py:80
+#: ./src/pyams_default_theme/component/paragraph/contact.py:82
msgid "Default contact renderer"
msgstr ""
+#. Default: Contact
+#: ./src/pyams_default_theme/component/paragraph/contact.py:96
+msgid "contact-button-label"
+msgstr ""
+
#: ./src/pyams_default_theme/component/paragraph/zmi/map.py:62
msgid "Don't use default map configuration"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/portlet/__init__.py:40
+#: ./src/pyams_default_theme/component/paragraph/portlet/__init__.py:39
msgid "Default paragraphs renderer"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/portlet/__init__.py:67
+#: ./src/pyams_default_theme/component/paragraph/portlet/__init__.py:96
msgid "Default paragraphs navigation"
msgstr ""
+#: ./src/pyams_default_theme/component/paragraph/portlet/templates/content.pt:13
+msgid "Previous and next topics"
+msgstr ""
+
#: ./src/pyams_default_theme/component/paragraph/interfaces/map.py:34
msgid "Don't use default configuration?"
msgstr ""
@@ -149,13 +166,13 @@
#: ./src/pyams_default_theme/component/paragraph/interfaces/frame.py:25
#: ./src/pyams_default_theme/component/paragraph/interfaces/verbatim.py:22
-#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:29
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:25
msgid "Left"
msgstr ""
#: ./src/pyams_default_theme/component/paragraph/interfaces/frame.py:26
#: ./src/pyams_default_theme/component/paragraph/interfaces/verbatim.py:23
-#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:30
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:26
msgid "Right"
msgstr ""
@@ -197,28 +214,36 @@
"columns count; full width counts for 12 columns"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:40
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:36
msgid "Show photo?"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:41
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:37
msgid "Display contact photo"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:45
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:41
msgid "Photo position"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:52
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:48
msgid "Show location map?"
msgstr ""
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:49
+msgid "If 'no', location map will not be displayed"
+msgstr ""
+
#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:53
-msgid "If 'no', location map will not be displayed"
+msgid "Map position"
msgstr ""
-#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:57
-msgid "Map position"
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:60
+msgid "Contact button label"
+msgstr ""
+
+#: ./src/pyams_default_theme/component/paragraph/interfaces/contact.py:61
+msgid "Custom label of the contact button displayed by front-office template"
msgstr ""
#: ./src/pyams_default_theme/component/association/__init__.py:44
@@ -264,7 +289,8 @@
msgstr ""
#: ./src/pyams_default_theme/shared/common/summary.py:38
-#: ./src/pyams_default_theme/shared/site/link.py:64
+#: ./src/pyams_default_theme/shared/site/link.py:70
+#: ./src/pyams_default_theme/shared/site/link.py:108
msgid "Consult content"
msgstr ""
@@ -272,7 +298,7 @@
msgid "Default title renderer"
msgstr ""
-#: ./src/pyams_default_theme/shared/common/portlet/head.py:38
+#: ./src/pyams_default_theme/shared/common/portlet/head.py:33
msgid "Default header renderer"
msgstr ""
@@ -284,10 +310,34 @@
msgid "WARNING: items displayed in this preview are out of context!!"
msgstr ""
-#: ./src/pyams_default_theme/shared/view/portlet/__init__.py:38
+#: ./src/pyams_default_theme/shared/view/portlet/__init__.py:48
msgid "Simple vertical view"
msgstr ""
+#: ./src/pyams_default_theme/shared/view/portlet/interfaces.py:24
+msgid "Display illustrations?"
+msgstr ""
+
+#: ./src/pyams_default_theme/shared/view/portlet/interfaces.py:25
+msgid "If 'no', view contents will not display illustrations"
+msgstr ""
+
+#: ./src/pyams_default_theme/shared/view/portlet/interfaces.py:29
+msgid "Paginate?"
+msgstr ""
+
+#: ./src/pyams_default_theme/shared/view/portlet/interfaces.py:30
+msgid "If 'no', results pagination will be disabled"
+msgstr ""
+
+#: ./src/pyams_default_theme/shared/view/portlet/interfaces.py:34
+msgid "Page size"
+msgstr ""
+
+#: ./src/pyams_default_theme/shared/view/portlet/interfaces.py:35
+msgid "Number of items per page, if pagination is enabled"
+msgstr ""
+
#: ./src/pyams_default_theme/shared/imagemap/__init__.py:52
msgid "Default imagemap renderer"
msgstr ""
@@ -297,14 +347,19 @@
msgstr ""
#: ./src/pyams_default_theme/shared/site/folder.py:60
-#: ./src/pyams_default_theme/features/search/__init__.py:64
+#: ./src/pyams_default_theme/features/search/__init__.py:77
msgid "Consult folder"
msgstr ""
-#: ./src/pyams_default_theme/shared/site/portlet/__init__.py:35
+#: ./src/pyams_default_theme/shared/site/portlet/__init__.py:48
msgid "Site container summary"
msgstr ""
+#: ./src/pyams_default_theme/shared/site/portlet/__init__.py:58
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:86
+msgid "Vertical panels with panoramic illustrations"
+msgstr ""
+
#: ./src/pyams_default_theme/shared/logo/__init__.py:34
msgid "Default logos renderer"
msgstr ""
@@ -317,19 +372,32 @@
msgid "Hidden content"
msgstr ""
-#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:49
+#: ./src/pyams_default_theme/features/share/portlet/__init__.py:35
+msgid "Default toolbox"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/share/portlet/templates/toolbox.pt:7
+#: ./src/pyams_default_theme/features/share/portlet/templates/toolbox.pt:9
+msgid "Print page"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:53
msgid "Horizontal list with vertical illustrations"
msgstr ""
-#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:59
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:64
msgid "Horizontal list with tabs and horizontal illustrations"
msgstr ""
-#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:72
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:75
+msgid "Horizontal carousel with full width illustrations"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:100
msgid "Vertical list with small horizontal menus illustrations"
msgstr ""
-#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:95
+#: ./src/pyams_default_theme/features/menu/portlet/navigation/__init__.py:123
msgid "Double-level selection navigation"
msgstr ""
@@ -369,34 +437,96 @@
msgid "PyAMS simple footer with links"
msgstr ""
-#: ./src/pyams_default_theme/features/header/interfaces.py:31
+#: ./src/pyams_default_theme/features/search/portlet/__init__.py:52
+msgid "Default search results"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/interfaces.py:24
+msgid "Display results count?"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/interfaces.py:25
+msgid "If 'no', results count will not be displayed"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/interfaces.py:29
+msgid "Allow results sorting?"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/interfaces.py:30
+msgid "If 'no', results will not be sortable"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/interfaces.py:34
+msgid "Allow pagination?"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/interfaces.py:35
+msgid "If 'no', results will not be paginated"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/templates/search-results.pt:10
+msgid "${count} result(s) found"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/search/portlet/templates/search-results.pt:13
+msgid "No result found!"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/interfaces.py:28
+msgid "Apply on root?"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/interfaces.py:29
+msgid ""
+"If 'no', header settings will not be applied on site root but only on inner "
+"sites"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/interfaces.py:34
msgid "Banner image"
msgstr ""
-#: ./src/pyams_default_theme/features/header/interfaces.py:32
+#: ./src/pyams_default_theme/features/header/interfaces.py:35
msgid "Image displayed as header background"
msgstr ""
-#: ./src/pyams_default_theme/features/header/interfaces.py:35
+#: ./src/pyams_default_theme/features/header/interfaces.py:38
msgid "Logo"
msgstr ""
-#: ./src/pyams_default_theme/features/header/interfaces.py:36
+#: ./src/pyams_default_theme/features/header/interfaces.py:39
msgid "Logo displayed in header"
msgstr ""
-#: ./src/pyams_default_theme/features/header/zmi/__init__.py:81
-msgid "Top tabs"
+#: ./src/pyams_default_theme/features/header/interfaces.py:42
+msgid "Search form target"
msgstr ""
-#: ./src/pyams_default_theme/features/header/skin/__init__.py:111
+#: ./src/pyams_default_theme/features/header/interfaces.py:43
+msgid "Site or folder handling site search"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/zmi/__init__.py:70
+msgid "Top menus"
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/skin/__init__.py:120
msgid "Hidden header"
msgstr ""
-#: ./src/pyams_default_theme/features/header/skin/__init__.py:134
+#: ./src/pyams_default_theme/features/header/skin/__init__.py:143
msgid "PyAMS simple header with banner and tabs"
msgstr ""
#: ./src/pyams_default_theme/features/header/skin/templates/simple-header.pt:13
msgid "Toggle navigation"
msgstr ""
+
+#: ./src/pyams_default_theme/features/header/skin/templates/simple-header.pt:57
+msgid "Search..."
+msgstr ""
+
+#: ./src/pyams_default_theme/features/header/skin/templates/simple-header.pt:59
+msgid "Search"
+msgstr ""
--- a/src/pyams_default_theme/resources/css/pyams-default.css Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/resources/css/pyams-default.css Tue Dec 04 15:53:25 2018 +0100
@@ -13,59 +13,7 @@
body {
font-family: Lato, Helvetica, Arial, sans-serif;
margin: 0 auto;
-}
-body .header-simple .regularbanner {
- position: relative;
-}
-body .header-simple .regularbanner picture.regularbanner__media,
-body .header-simple .regularbanner img.regularbanner__media {
- width: 100%;
-}
-body .header-simple .regularbanner picture.logo,
-body .header-simple .regularbanner img.logo {
- position: absolute;
- top: 10px;
- left: 10px;
- max-height: calc(100% - 20px);
-}
-body .affix {
- top: 0;
- width: 100%;
- z-index: 9999 !important;
- opacity: 0.95;
- transition: all 0.5s ease-in-out;
-}
-body .affix ~ .container-fluid {
- position: relative;
- top: 50px;
-}
-body .navbar {
- margin-bottom: 20px;
- background-color: white;
- border: 1px solid #39413b;
- font-family: Oswald, Helvetica, Arial, Sans-Serif;
- transition: all 0.5s ease-in-out;
-}
-body .navbar a,
-body .navbar a:active,
-body .navbar a:visited {
- color: #39413b;
-}
-body .navbar li.active,
-body .navbar .icon-bar {
- background-color: #a5bcaa;
-}
-body .navbar.affix {
- background-color: #39413b;
-}
-body .navbar.affix a {
- color: white;
-}
-body .navbar.affix:hover a:hover {
- color: #39413b;
-}
-body .navbar.affix .icon-bar {
- background-color: white;
+ overflow-x: hidden;
}
h1,
h2,
@@ -75,6 +23,78 @@
h6 {
font-family: Oswald, Helvetica, Arial, Sans-Serif;
}
+hr.simple {
+ margin-top: 10px;
+ margin-bottom: 10px;
+}
+hr.noborder {
+ border: 0;
+}
+/**
+ * Header styles
+ */
+.header-simple .regularbanner {
+ position: relative;
+}
+.header-simple .regularbanner picture.regularbanner__media,
+.header-simple .regularbanner img.regularbanner__media {
+ width: 100%;
+}
+.header-simple .regularbanner picture.logo,
+.header-simple .regularbanner img.logo {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ max-height: calc(100% - 20px);
+}
+.affix {
+ top: 0;
+ width: 100%;
+ z-index: 9999 !important;
+ opacity: 0.95;
+ transition: all 0.5s ease-in-out;
+}
+.affix ~ .container-fluid {
+ position: relative;
+ top: 50px;
+}
+.navbar {
+ margin-bottom: 20px;
+ background-color: white;
+ border: 1px solid #39413b;
+ font-family: Oswald, Helvetica, Arial, Sans-Serif;
+ transition: all 0.5s ease-in-out;
+}
+.navbar a,
+.navbar a:active,
+.navbar a:visited {
+ color: #39413b;
+}
+.navbar li.active,
+.navbar .icon-bar {
+ background-color: #a5bcaa;
+}
+.navbar.affix {
+ background-color: #39413b;
+}
+.navbar.affix a {
+ color: white;
+}
+.navbar.affix .dropdown-menu a {
+ color: #39413b;
+}
+.navbar.affix:hover a:hover {
+ color: #39413b;
+}
+.navbar.affix .icon-bar {
+ background-color: white;
+}
+.breadcrumb {
+ margin-bottom: 1rem;
+}
+.page-header {
+ margin-top: 2rem;
+}
@media only screen and (min-width: 1200px) {
.portal-page .slot.col-lg-0 {
display: none;
@@ -95,6 +115,49 @@
display: none;
}
}
+.toolbox {
+ display: flex;
+ flex-direction: column;
+}
+.toolbox button {
+ text-align: left;
+ display: flex;
+ align-items: center;
+}
+.toolbox button i.fa {
+ display: inline-block;
+ margin-right: 1rem;
+}
+@media only screen and (min-width: 1340px) {
+ .col-lg-12 .portlet > section.wrapper {
+ margin-left: calc(0vw);
+ margin-right: calc(0vw);
+ }
+}
+@media only screen and (min-width: 1052px) {
+ .col-md-12 .portlet > section.wrapper {
+ margin-left: calc(0vw);
+ margin-right: calc(0vw);
+ }
+}
+@media only screen and (max-width: 1051px) {
+ .col-sm-12 .portlet > section.wrapper {
+ margin-left: calc(0vw);
+ margin-right: calc(0vw);
+ }
+}
+@media only screen and (max-width: 767px) {
+ .navbar.affix .dropdown-menu {
+ background-color: #39413b;
+ }
+ .navbar.affix .dropdown-menu a {
+ color: white;
+ }
+ .col-xs-12 .portlet > section.wrapper {
+ margin-left: calc(0vw);
+ margin-right: calc(0vw);
+ }
+}
/**
* Summary styles
*/
@@ -113,6 +176,25 @@
border-left: 5px solid #ddd;
}
/**
+ * Panels
+ */
+.panels {
+ margin-top: 2rem;
+}
+/**
+ * Search results
+ */
+.search-results .breadcrumb:empty {
+ margin: 0;
+ padding: 0;
+}
+.search-results .thumbnail.pull-left {
+ margin-right: 3rem;
+}
+.search-results .tags span {
+ margin: 0 0.2rem;
+}
+/**
* Images gallery
*/
.illustration {
@@ -203,4 +285,10 @@
.verbatim .panel-body .author {
margin-top: 0.5em;
}
+/**
+ * Source code
+ */
+.source pre {
+ font-family: 'Anonymous Pro', monospace;
+}
/*# sourceMappingURL=pyams-default.css.map */
\ No newline at end of file
--- a/src/pyams_default_theme/resources/css/pyams-default.css.map Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/resources/css/pyams-default.css.map Tue Dec 04 15:53:25 2018 +0100
@@ -1,1 +1,1 @@
-{"version":3,"sources":["../../../../../../../../../home/tflorac/Dropbox/src/PyAMS/pyams_default_theme/src/pyams_default_theme/resources/less/pyams-default.less"],"names":[],"mappings":";;;AAIC,cAAC;EACA,mBAAA;;AAED,cAAC;EACA,mBAAA;;;;;AASF;EACC,+CAAA;EACA,cAAA;;AAFD,IAIC,eACC;EACC,kBAAA;;AAIC,IANH,eACC,eAGC,QAEE;AAAD,IANH,eACC,eAIC,IACE;EACA,WAAA;;AAED,IATH,eACC,eAGC,QAKE;AAAD,IATH,eACC,eAIC,IAIE;EACA,kBAAA;EACA,SAAA;EACA,UAAA;EACA,6BAAA;;AAjBL,IAsBC;EACC,MAAA;EACA,WAAA;EACA,wBAAA;EACA,aAAA;EACA,gCAAA;;AA3BF,IA6BC,OAAO;EACN,kBAAA;EACA,SAAA;;AA/BF,IAiCC;EACC,mBAAA;EACA,uBAAA;EACA,yBAAA;EACA,iDAAA;EACA,gCAAA;;AAtCF,IAiCC,QAOC;AAxCF,IAiCC,QAQC,EAAC;AAzCH,IAiCC,QASC,EAAC;EACA,cAAA;;AA3CH,IAiCC,QAYC,GAAE;AA7CJ,IAiCC,QAaC;EACC,yBAAA;;AAED,IAhBD,QAgBE;EACA,yBAAA;;AADD,IAhBD,QAgBE,MAGA;EACC,YAAA;;AAED,IAtBF,QAgBE,MAMC,MACA,EAAC;EACA,cAAA;;AARH,IAhBD,QAgBE,MAWA;EACC,uBAAA;;AAMJ;AACA;AACA;AACA;AACA;AACA;EACC,iDAAA;;AAKC,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;;;;;;AAaF,QADD,WACE;EACA,kBAAA;;AAKH;EACC,gBAAA;EACA,sBAAA;EACA,2BAAA;;AAEA,UAAC;EACA,eAAA;EACA,gBAAA;EACA,sBAAA;EACA,2BAAA;;;;;AAQF;EACC,mBAAA;;AADD,aAGC;EACC,kBAAA;EACA,gBAAA;EACA,kBAAA;;AAGF;EACC,aAAA;EACA,eAAA;;AAFD,QAIC;EACC,oBAAA;;AALF,QAOC;EACC,6CAAA;EACG,kBAAA;EACH,QAAQ,WAAR;EACA,gCAAA;;AAEA,QAND,IAME;EACA,YAAA;;AAdH,QAiBC;EACC,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;;AAIF;EACC,eAAA;EACA,gBAAA;EACA,aAAA;;AAHD,cAKC;EACC,cAAA;EACA,2BAAA;EACA,kBAAA;EACA,gBAAA;;;;;AASF,cACC;EACC,WAAA;;;;;AAQF;EACC,aAAA;EACA,6BAAA;;AAFD,WAIC;EACC,iBAAA;EACA,gBAAA;;;;;AAWA,aADD,OACE;EACA,iBAAA;;AAED,aAJD,OAIE;EACA,gBAAA;;AANH,aASC;EACC,iBAAA;EACA,oBAAA;;;;;AASF,SACC;EACC,kBAAA;EACA,iBAAA;;AAEA,SAJD,YAIE;EACA,SAAS,GAAT;EACA,kBAAA;EACA,WAAA;EACA,MAAA;EACA,cAAA;;AAVH,SACC,YAWC;EACC,iBAAA","file":"pyams-default.css"}
\ No newline at end of file
+{"version":3,"sources":["../less/pyams-default.less"],"names":[],"mappings":";;;AAIC,cAAC;EACA,mBAAA;;AAED,cAAC;EACA,mBAAA;;;;;AASF;EACC,+CAAA;EACA,cAAA;EACA,kBAAA;;AAGD;AACA;AACA;AACA;AACA;AACA;EACC,iDAAA;;AAIA,EAAC;EACA,gBAAA;EACA,mBAAA;;AAED,EAAC;EACA,SAAA;;;;;AAQF,cACC;EACC,kBAAA;;AAIC,cALF,eAGC,QAEE;AAAD,cALF,eAIC,IACE;EACA,WAAA;;AAED,cARF,eAGC,QAKE;AAAD,cARF,eAIC,IAIE;EACA,kBAAA;EACA,SAAA;EACA,UAAA;EACA,6BAAA;;AAKJ;EACC,MAAA;EACA,WAAA;EACA,wBAAA;EACA,aAAA;EACA,gCAAA;;AAED,MAAO;EACN,kBAAA;EACA,SAAA;;AAED;EACC,mBAAA;EACA,uBAAA;EACA,yBAAA;EACA,iDAAA;EACA,gCAAA;;AALD,OAOC;AAPD,OAQC,EAAC;AARF,OASC,EAAC;EACA,cAAA;;AAVF,OAYC,GAAE;AAZH,OAaC;EACC,yBAAA;;AAED,OAAC;EACA,yBAAA;;AADD,OAAC,MAGA;EACC,YAAA;;AAJF,OAAC,MAMA,eACC;EACC,cAAA;;AAGF,OAXA,MAWC,MACA,EAAC;EACA,cAAA;;AAbH,OAAC,MAgBA;EACC,uBAAA;;AAKH;EACC,mBAAA;;AAGD;EACC,gBAAA;;AAKC,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;;;AAMJ;EACC,aAAA;EACA,sBAAA;;AAFD,QAIC;EACC,gBAAA;EACA,aAAA;EACA,mBAAA;;AAPF,QAIC,OAKC,EAAC;EACA,qBAAA;EACA,kBAAA;;AAKH,wBAA2C;EAC1C,UAAW,SAAS,UAAS;IAC5B,aAAa,SAAb;IACA,cAAc,SAAd;;;AAIF,wBAA2C;EAC1C,UAAW,SAAS,UAAS;IAC5B,aAAa,SAAb;IACA,cAAc,SAAd;;;AAIF,wBAA2C;EAC1C,UAAW,SAAS,UAAS;IAC5B,aAAa,SAAb;IACA,cAAc,SAAd;;;AAIF,wBAA0C;EAExC,OAAC,MACA;IACC,yBAAA;;EAFF,OAAC,MACA,eAGC;IACC,YAAA;;EAMJ,UAAW,SAAS,UAAS;IAC5B,aAAa,SAAb;IACA,cAAc,SAAd;;;;;;AAWA,QADD,WACE;EACA,kBAAA;;AAKH;EACC,gBAAA;EACA,sBAAA;EACA,2BAAA;;AAEA,UAAC;EACA,eAAA;EACA,gBAAA;EACA,sBAAA;EACA,2BAAA;;;;;AAQF;EACC,gBAAA;;;;;AAQD,eACC,YAAW;EACV,SAAA;EACA,UAAA;;AAGA,eADD,WACE;EACA,kBAAA;;AAPH,eAUC,MACC;EACC,gBAAA;;;;;AAUH;EACC,mBAAA;;AADD,aAGC;EACC,kBAAA;EACA,gBAAA;EACA,kBAAA;;AAGF;EACC,aAAA;EACA,eAAA;;AAFD,QAIC;EACC,oBAAA;;AALF,QAOC;EACC,6CAAA;EACG,kBAAA;EACH,QAAQ,WAAR;EACA,gCAAA;;AAEA,QAND,IAME;EACA,YAAA;;AAdH,QAiBC;EACC,mBAAA;EACA,iBAAA;EACA,kBAAA;EACA,gBAAA;;AAIF;EACC,eAAA;EACA,gBAAA;EACA,aAAA;;AAHD,cAKC;EACC,cAAA;EACA,2BAAA;EACA,kBAAA;EACA,gBAAA;;;;;AASF,cACC;EACC,WAAA;;;;;AAQF;EACC,aAAA;EACA,6BAAA;;AAFD,WAIC;EACC,iBAAA;EACA,gBAAA;;;;;AAWA,aADD,OACE;EACA,iBAAA;;AAED,aAJD,OAIE;EACA,gBAAA;;AANH,aASC;EACC,iBAAA;EACA,oBAAA;;;;;AASF,SACC;EACC,kBAAA;EACA,iBAAA;;AAEA,SAJD,YAIE;EACA,SAAS,GAAT;EACA,kBAAA;EACA,WAAA;EACA,MAAA;EACA,cAAA;;AAVH,SACC,YAWC;EACC,iBAAA;;;;;AAUH,OACC;EACC,aAAa,0BAAb","file":"pyams-default.css"}
\ No newline at end of file
--- a/src/pyams_default_theme/resources/css/pyams-default.min.css Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/resources/css/pyams-default.min.css Tue Dec 04 15:53:25 2018 +0100
@@ -1,1 +1,1 @@
-.margin-bottom-10{margin-bottom:10px}.margin-bottom-20{margin-bottom:20px}body{font-family:Lato,Helvetica,Arial,sans-serif;margin:0 auto}body .header-simple .regularbanner{position:relative}body .header-simple .regularbanner img.regularbanner__media,body .header-simple .regularbanner picture.regularbanner__media{width:100%}body .header-simple .regularbanner img.logo,body .header-simple .regularbanner picture.logo{position:absolute;top:10px;left:10px;max-height:calc(100% - 20px)}body .affix{top:0;width:100%;z-index:9999!important;opacity:.95;transition:all .5s ease-in-out}body .affix~.container-fluid{position:relative;top:50px}body .navbar{margin-bottom:20px;background-color:#fff;border:1px solid #39413b;font-family:Oswald,Helvetica,Arial,Sans-Serif;transition:all .5s ease-in-out}body .navbar a,body .navbar a:active,body .navbar a:visited{color:#39413b}body .navbar .icon-bar,body .navbar li.active{background-color:#a5bcaa}body .navbar.affix{background-color:#39413b}body .navbar.affix a{color:#fff}body .navbar.affix:hover a:hover{color:#39413b}body .navbar.affix .icon-bar{background-color:#fff}h1,h2,h3,h4,h5,h6{font-family:Oswald,Helvetica,Arial,Sans-Serif}@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}}.summary .thumbnail.pull-left{margin-right:15px}blockquote{margin-top:2rem;border:1px solid #ddd;border-left:5px solid #ddd}blockquote.pull-right{padding:0 15px;text-align:left;border:1px solid #ddd;border-left:5px solid #ddd}.illustration{margin-bottom:1rem}.illustration .author{padding-top:.2em;font-size:.9em;font-style:italic}.gallery{display:flex;flex-wrap:wrap}.gallery .legend{margin-bottom:.2em}.gallery img{box-shadow:0 2px 6px 2px rgba(0,0,0,.75);margin-bottom:5px;filter:grayscale();transition:all ease-in-out .5s}.gallery img:hover{filter:none}.gallery .author{margin-bottom:15px;text-align:right;font-style:italic;font-size:.8em}.ekko-lightbox{position:fixed;top:0!important;height:100vh}.ekko-lightbox .modal-footer{padding-top:0;text-align:right!important;font-style:italic;font-size:.8em}.video-wrapper iframe{width:100%}.milestones{display:flex;justify-content:space-around}.milestones .arrow{font-weight:700;font-size:1.5em}.contact-card .photo.pull-left{margin-right:1em}.contact-card .photo.pull-right{margin-left:1em}.contact-card .address{margin-top:.5em;margin-bottom:.5em}.verbatim .panel-body{position:relative;margin-left:50px}.verbatim .panel-body::before{content:'«';position:absolute;left:-30px;top:0;font-size:4em}.verbatim .panel-body .author{margin-top:.5em}
+.margin-bottom-10{margin-bottom:10px}.margin-bottom-20{margin-bottom:20px}body{font-family:Lato,Helvetica,Arial,sans-serif;margin:0 auto;overflow-x:hidden}h1,h2,h3,h4,h5,h6{font-family:Oswald,Helvetica,Arial,Sans-Serif}hr.simple{margin-top:10px;margin-bottom:10px}hr.noborder{border:0}.header-simple .regularbanner{position:relative}.header-simple .regularbanner img.regularbanner__media,.header-simple .regularbanner picture.regularbanner__media{width:100%}.header-simple .regularbanner img.logo,.header-simple .regularbanner picture.logo{position:absolute;top:10px;left:10px;max-height:calc(100% - 20px)}.affix{top:0;width:100%;z-index:9999!important;opacity:.95;transition:all .5s ease-in-out}.affix~.container-fluid{position:relative;top:50px}.navbar{margin-bottom:20px;background-color:#fff;border:1px solid #39413b;font-family:Oswald,Helvetica,Arial,Sans-Serif;transition:all .5s ease-in-out}.navbar a,.navbar a:active,.navbar a:visited{color:#39413b}.navbar .icon-bar,.navbar li.active{background-color:#a5bcaa}.navbar.affix{background-color:#39413b}.navbar.affix a{color:#fff}.navbar.affix .dropdown-menu a{color:#39413b}.navbar.affix:hover a:hover{color:#39413b}.navbar.affix .icon-bar{background-color:#fff}.breadcrumb{margin-bottom:1rem}.page-header{margin-top:2rem}@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}}.toolbox{display:flex;flex-direction:column}.toolbox button{text-align:left;display:flex;align-items:center}.toolbox button i.fa{display:inline-block;margin-right:1rem}@media only screen and (min-width:1340px){.col-lg-12 .portlet>section.wrapper{margin-left:calc(0vw);margin-right:calc(0vw)}}@media only screen and (min-width:1052px){.col-md-12 .portlet>section.wrapper{margin-left:calc(0vw);margin-right:calc(0vw)}}@media only screen and (max-width:1051px){.col-sm-12 .portlet>section.wrapper{margin-left:calc(0vw);margin-right:calc(0vw)}}@media only screen and (max-width:767px){.navbar.affix .dropdown-menu{background-color:#39413b}.navbar.affix .dropdown-menu a{color:#fff}.col-xs-12 .portlet>section.wrapper{margin-left:calc(0vw);margin-right:calc(0vw)}}.summary .thumbnail.pull-left{margin-right:15px}blockquote{margin-top:2rem;border:1px solid #ddd;border-left:5px solid #ddd}blockquote.pull-right{padding:0 15px;text-align:left;border:1px solid #ddd;border-left:5px solid #ddd}.panels{margin-top:2rem}.search-results .breadcrumb:empty{margin:0;padding:0}.search-results .thumbnail.pull-left{margin-right:3rem}.search-results .tags span{margin:0 .2rem}.illustration{margin-bottom:1rem}.illustration .author{padding-top:.2em;font-size:.9em;font-style:italic}.gallery{display:flex;flex-wrap:wrap}.gallery .legend{margin-bottom:.2em}.gallery img{box-shadow:0 2px 6px 2px rgba(0,0,0,.75);margin-bottom:5px;filter:grayscale();transition:all ease-in-out .5s}.gallery img:hover{filter:none}.gallery .author{margin-bottom:15px;text-align:right;font-style:italic;font-size:.8em}.ekko-lightbox{position:fixed;top:0!important;height:100vh}.ekko-lightbox .modal-footer{padding-top:0;text-align:right!important;font-style:italic;font-size:.8em}.video-wrapper iframe{width:100%}.milestones{display:flex;justify-content:space-around}.milestones .arrow{font-weight:700;font-size:1.5em}.contact-card .photo.pull-left{margin-right:1em}.contact-card .photo.pull-right{margin-left:1em}.contact-card .address{margin-top:.5em;margin-bottom:.5em}.verbatim .panel-body{position:relative;margin-left:50px}.verbatim .panel-body::before{content:'«';position:absolute;left:-30px;top:0;font-size:4em}.verbatim .panel-body .author{margin-top:.5em}.source pre{font-family:'Anonymous Pro',monospace}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/resources/img/print-button.svg Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ width="45px" height="45px" viewBox="0 0 45 45" style="enable-background:new 0 0 45 45;" xml:space="preserve">
+<g>
+ <path d="M42.5,19.408H40V1.843c0-0.69-0.561-1.25-1.25-1.25H6.25C5.56,0.593,5,1.153,5,1.843v17.563H2.5
+ c-1.381,0-2.5,1.119-2.5,2.5v20c0,1.381,1.119,2.5,2.5,2.5h40c1.381,0,2.5-1.119,2.5-2.5v-20C45,20.525,43.881,19.408,42.5,19.408z
+ M32.531,38.094H12.468v-5h20.063V38.094z M37.5,19.408H35c-1.381,0-2.5,1.119-2.5,2.5v5h-20v-5c0-1.381-1.119-2.5-2.5-2.5H7.5
+ V3.093h30V19.408z M32.5,8.792h-20c-0.69,0-1.25-0.56-1.25-1.25s0.56-1.25,1.25-1.25h20c0.689,0,1.25,0.56,1.25,1.25
+ S33.189,8.792,32.5,8.792z M32.5,13.792h-20c-0.69,0-1.25-0.56-1.25-1.25s0.56-1.25,1.25-1.25h20c0.689,0,1.25,0.56,1.25,1.25
+ S33.189,13.792,32.5,13.792z M32.5,18.792h-20c-0.69,0-1.25-0.56-1.25-1.25s0.56-1.25,1.25-1.25h20c0.689,0,1.25,0.56,1.25,1.25
+ S33.189,18.792,32.5,18.792z"/>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+<g>
+</g>
+</svg>
--- a/src/pyams_default_theme/resources/js/ext/ekko-lightbox.min.js Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/resources/js/ext/ekko-lightbox.min.js Tue Dec 04 15:53:25 2018 +0100
@@ -1,1 +1,1 @@
-!function(t){"use strict";var e=function(){function o(t,e){for(var i=0;i<e.length;i++){var o=e[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(t,e,i){return e&&o(t.prototype,e),i&&o(t,i),t}}();var c,i,o,l,a;c=jQuery,i="ekkoLightbox",o=c.fn[i],l={title:"",footer:"",maxWidth:9999,maxHeight:9999,showArrows:!0,wrapping:!0,type:null,alwaysShowClose:!1,loadingMessage:'<div class="ekko-lightbox-loader"><div><div></div><div></div></div></div>',leftArrow:"<span>❮</span>",rightArrow:"<span>❯</span>",strings:{close:"Close",fail:"Failed to load image:",type:"Could not detect remote target type. Force the type using data-type"},doc:document,onShow:function(){},onShown:function(){},onHide:function(){},onHidden:function(){},onNavigate:function(){},onContentLoaded:function(){}},a=function(){function n(t,e){var i=this;!function(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}(this,n),this._config=c.extend({},l,e),this._$modalArrows=null,this._galleryIndex=0,this._galleryName=null,this._padding=null,this._border=null,this._titleIsShown=!1,this._footerIsShown=!1,this._wantedWidth=0,this._wantedHeight=0,this._touchstartX=0,this._touchendX=0,this._modalId="ekkoLightbox-"+Math.floor(1e3*Math.random()+1),this._$element=t instanceof jQuery?t:c(t),this._isBootstrap3=3==c.fn.modal.Constructor.VERSION[0];var o='<h4 class="modal-title">'+(this._config.title||" ")+"</h4>",a='<button type="button" class="close" data-dismiss="modal" aria-label="'+this._config.strings.close+'"><span aria-hidden="true">×</span></button>',s='<div class="modal-dialog" role="document"><div class="modal-content">'+('<div class="modal-header'+(this._config.title||this._config.alwaysShowClose?"":" hide")+'">'+(this._isBootstrap3?a+o:o+a)+"</div>")+'<div class="modal-body"><div class="ekko-lightbox-container"><div class="ekko-lightbox-item fade in show"></div><div class="ekko-lightbox-item fade"></div></div></div>'+('<div class="modal-footer'+(this._config.footer?"":" hide")+'">'+(this._config.footer||" ")+"</div>")+"</div></div>";c(this._config.doc.body).append('<div id="'+this._modalId+'" class="ekko-lightbox modal fade" tabindex="-1" tabindex="-1" role="dialog" aria-hidden="true">'+s+"</div>"),this._$modal=c("#"+this._modalId,this._config.doc),this._$modalDialog=this._$modal.find(".modal-dialog").first(),this._$modalContent=this._$modal.find(".modal-content").first(),this._$modalBody=this._$modal.find(".modal-body").first(),this._$modalHeader=this._$modal.find(".modal-header").first(),this._$modalFooter=this._$modal.find(".modal-footer").first(),this._$lightboxContainer=this._$modalBody.find(".ekko-lightbox-container").first(),this._$lightboxBodyOne=this._$lightboxContainer.find("> div:first-child").first(),this._$lightboxBodyTwo=this._$lightboxContainer.find("> div:last-child").first(),this._border=this._calculateBorders(),this._padding=this._calculatePadding(),this._galleryName=this._$element.data("gallery"),this._galleryName&&(this._$galleryItems=c(document.body).find('*[data-gallery="'+this._galleryName+'"]'),this._galleryIndex=this._$galleryItems.index(this._$element),c(document).on("keydown.ekkoLightbox",this._navigationalBinder.bind(this)),this._config.showArrows&&1<this._$galleryItems.length&&(this._$lightboxContainer.append('<div class="ekko-lightbox-nav-overlay"><a href="#">'+this._config.leftArrow+'</a><a href="#">'+this._config.rightArrow+"</a></div>"),this._$modalArrows=this._$lightboxContainer.find("div.ekko-lightbox-nav-overlay").first(),this._$lightboxContainer.on("click","a:first-child",function(t){return t.preventDefault(),i.navigateLeft()}),this._$lightboxContainer.on("click","a:last-child",function(t){return t.preventDefault(),i.navigateRight()}),this.updateNavigation())),this._$modal.on("show.bs.modal",this._config.onShow.bind(this)).on("shown.bs.modal",function(){return i._toggleLoading(!0),i._handle(),i._config.onShown.call(i)}).on("hide.bs.modal",this._config.onHide.bind(this)).on("hidden.bs.modal",function(){return i._galleryName&&(c(document).off("keydown.ekkoLightbox"),c(window).off("resize.ekkoLightbox")),i._$modal.remove(),i._config.onHidden.call(i)}).modal(this._config),c(window).on("resize.ekkoLightbox",function(){i._resize(i._wantedWidth,i._wantedHeight)}),this._$lightboxContainer.on("touchstart",function(){i._touchstartX=event.changedTouches[0].screenX}).on("touchend",function(){i._touchendX=event.changedTouches[0].screenX,i._swipeGesure()})}return e(n,null,[{key:"Default",get:function(){return l}}]),e(n,[{key:"element",value:function(){return this._$element}},{key:"modal",value:function(){return this._$modal}},{key:"navigateTo",value:function(t){if(t<0||t>this._$galleryItems.length-1)return this;this._galleryIndex=t,this.updateNavigation(),this._$element=c(this._$galleryItems.get(this._galleryIndex)),this._handle()}},{key:"navigateLeft",value:function(){if(this._$galleryItems&&1!==this._$galleryItems.length){if(0===this._galleryIndex){if(!this._config.wrapping)return;this._galleryIndex=this._$galleryItems.length-1}else this._galleryIndex--;return this._config.onNavigate.call(this,"left",this._galleryIndex),this.navigateTo(this._galleryIndex)}}},{key:"navigateRight",value:function(){if(this._$galleryItems&&1!==this._$galleryItems.length){if(this._galleryIndex===this._$galleryItems.length-1){if(!this._config.wrapping)return;this._galleryIndex=0}else this._galleryIndex++;return this._config.onNavigate.call(this,"right",this._galleryIndex),this.navigateTo(this._galleryIndex)}}},{key:"updateNavigation",value:function(){if(!this._config.wrapping){var t=this._$lightboxContainer.find("div.ekko-lightbox-nav-overlay");0===this._galleryIndex?t.find("a:first-child").addClass("disabled"):t.find("a:first-child").removeClass("disabled"),this._galleryIndex===this._$galleryItems.length-1?t.find("a:last-child").addClass("disabled"):t.find("a:last-child").removeClass("disabled")}}},{key:"close",value:function(){return this._$modal.modal("hide")}},{key:"_navigationalBinder",value:function(t){return 39===(t=t||window.event).keyCode?this.navigateRight():37===t.keyCode?this.navigateLeft():void 0}},{key:"_detectRemoteType",value:function(t,e){return!(e=e||!1)&&this._isImage(t)&&(e="image"),!e&&this._getYoutubeId(t)&&(e="youtube"),!e&&this._getVimeoId(t)&&(e="vimeo"),!e&&this._getInstagramId(t)&&(e="instagram"),("audio"==e||"video"==e||!e&&this._isMedia(t))&&(e="media"),(!e||["image","youtube","vimeo","instagram","media","url"].indexOf(e)<0)&&(e="url"),e}},{key:"_getRemoteContentType",value:function(t){return c.ajax({type:"HEAD",url:t,async:!1}).getResponseHeader("Content-Type")}},{key:"_isImage",value:function(t){return t&&t.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)}},{key:"_isMedia",value:function(t){return t&&t.match(/(\.(mp3|mp4|ogg|webm|wav)((\?|#).*)?$)/i)}},{key:"_containerToUse",value:function(){var t=this,e=this._$lightboxBodyTwo,i=this._$lightboxBodyOne;return this._$lightboxBodyTwo.hasClass("in")&&(e=this._$lightboxBodyOne,i=this._$lightboxBodyTwo),i.removeClass("in show"),setTimeout(function(){t._$lightboxBodyTwo.hasClass("in")||t._$lightboxBodyTwo.empty(),t._$lightboxBodyOne.hasClass("in")||t._$lightboxBodyOne.empty()},500),e.addClass("in show"),e}},{key:"_handle",value:function(){var t=this._containerToUse();this._updateTitleAndFooter();var e=this._$element.attr("data-remote")||this._$element.attr("href"),i=this._detectRemoteType(e,this._$element.attr("data-type")||!1);if(["image","youtube","vimeo","instagram","media","url"].indexOf(i)<0)return this._error(this._config.strings.type);switch(i){case"image":this._preloadImage(e,t),this._preloadImageByIndex(this._galleryIndex,3);break;case"youtube":this._showYoutubeVideo(e,t);break;case"vimeo":this._showVimeoVideo(this._getVimeoId(e),t);break;case"instagram":this._showInstagramVideo(this._getInstagramId(e),t);break;case"media":this._showHtml5Media(e,t);break;default:this._loadRemoteContent(e,t)}return this}},{key:"_getYoutubeId",value:function(t){if(!t)return!1;var e=t.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);return!(!e||11!==e[2].length)&&e[2]}},{key:"_getVimeoId",value:function(t){return!!(t&&0<t.indexOf("vimeo"))&&t}},{key:"_getInstagramId",value:function(t){return!!(t&&0<t.indexOf("instagram"))&&t}},{key:"_toggleLoading",value:function(t){return(t=t||!1)?(this._$modalDialog.css("display","none"),this._$modal.removeClass("in show"),c(".modal-backdrop").append(this._config.loadingMessage)):(this._$modalDialog.css("display","block"),this._$modal.addClass("in show"),c(".modal-backdrop").find(".ekko-lightbox-loader").remove()),this}},{key:"_calculateBorders",value:function(){return{top:this._totalCssByAttribute("border-top-width"),right:this._totalCssByAttribute("border-right-width"),bottom:this._totalCssByAttribute("border-bottom-width"),left:this._totalCssByAttribute("border-left-width")}}},{key:"_calculatePadding",value:function(){return{top:this._totalCssByAttribute("padding-top"),right:this._totalCssByAttribute("padding-right"),bottom:this._totalCssByAttribute("padding-bottom"),left:this._totalCssByAttribute("padding-left")}}},{key:"_totalCssByAttribute",value:function(t){return parseInt(this._$modalDialog.css(t),10)+parseInt(this._$modalContent.css(t),10)+parseInt(this._$modalBody.css(t),10)}},{key:"_updateTitleAndFooter",value:function(){var t=this._$element.data("title")||"",e=this._$element.data("footer")||"";return this._titleIsShown=!1,t||this._config.alwaysShowClose?(this._titleIsShown=!0,this._$modalHeader.css("display","").find(".modal-title").html(t||" ")):this._$modalHeader.css("display","none"),this._footerIsShown=!1,e?(this._footerIsShown=!0,this._$modalFooter.css("display","").html(e)):this._$modalFooter.css("display","none"),this}},{key:"_showYoutubeVideo",value:function(t,e){var i=this._getYoutubeId(t),o=0<t.indexOf("&")?t.substr(t.indexOf("&")):"",a=this._$element.data("width")||560,s=this._$element.data("height")||a/(560/315);return this._showVideoIframe("//www.youtube.com/embed/"+i+"?badge=0&autoplay=1&html5=1"+o,a,s,e)}},{key:"_showVimeoVideo",value:function(t,e){var i=this._$element.data("width")||500,o=this._$element.data("height")||i/(560/315);return this._showVideoIframe(t+"?autoplay=1",i,o,e)}},{key:"_showInstagramVideo",value:function(t,e){var i=this._$element.data("width")||612,o=i+80;return t="/"!==t.substr(-1)?t+"/":t,e.html('<iframe width="'+i+'" height="'+o+'" src="'+t+'embed/" frameborder="0" allowfullscreen></iframe>'),this._resize(i,o),this._config.onContentLoaded.call(this),this._$modalArrows&&this._$modalArrows.css("display","none"),this._toggleLoading(!1),this}},{key:"_showVideoIframe",value:function(t,e,i,o){return i=i||e,o.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="'+e+'" height="'+i+'" src="'+t+'" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>'),this._resize(e,i),this._config.onContentLoaded.call(this),this._$modalArrows&&this._$modalArrows.css("display","none"),this._toggleLoading(!1),this}},{key:"_showHtml5Media",value:function(t,e){var i=this._getRemoteContentType(t);if(!i)return this._error(this._config.strings.type);var o="";o=0<i.indexOf("audio")?"audio":"video";var a=this._$element.data("width")||560,s=this._$element.data("height")||a/(560/315);return e.html('<div class="embed-responsive embed-responsive-16by9"><'+o+' width="'+a+'" height="'+s+'" preload="auto" autoplay controls class="embed-responsive-item"><source src="'+t+'" type="'+i+'">'+this._config.strings.type+"</"+o+"></div>"),this._resize(a,s),this._config.onContentLoaded.call(this),this._$modalArrows&&this._$modalArrows.css("display","none"),this._toggleLoading(!1),this}},{key:"_loadRemoteContent",value:function(t,e){var i=this,o=this._$element.data("width")||560,a=this._$element.data("height")||560,s=this._$element.data("disableExternalCheck")||!1;return this._toggleLoading(!1),s||this._isExternal(t)?(e.html('<iframe src="'+t+'" frameborder="0" allowfullscreen></iframe>'),this._config.onContentLoaded.call(this)):e.load(t,c.proxy(function(){return i._$element.trigger("loaded.bs.modal")})),this._$modalArrows&&this._$modalArrows.css("display","none"),this._resize(o,a),this}},{key:"_isExternal",value:function(t){var e=t.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);return"string"==typeof e[1]&&0<e[1].length&&e[1].toLowerCase()!==location.protocol||"string"==typeof e[2]&&0<e[2].length&&e[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"),"")!==location.host}},{key:"_error",value:function(t){return console.error(t),this._containerToUse().html(t),this._resize(300,300),this}},{key:"_preloadImageByIndex",value:function(t,e){if(this._$galleryItems){var i=c(this._$galleryItems.get(t),!1);if(void 0!==i){var o=i.attr("data-remote")||i.attr("href");return("image"===i.attr("data-type")||this._isImage(o))&&this._preloadImage(o,!1),0<e?this._preloadImageByIndex(t+1,e-1):void 0}}}},{key:"_preloadImage",value:function(t,e){var i=this;e=e||!1;var o,a=new Image;return e&&(o=setTimeout(function(){e.append(i._config.loadingMessage)},200),a.onload=function(){o&&clearTimeout(o),o=null;var t=c("<img />");return t.attr("src",a.src),t.addClass("img-fluid"),t.css("width","100%"),e.html(t),i._$modalArrows&&i._$modalArrows.css("display",""),i._resize(a.width,a.height),i._toggleLoading(!1),i._config.onContentLoaded.call(i)},a.onerror=function(){return i._toggleLoading(!1),i._error(i._config.strings.fail+" "+t)}),a.src=t,a}},{key:"_swipeGesure",value:function(){return this._touchendX<this._touchstartX?this.navigateRight():this._touchendX>this._touchstartX?this.navigateLeft():void 0}},{key:"_resize",value:function(t,e){e=e||t;var i=(this._wantedWidth=t)/(this._wantedHeight=e),o=this._padding.left+this._padding.right+this._border.left+this._border.right,a=575<this._config.doc.body.clientWidth?20:0,s=575<this._config.doc.body.clientWidth?0:20,n=Math.min(t+o,this._config.doc.body.clientWidth-a,this._config.maxWidth);n<t+o?(e=(n-o-s)/i,t=n):t+=o;var l=0,r=0;this._footerIsShown&&(r=this._$modalFooter.outerHeight(!0)||55),this._titleIsShown&&(l=this._$modalHeader.outerHeight(!0)||67);var d=this._padding.top+this._padding.bottom+this._border.bottom+this._border.top,h=parseFloat(this._$modalDialog.css("margin-top"))+parseFloat(this._$modalDialog.css("margin-bottom")),g=Math.min(e,c(window).height()-d-h-l-r,this._config.maxHeight-d-l-r);g<e&&(t=Math.ceil(g*i)+o),this._$lightboxContainer.css("height",g),this._$modalDialog.css("flex",1).css("maxWidth",t);var _=this._$modal.data("bs.modal");if(_)try{_._handleUpdate()}catch(t){_.handleUpdate()}return this}}],[{key:"_jQueryInterface",value:function(i){var o=this;return i=i||{},this.each(function(){var t=c(o),e=c.extend({},n.Default,t.data(),"object"==typeof i&&i);new n(o,e)})}}]),n}(),c.fn[i]=a._jQueryInterface,c.fn[i].Constructor=a,c.fn[i].noConflict=function(){return c.fn[i]=o,a._jQueryInterface}}(jQuery);
++function(t){"use strict";function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=function(){function t(t,e){for(var i=0;i<e.length;i++){var o=e[i];o.enumerable=o.enumerable||!1,o.configurable=!0,"value"in o&&(o.writable=!0),Object.defineProperty(t,o.key,o)}}return function(e,i,o){return i&&t(e.prototype,i),o&&t(e,o),e}}();!function(t){var o="ekkoLightbox",a=t.fn[o],s={title:"",footer:"",maxWidth:9999,maxHeight:9999,showArrows:!0,wrapping:!0,type:null,alwaysShowClose:!1,loadingMessage:'<div class="ekko-lightbox-loader"><div><div></div><div></div></div></div>',leftArrow:"<span>❮</span>",rightArrow:"<span>❯</span>",strings:{close:"Close",fail:"Failed to load image:",type:"Could not detect remote target type. Force the type using data-type"},doc:document,onShow:function(){},onShown:function(){},onHide:function(){},onHidden:function(){},onNavigate:function(){},onContentLoaded:function(){}},n=function(){function o(i,a){var n=this;e(this,o),this._config=t.extend({},s,a),this._$modalArrows=null,this._galleryIndex=0,this._galleryName=null,this._padding=null,this._border=null,this._titleIsShown=!1,this._footerIsShown=!1,this._wantedWidth=0,this._wantedHeight=0,this._touchstartX=0,this._touchendX=0,this._modalId="ekkoLightbox-"+Math.floor(1e3*Math.random()+1),this._$element=i instanceof jQuery?i:t(i),this._isBootstrap3=3==t.fn.modal.Constructor.VERSION[0];var l='<h4 class="modal-title">'+(this._config.title||" ")+"</h4>",r='<button type="button" class="close" data-dismiss="modal" aria-label="'+this._config.strings.close+'"><span aria-hidden="true">×</span></button>',d='<div class="modal-dialog" role="document"><div class="modal-content">'+('<div class="modal-header'+(this._config.title||this._config.alwaysShowClose?"":" hide")+'">'+(this._isBootstrap3?r+l:l+r)+"</div>")+'<div class="modal-body"><div class="ekko-lightbox-container"><div class="ekko-lightbox-item fade in show"></div><div class="ekko-lightbox-item fade"></div></div></div>'+('<div class="modal-footer'+(this._config.footer?"":" hide")+'">'+(this._config.footer||" ")+"</div>")+"</div></div>";t(this._config.doc.body).append('<div id="'+this._modalId+'" class="ekko-lightbox modal fade" tabindex="-1" tabindex="-1" role="dialog" aria-hidden="true">'+d+"</div>"),this._$modal=t("#"+this._modalId,this._config.doc),this._$modalDialog=this._$modal.find(".modal-dialog").first(),this._$modalContent=this._$modal.find(".modal-content").first(),this._$modalBody=this._$modal.find(".modal-body").first(),this._$modalHeader=this._$modal.find(".modal-header").first(),this._$modalFooter=this._$modal.find(".modal-footer").first(),this._$lightboxContainer=this._$modalBody.find(".ekko-lightbox-container").first(),this._$lightboxBodyOne=this._$lightboxContainer.find("> div:first-child").first(),this._$lightboxBodyTwo=this._$lightboxContainer.find("> div:last-child").first(),this._border=this._calculateBorders(),this._padding=this._calculatePadding(),this._galleryName=this._$element.data("gallery"),this._galleryName&&(this._$galleryItems=t(document.body).find('*[data-gallery="'+this._galleryName+'"]'),this._galleryIndex=this._$galleryItems.index(this._$element),t(document).on("keydown.ekkoLightbox",this._navigationalBinder.bind(this)),this._config.showArrows&&this._$galleryItems.length>1&&(this._$lightboxContainer.append('<div class="ekko-lightbox-nav-overlay"><a href="#">'+this._config.leftArrow+'</a><a href="#">'+this._config.rightArrow+"</a></div>"),this._$modalArrows=this._$lightboxContainer.find("div.ekko-lightbox-nav-overlay").first(),this._$lightboxContainer.on("click","a:first-child",function(t){return t.preventDefault(),n.navigateLeft()}),this._$lightboxContainer.on("click","a:last-child",function(t){return t.preventDefault(),n.navigateRight()}),this.updateNavigation())),this._$modal.on("show.bs.modal",this._config.onShow.bind(this)).on("shown.bs.modal",function(){return n._toggleLoading(!0),n._handle(),n._config.onShown.call(n)}).on("hide.bs.modal",this._config.onHide.bind(this)).on("hidden.bs.modal",function(){return n._galleryName&&(t(document).off("keydown.ekkoLightbox"),t(window).off("resize.ekkoLightbox")),n._$modal.remove(),n._config.onHidden.call(n)}).modal(this._config),t(window).on("resize.ekkoLightbox",function(){n._resize(n._wantedWidth,n._wantedHeight)}),this._$lightboxContainer.on("touchstart",function(){n._touchstartX=event.changedTouches[0].screenX}).on("touchend",function(){n._touchendX=event.changedTouches[0].screenX,n._swipeGesure()})}return i(o,null,[{key:"Default",get:function(){return s}}]),i(o,[{key:"element",value:function(){return this._$element}},{key:"modal",value:function(){return this._$modal}},{key:"navigateTo",value:function(e){if(e<0||e>this._$galleryItems.length-1)return this;this._galleryIndex=e,this.updateNavigation(),this._$element=t(this._$galleryItems.get(this._galleryIndex)),this._handle()}},{key:"navigateLeft",value:function(){if(this._$galleryItems&&1!==this._$galleryItems.length){if(0===this._galleryIndex){if(!this._config.wrapping)return;this._galleryIndex=this._$galleryItems.length-1}else this._galleryIndex--;return this._config.onNavigate.call(this,"left",this._galleryIndex),this.navigateTo(this._galleryIndex)}}},{key:"navigateRight",value:function(){if(this._$galleryItems&&1!==this._$galleryItems.length){if(this._galleryIndex===this._$galleryItems.length-1){if(!this._config.wrapping)return;this._galleryIndex=0}else this._galleryIndex++;return this._config.onNavigate.call(this,"right",this._galleryIndex),this.navigateTo(this._galleryIndex)}}},{key:"updateNavigation",value:function(){if(!this._config.wrapping){var t=this._$lightboxContainer.find("div.ekko-lightbox-nav-overlay");0===this._galleryIndex?t.find("a:first-child").addClass("disabled"):t.find("a:first-child").removeClass("disabled"),this._galleryIndex===this._$galleryItems.length-1?t.find("a:last-child").addClass("disabled"):t.find("a:last-child").removeClass("disabled")}}},{key:"close",value:function(){return this._$modal.modal("hide")}},{key:"_navigationalBinder",value:function(t){return 39===(t=t||window.event).keyCode?this.navigateRight():37===t.keyCode?this.navigateLeft():void 0}},{key:"_detectRemoteType",value:function(t,e){return!(e=e||!1)&&this._isImage(t)&&(e="image"),!e&&this._getYoutubeId(t)&&(e="youtube"),!e&&this._getVimeoId(t)&&(e="vimeo"),!e&&this._getInstagramId(t)&&(e="instagram"),("audio"==e||"video"==e||!e&&this._isMedia(t))&&(e="media"),(!e||["image","youtube","vimeo","instagram","media","url"].indexOf(e)<0)&&(e="url"),e}},{key:"_getRemoteContentType",value:function(e){return t.ajax({type:"HEAD",url:e,async:!1}).getResponseHeader("Content-Type")}},{key:"_isImage",value:function(t){return t&&t.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i)}},{key:"_isMedia",value:function(t){return t&&t.match(/(\.(mp3|mp4|ogg|webm|wav)((\?|#).*)?$)/i)}},{key:"_containerToUse",value:function(){var t=this,e=this._$lightboxBodyTwo,i=this._$lightboxBodyOne;return this._$lightboxBodyTwo.hasClass("in")&&(e=this._$lightboxBodyOne,i=this._$lightboxBodyTwo),i.removeClass("in show"),setTimeout(function(){t._$lightboxBodyTwo.hasClass("in")||t._$lightboxBodyTwo.empty(),t._$lightboxBodyOne.hasClass("in")||t._$lightboxBodyOne.empty()},500),e.addClass("in show"),e}},{key:"_handle",value:function(){var t=this._containerToUse();this._updateTitleAndFooter();var e=this._$element.attr("data-remote")||this._$element.attr("href"),i=this._detectRemoteType(e,this._$element.attr("data-type")||!1);if(["image","youtube","vimeo","instagram","media","url"].indexOf(i)<0)return this._error(this._config.strings.type);switch(i){case"image":this._preloadImage(e,t),this._preloadImageByIndex(this._galleryIndex,3);break;case"youtube":this._showYoutubeVideo(e,t);break;case"vimeo":this._showVimeoVideo(this._getVimeoId(e),t);break;case"instagram":this._showInstagramVideo(this._getInstagramId(e),t);break;case"media":this._showHtml5Media(e,t);break;default:this._loadRemoteContent(e,t)}return this}},{key:"_getYoutubeId",value:function(t){if(!t)return!1;var e=t.match(/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*/);return!(!e||11!==e[2].length)&&e[2]}},{key:"_getVimeoId",value:function(t){return!!(t&&t.indexOf("vimeo")>0)&&t}},{key:"_getInstagramId",value:function(t){return!!(t&&t.indexOf("instagram")>0)&&t}},{key:"_toggleLoading",value:function(e){return(e=e||!1)?(this._$modalDialog.css("display","none"),this._$modal.removeClass("in show"),t(".modal-backdrop").append(this._config.loadingMessage)):(this._$modalDialog.css("display","block"),this._$modal.addClass("in show"),t(".modal-backdrop").find(".ekko-lightbox-loader").remove()),this}},{key:"_calculateBorders",value:function(){return{top:this._totalCssByAttribute("border-top-width"),right:this._totalCssByAttribute("border-right-width"),bottom:this._totalCssByAttribute("border-bottom-width"),left:this._totalCssByAttribute("border-left-width")}}},{key:"_calculatePadding",value:function(){return{top:this._totalCssByAttribute("padding-top"),right:this._totalCssByAttribute("padding-right"),bottom:this._totalCssByAttribute("padding-bottom"),left:this._totalCssByAttribute("padding-left")}}},{key:"_totalCssByAttribute",value:function(t){return parseInt(this._$modalDialog.css(t),10)+parseInt(this._$modalContent.css(t),10)+parseInt(this._$modalBody.css(t),10)}},{key:"_updateTitleAndFooter",value:function(){var t=this._$element.data("title")||"",e=this._$element.data("footer")||"";return this._titleIsShown=!1,t||this._config.alwaysShowClose?(this._titleIsShown=!0,this._$modalHeader.css("display","").find(".modal-title").html(t||" ")):this._$modalHeader.css("display","none"),this._footerIsShown=!1,e?(this._footerIsShown=!0,this._$modalFooter.css("display","").html(e)):this._$modalFooter.css("display","none"),this}},{key:"_showYoutubeVideo",value:function(t,e){var i=this._getYoutubeId(t),o=t.indexOf("&")>0?t.substr(t.indexOf("&")):"",a=this._$element.data("width")||560,s=this._$element.data("height")||a/(560/315);return this._showVideoIframe("//www.youtube.com/embed/"+i+"?badge=0&autoplay=1&html5=1"+o,a,s,e)}},{key:"_showVimeoVideo",value:function(t,e){var i=this._$element.data("width")||500,o=this._$element.data("height")||i/(560/315);return this._showVideoIframe(t+"?autoplay=1",i,o,e)}},{key:"_showInstagramVideo",value:function(t,e){var i=this._$element.data("width")||612,o=i+80;return t="/"!==t.substr(-1)?t+"/":t,e.html('<iframe width="'+i+'" height="'+o+'" src="'+t+'embed/" frameborder="0" allowfullscreen></iframe>'),this._resize(i,o),this._config.onContentLoaded.call(this),this._$modalArrows&&this._$modalArrows.css("display","none"),this._toggleLoading(!1),this}},{key:"_showVideoIframe",value:function(t,e,i,o){return i=i||e,o.html('<div class="embed-responsive embed-responsive-16by9"><iframe width="'+e+'" height="'+i+'" src="'+t+'" frameborder="0" allowfullscreen class="embed-responsive-item"></iframe></div>'),this._resize(e,i),this._config.onContentLoaded.call(this),this._$modalArrows&&this._$modalArrows.css("display","none"),this._toggleLoading(!1),this}},{key:"_showHtml5Media",value:function(t,e){var i=this._getRemoteContentType(t);if(!i)return this._error(this._config.strings.type);var o="";o=i.indexOf("audio")>0?"audio":"video";var a=this._$element.data("width")||560,s=this._$element.data("height")||a/(560/315);return e.html('<div class="embed-responsive embed-responsive-16by9"><'+o+' width="'+a+'" height="'+s+'" preload="auto" autoplay controls class="embed-responsive-item"><source src="'+t+'" type="'+i+'">'+this._config.strings.type+"</"+o+"></div>"),this._resize(a,s),this._config.onContentLoaded.call(this),this._$modalArrows&&this._$modalArrows.css("display","none"),this._toggleLoading(!1),this}},{key:"_loadRemoteContent",value:function(e,i){var o=this,a=this._$element.data("width")||560,s=this._$element.data("height")||560,n=this._$element.data("disableExternalCheck")||!1;return this._toggleLoading(!1),n||this._isExternal(e)?(i.html('<iframe src="'+e+'" frameborder="0" allowfullscreen></iframe>'),this._config.onContentLoaded.call(this)):i.load(e,t.proxy(function(){return o._$element.trigger("loaded.bs.modal")})),this._$modalArrows&&this._$modalArrows.css("display","none"),this._resize(a,s),this}},{key:"_isExternal",value:function(t){var e=t.match(/^([^:\/?#]+:)?(?:\/\/([^\/?#]*))?([^?#]+)?(\?[^#]*)?(#.*)?/);return"string"==typeof e[1]&&e[1].length>0&&e[1].toLowerCase()!==location.protocol||"string"==typeof e[2]&&e[2].length>0&&e[2].replace(new RegExp(":("+{"http:":80,"https:":443}[location.protocol]+")?$"),"")!==location.host}},{key:"_error",value:function(t){return console.error(t),this._containerToUse().html(t),this._resize(300,300),this}},{key:"_preloadImageByIndex",value:function(e,i){if(this._$galleryItems){var o=t(this._$galleryItems.get(e),!1);if(void 0!==o){var a=o.attr("data-remote")||o.attr("href");return("image"===o.attr("data-type")||this._isImage(a))&&this._preloadImage(a,!1),i>0?this._preloadImageByIndex(e+1,i-1):void 0}}}},{key:"_preloadImage",value:function(e,i){var o=this;i=i||!1;var a=new Image;return i&&function(){var s=setTimeout(function(){i.append(o._config.loadingMessage)},200);a.onload=function(){s&&clearTimeout(s),s=null;var e=t("<img />");return e.attr("src",a.src),e.addClass("img-fluid"),e.css("width","100%"),i.html(e),o._$modalArrows&&o._$modalArrows.css("display",""),o._resize(a.width,a.height),o._toggleLoading(!1),o._config.onContentLoaded.call(o)},a.onerror=function(){return o._toggleLoading(!1),o._error(o._config.strings.fail+" "+e)}}(),a.src=e,a}},{key:"_swipeGesure",value:function(){return this._touchendX<this._touchstartX?this.navigateRight():this._touchendX>this._touchstartX?this.navigateLeft():void 0}},{key:"_resize",value:function(e,i){i=i||e,this._wantedWidth=e,this._wantedHeight=i;var o=e/i,a=this._padding.left+this._padding.right+this._border.left+this._border.right,s=this._config.doc.body.clientWidth>575?20:0,n=this._config.doc.body.clientWidth>575?0:20,l=Math.min(e+a,this._config.doc.body.clientWidth-s,this._config.maxWidth);e+a>l?(i=(l-a-n)/o,e=l):e+=a;var r=0,d=0;this._footerIsShown&&(d=this._$modalFooter.outerHeight(!0)||55),this._titleIsShown&&(r=this._$modalHeader.outerHeight(!0)||67);var h=this._padding.top+this._padding.bottom+this._border.bottom+this._border.top,g=parseFloat(this._$modalDialog.css("margin-top"))+parseFloat(this._$modalDialog.css("margin-bottom")),_=Math.min(i,t(window).height()-h-g-r-d,this._config.maxHeight-h-r-d);i>_&&(e=Math.ceil(_*o)+a),this._$lightboxContainer.css("height",_),this._$modalDialog.css("flex",1).css("maxWidth",e);var c=this._$modal.data("bs.modal");if(c)try{c._handleUpdate()}catch(t){c.handleUpdate()}return this}}],[{key:"_jQueryInterface",value:function(e){var i=this;return e=e||{},this.each(function(){var a=t(i),s=t.extend({},o.Default,a.data(),"object"==typeof e&&e);new o(i,s)})}}]),o}();t.fn[o]=n._jQueryInterface,t.fn[o].Constructor=n,t.fn[o].noConflict=function(){return t.fn[o]=a,n._jQueryInterface}}(jQuery)}(jQuery);
--- a/src/pyams_default_theme/resources/less/pyams-default.less Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/resources/less/pyams-default.less Tue Dec 04 15:53:25 2018 +0100
@@ -18,68 +18,7 @@
body {
font-family: Lato, Helvetica, Arial, sans-serif;
margin: 0 auto;
-
- .header-simple {
- .regularbanner {
- position: relative;
-
- picture,
- img {
- &.regularbanner__media {
- width: 100%;
- }
- &.logo {
- position: absolute;
- top: 10px;
- left: 10px;
- max-height: ~"calc(100% - 20px)";
- }
- }
- }
- }
- .affix {
- top: 0;
- width: 100%;
- z-index: 9999 !important;
- opacity: 0.95;
- transition: all .5s ease-in-out;
- }
- .affix ~ .container-fluid {
- position: relative;
- top: 50px;
- }
- .navbar {
- margin-bottom: 20px;
- background-color: white;
- border: 1px solid #39413b;
- font-family: Oswald, Helvetica, Arial, Sans-Serif;
- transition: all .5s ease-in-out;
-
- a,
- a:active,
- a:visited {
- color: #39413b;
- }
- li.active,
- .icon-bar {
- background-color: #a5bcaa;
- }
- &.affix {
- background-color: #39413b;
-
- a {
- color: white;
- }
- &:hover {
- a:hover {
- color: #39413b;
- }
- }
- .icon-bar {
- background-color: white;
- }
- }
- }
+ overflow-x: hidden;
}
h1,
@@ -91,6 +30,95 @@
font-family: Oswald, Helvetica, Arial, Sans-Serif;
}
+hr {
+ &.simple {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ }
+ &.noborder {
+ border: 0;
+ }
+}
+
+
+/**
+ * Header styles
+ */
+.header-simple {
+ .regularbanner {
+ position: relative;
+
+ picture,
+ img {
+ &.regularbanner__media {
+ width: 100%;
+ }
+ &.logo {
+ position: absolute;
+ top: 10px;
+ left: 10px;
+ max-height: ~"calc(100% - 20px)";
+ }
+ }
+ }
+}
+.affix {
+ top: 0;
+ width: 100%;
+ z-index: 9999 !important;
+ opacity: 0.95;
+ transition: all .5s ease-in-out;
+}
+.affix ~ .container-fluid {
+ position: relative;
+ top: 50px;
+}
+.navbar {
+ margin-bottom: 20px;
+ background-color: white;
+ border: 1px solid #39413b;
+ font-family: Oswald, Helvetica, Arial, Sans-Serif;
+ transition: all .5s ease-in-out;
+
+ a,
+ a:active,
+ a:visited {
+ color: #39413b;
+ }
+ li.active,
+ .icon-bar {
+ background-color: #a5bcaa;
+ }
+ &.affix {
+ background-color: #39413b;
+
+ a {
+ color: white;
+ }
+ .dropdown-menu {
+ a {
+ color: #39413b;
+ }
+ }
+ &:hover {
+ a:hover {
+ color: #39413b;
+ }
+ }
+ .icon-bar {
+ background-color: white;
+ }
+ }
+}
+
+.breadcrumb {
+ margin-bottom: 1rem;
+}
+
+.page-header {
+ margin-top: 2rem;
+}
+
.portal-page {
.slot {
@media only screen and (min-width: 1200px) {
@@ -116,6 +144,62 @@
}
}
+.toolbox {
+ display: flex;
+ flex-direction: column;
+
+ button {
+ text-align: left;
+ display: flex;
+ align-items: center;
+
+ i.fa {
+ display: inline-block;
+ margin-right: 1rem;
+ }
+ }
+}
+
+@media only screen and (min-width: 1340px) {
+ .col-lg-12 .portlet > section.wrapper {
+ margin-left: calc(-50vw + 50%);
+ margin-right: calc(-50vw + 50%);
+ }
+}
+
+@media only screen and (min-width: 1052px) {
+ .col-md-12 .portlet > section.wrapper {
+ margin-left: calc(-50vw + 50%);
+ margin-right: calc(-50vw + 50%);
+ }
+}
+
+@media only screen and (max-width: 1051px) {
+ .col-sm-12 .portlet > section.wrapper {
+ margin-left: calc(-50vw + 50%);
+ margin-right: calc(-50vw + 50%);
+ }
+}
+
+@media only screen and (max-width: 767px) {
+ .navbar {
+ &.affix {
+ .dropdown-menu {
+ background-color: #39413b;
+
+ a {
+ color: white;
+ }
+ }
+ }
+ }
+
+ .col-xs-12 .portlet > section.wrapper {
+ margin-left: calc(-50vw + 50%);
+ margin-right: calc(-50vw + 50%);
+ }
+}
+
/**
* Summary styles
@@ -142,6 +226,37 @@
}
}
+
+/**
+ * Panels
+ */
+.panels {
+ margin-top: 2rem;
+}
+
+
+/**
+ * Search results
+ */
+
+.search-results {
+ .breadcrumb:empty {
+ margin: 0;
+ padding: 0;
+ }
+ .thumbnail {
+ &.pull-left {
+ margin-right: 3rem;
+ }
+ }
+ .tags {
+ span {
+ margin: 0 0.2rem;
+ }
+ }
+}
+
+
/**
* Images gallery
*/
@@ -260,3 +375,14 @@
}
}
}
+
+
+/**
+ * Source code
+ */
+
+.source {
+ pre {
+ font-family: 'Anonymous Pro', monospace;
+ }
+}
--- a/src/pyams_default_theme/shared/common/portlet/head.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/shared/common/portlet/head.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,19 +12,14 @@
__docformat__ = 'restructuredtext'
+from zope.interface import Interface
-# import standard library
-
-# import interfaces
from pyams_content.shared.common.portlet.interfaces import ISharedContentHeaderPortletSettings
from pyams_portal.interfaces import IPortalContext, IPortletRenderer
+from pyams_portal.portlet import PortletRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_portal.portlet import PortletRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
-from zope.interface import Interface
from pyams_default_theme import _
--- a/src/pyams_default_theme/shared/site/link.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/shared/site/link.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,8 +12,9 @@
__docformat__ = 'restructuredtext'
-from pyams_content.shared.site.interfaces import IContentLink
-from pyams_default_theme.interfaces import IContentSummaryInfo
+from pyams_content.component.illustration import ILinkIllustration
+from pyams_content.shared.site.interfaces import IContentLink, IExternalContentLink
+from pyams_default_theme.interfaces import IContentNavigationIllustration, IContentSummaryInfo
from pyams_i18n.interfaces import II18n
from pyams_skin.layer import IPyAMSUserLayer
from pyams_utils.adapter import ContextRequestAdapter, adapter_config
@@ -22,6 +23,10 @@
from pyams_default_theme import _
+#
+# Content link adapters
+#
+
@adapter_config(context=(IContentLink, IPyAMSUserLayer), provides=IRelativeURL)
def content_link_relative_url(context, request):
"""Content link relative URL"""
@@ -64,3 +69,46 @@
if not title:
title = _("Consult content")
return self.request.localizer.translate(title)
+
+
+@adapter_config(context=(IContentLink, IPyAMSUserLayer), provides=IContentNavigationIllustration)
+def content_link_illustration_factory(context, request):
+ """Content link illustration factory"""
+ target = context.target
+ if target is not None:
+ return request.registry.queryMultiAdapter((target, request), IContentNavigationIllustration)
+
+
+#
+# External content link adapters
+#
+
+@adapter_config(context=(IExternalContentLink, IPyAMSUserLayer), provides=IRelativeURL)
+class ExternalContentLinkRelativeUrl(ContextRequestAdapter):
+ """External content link relative URL"""
+
+ def get_url(self, display_context=None, view_name=None, query=None):
+ return self.context.url
+
+
+@adapter_config(context=(IExternalContentLink, IPyAMSUserLayer), provides=IContentSummaryInfo)
+class ExternalContentLinkSummaryAdapter(ContextRequestAdapter):
+ """External content link summary adapter"""
+
+ @property
+ def title(self):
+ return II18n(self.context).query_attribute('navigation_title', request=self.request)
+
+ @property
+ def header(self):
+ return II18n(self.context).query_attribute('navigation_header', request=self.request)
+
+ @property
+ def button_title(self):
+ return self.request.localizer.translate(_("Consult content"))
+
+
+@adapter_config(context=(IExternalContentLink, IPyAMSUserLayer), provides=IContentNavigationIllustration)
+def external_content_link_illustration_factory(context, request):
+ """External content link illustration factory"""
+ return request.registry.queryAdapter(context, ILinkIllustration)
--- a/src/pyams_default_theme/shared/site/portlet/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/shared/site/portlet/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -26,13 +26,8 @@
from pyams_default_theme import _
-@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, ISiteContainerSummaryPortletSettings),
- provides=IPortletRenderer)
-@template_config(template='templates/site-summary.pt', layer=IPyAMSLayer)
-class SiteContainerSummaryPortletDefaultRenderer(PortletRenderer):
- """Site container summary portlet default renderer"""
-
- label = _("Site container summary")
+class BaseSiteSummaryPortletRenderer(PortletRenderer):
+ """Base site summary portlet renderer"""
@property
def visible_items(self):
@@ -42,3 +37,22 @@
yield from filter(lambda x: x is not None,
[registry.queryMultiAdapter((item, self.request), IContentSummaryInfo)
for item in container.get_visible_items(self.request)])
+
+
+@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, ISiteContainerSummaryPortletSettings),
+ provides=IPortletRenderer)
+@template_config(template='templates/site-summary.pt', layer=IPyAMSLayer)
+class SiteContainerSummaryPortletDefaultRenderer(BaseSiteSummaryPortletRenderer):
+ """Site container summary portlet default renderer"""
+
+ label = _("Site container summary")
+
+
+@adapter_config(name='summary-panels',
+ context=(IPortalContext, IPyAMSLayer, Interface, ISiteContainerSummaryPortletSettings),
+ provides=IPortletRenderer)
+@template_config(template='templates/site-panels.pt', layer=IPyAMSLayer)
+class SiteContainerSummaryPortletPanelsRenderer(BaseSiteSummaryPortletRenderer):
+ """Site container summary portlet panels renderer"""
+
+ label = _("Vertical panels with panoramic illustrations")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/shared/site/portlet/templates/site-panels.pt Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,35 @@
+<div class="panels" i18n:domain="pyams_default_theme"
+ tal:define="settings view.settings;
+ button_title i18n:settings.button_title;">
+ <h2 tal:condition="settings.title">${i18n:settings.title}</h2>
+ <div tal:repeat="item view.visible_items"
+ class="col-sm-4">
+ <tal:var define="target tales:relative_url(item.context)">
+ <div class="thumbnail pull-left hidden-xs">
+ <a tal:define="illustration tales:pyams_illustration(item.context)"
+ tal:condition="illustration"
+ href="${target}">
+ <tal:if define="image i18n:illustration.data;
+ alt i18n:illustration.alt_title;"
+ condition="image">
+ ${structure:tales:picture(image, lg_thumb='pano', lg_width=4, md_thumb='pano', md_width=4,
+ sm_thumb='pano', sm_width=4, xs_thumb='pano', xs_width=12, alt=alt)}
+ </tal:if>
+ </a>
+ </div>
+ <div>
+ <a href="${target}">
+ <h3>${item.title}</h3>
+ </a>
+ <div class="header">${structure:tales:html(item.header)}</div>
+ <div class="action">
+ <a tal:condition="button_title"
+ href="${target}">
+ <span i18n:translate="">${button_title}</span>
+ </a>
+ </div>
+ </div>
+ </tal:var>
+ </div>
+ <div class="clearfix"></div>
+</div>
\ No newline at end of file
--- a/src/pyams_default_theme/shared/site/portlet/templates/site-summary.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/shared/site/portlet/templates/site-summary.pt Tue Dec 04 15:53:25 2018 +0100
@@ -1,6 +1,7 @@
<div i18n:domain="pyams_default_theme"
tal:define="settings view.settings;
button_title i18n:settings.button_title;">
+ <h2 tal:condition="settings.title">${i18n:settings.title}</h2>
<div class="summary">
<div tal:repeat="item view.visible_items">
<tal:var define="target tales:relative_url(item.context)">
@@ -17,7 +18,9 @@
</a>
</div>
<div>
- <h2>${item.title}</h2>
+ <a href="${target}">
+ <h3>${item.title}</h3>
+ </a>
<div class="header">${structure:tales:html(item.header)}</div>
<div class="action">
<a href="${target}">
--- a/src/pyams_default_theme/shared/view/portlet/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/shared/view/portlet/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,23 +12,33 @@
__docformat__ = 'restructuredtext'
+from persistent import Persistent
+from zope.container.contained import Contained
+from zope.interface import Interface, implementer
+from zope.schema.fieldproperty import FieldProperty
-# import standard library
-
-# import interfaces
from pyams_content.shared.view.portlet.interfaces import IViewItemsPortletSettings
+from pyams_default_theme.shared.view.portlet.interfaces import IViewItemsPortletVerticalRendererSettings
from pyams_portal.interfaces import IPortalContext, IPortletRenderer
+from pyams_portal.portlet import PortletRenderer
from pyams_skin.layer import IPyAMSLayer
-
-# import packages
-from pyams_portal.portlet import PortletRenderer
from pyams_template.template import template_config
from pyams_utils.adapter import adapter_config
-from zope.interface import Interface
+from pyams_utils.factory import factory_config
from pyams_default_theme import _
+@factory_config(provided=IViewItemsPortletVerticalRendererSettings)
+@implementer(IViewItemsPortletVerticalRendererSettings)
+class ViewItemsPortletVerticalRendererSettings(Persistent, Contained):
+ """View items portlet renderer settings"""
+
+ display_illustrations = FieldProperty(IViewItemsPortletVerticalRendererSettings['display_illustrations'])
+ paginate = FieldProperty(IViewItemsPortletVerticalRendererSettings['paginate'])
+ page_size = FieldProperty(IViewItemsPortletVerticalRendererSettings['page_size'])
+
+
@adapter_config(context=(IPortalContext, IPyAMSLayer, Interface, IViewItemsPortletSettings),
provides=IPortletRenderer)
@template_config(template='templates/view-items-list.pt', layer=IPyAMSLayer)
@@ -36,3 +46,6 @@
"""View items portlet renderer"""
label = _("Simple vertical view")
+ weight = 0
+
+ settings_interface = IViewItemsPortletVerticalRendererSettings
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_default_theme/shared/view/portlet/interfaces.py Tue Dec 04 15:53:25 2018 +0100
@@ -0,0 +1,37 @@
+#
+# 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'
+
+from zope.interface import Interface
+from zope.schema import Bool, Int
+
+from pyams_default_theme import _
+
+
+class IViewItemsPortletVerticalRendererSettings(Interface):
+ """View items portlet vertical renderer settings interface"""
+
+ display_illustrations = Bool(title=_("Display illustrations?"),
+ description=_("If 'no', view contents will not display illustrations"),
+ required=True,
+ default=True)
+
+ paginate = Bool(title=_("Paginate?"),
+ description=_("If 'no', results pagination will be disabled"),
+ required=True,
+ default=True)
+
+ page_size = Int(title=_("Page size"),
+ description=_("Number of items per page, if pagination is enabled"),
+ required=False,
+ default=10)
--- a/src/pyams_default_theme/shared/view/portlet/templates/view-items-list.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/shared/view/portlet/templates/view-items-list.pt Tue Dec 04 15:53:25 2018 +0100
@@ -1,6 +1,60 @@
-<ul>
- <li tal:repeat="item view.settings.get_items(request)">
- <a tal:attributes="href tales:relative_url(item)"
- tal:content="i18n:item.title">Title</a>
- </li>
-</ul>
+<div tal:define="settings view.settings;
+ renderer_settings view.renderer_settings;"
+ i18n:domain="pyams_default_theme">
+ <h2>${i18n:settings.title}</h2>
+ <div class="search-results"
+ tal:define="start int(request.params.get('start', 0));
+ limit (start + renderer_settings.page_size) if renderer_settings.paginate else 999;
+ items settings.get_items(request, limit);
+ global count 0;">
+ <tal:loop repeat="item items">
+ <div tal:define="global count count +1;
+ target tales:relative_url(item);">
+ <tal:if condition="renderer_settings.display_illustrations">
+ <div class="thumbnail pull-left col-lg-3 col-md-3 col-sm-4 hidden-xs"
+ tal:define="illustration tales:pyams_illustration(item)"
+ tal:condition="illustration">
+ <a href="${target}">
+ <tal:if define="image i18n:illustration.data;
+ alt i18n:illustration.alt_title;"
+ condition="image">
+ ${structure:tales:picture(image, lg_thumb='pano', lg_width=3, md_thumb='pano', md_width=3, sm_thumb='pano',
+ sm_width=4, xs_thumb='pano', xs_width=12, alt=alt, css_class='result_media')}
+ </tal:if>
+ </a>
+ </div>
+ </tal:if>
+ <div>
+ <a href="${target}">
+ <h3>${i18n:item.title}</h3>
+ </a>
+ <div class="breadcrumbs">${structure:tales:breadcrumbs(item)}</div>
+ <div class="tags">${structure:tales:tags(item)}</div>
+ <div class="header"
+ tal:define="header i18n:item.header">
+ ${structure:tales:html(header)}
+ </div>
+ </div>
+ </div>
+ <div class="clearfix"></div>
+ </tal:loop>
+ <footer tal:condition="renderer_settings.paginate">
+ <ul class="pager">
+ <li class="previous"
+ tal:condition="start > 0">
+ <a href="${request.path_url}?start=${start - renderer_settings.page_size}">
+ <span aria-hidden="true">←</span>
+ <i18n:var translate="">Previous</i18n:var>
+ </a>
+ </li>
+ <li class="next"
+ tal:condition="count == renderer_settings.page_size">
+ <a href="${request.path_url}?start=${start + count}">
+ <i18n:var translate="">Next</i18n:var>
+ <span aria-hidden="true">→</span>
+ </a>
+ </li>
+ </ul>
+ </footer>
+ </div>
+</div>
--- a/src/pyams_default_theme/viewlet/breadcrumb/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/viewlet/breadcrumb/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -12,36 +12,29 @@
__docformat__ = 'restructuredtext'
-from pyramid.location import lineage
from zope.interface import Interface
+from zope.location import ILocation
-from pyams_skin.interfaces.viewlet import IBreadcrumbItem
+from pyams_skin.interfaces.viewlet import IBreadcrumbs
from pyams_skin.layer import IPyAMSUserLayer
-from pyams_skin.viewlet.breadcrumb import BreadcrumbsContentProvider as BaseBreadcrumbsContentProvider
-from pyams_template.template import template_config
+from pyams_skin.viewlet.breadcrumb import BreadcrumbsContentProvider, BreadcrumbsAdapter as BaseBreadcrumbsAdapter
+from pyams_template.template import override_template
+from pyams_utils.adapter import adapter_config
from pyams_utils.interfaces.url import DISPLAY_CONTEXT
-from pyams_viewlet.viewlet import contentprovider_config
-@contentprovider_config(name='pyams.breadcrumbs', layer=IPyAMSUserLayer, view=Interface)
-@template_config(template='breadcrumbs.pt', layer=IPyAMSUserLayer)
-class BreadcrumbsContentProvider(BaseBreadcrumbsContentProvider):
- """Breadcrumbs content provider"""
+@adapter_config(context=(ILocation, IPyAMSUserLayer, Interface), provides=IBreadcrumbs)
+class BreadcrumbsAdapter(BaseBreadcrumbsAdapter):
+ """Breadcrumbs adapter"""
@property
def items(self):
- source = None
- registry = self.request.registry
+ source = self.request.annotations.get(DISPLAY_CONTEXT)
if source is None:
- source = self.request.annotations.get(DISPLAY_CONTEXT)
- if source is None:
- source = self.request.context
+ source = self.request.context
if source is not None:
- for context in reversed(tuple(lineage(source))):
- item = registry.queryMultiAdapter((context, self.request, self.view), IBreadcrumbItem)
- if item is None:
- item = registry.queryMultiAdapter((context, self.request), IBreadcrumbItem)
- if item is None:
- item = registry.queryAdapter(context, IBreadcrumbItem)
- if item is not None:
- yield item
+ yield from self.get_items(source)
+
+
+override_template(context=BreadcrumbsContentProvider, layer=IPyAMSUserLayer,
+ template='breadcrumbs.pt')
--- a/src/pyams_default_theme/viewlet/breadcrumb/breadcrumbs.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/viewlet/breadcrumb/breadcrumbs.pt Tue Dec 04 15:53:25 2018 +0100
@@ -1,6 +1,5 @@
-<ol class="breadcrumb">
- <li tal:repeat="item view.items">
- <a class="${'active' if repeat.item.end else None}"
- href="${item.url}">${item.label}</a>
- </li>
-</ol>
\ No newline at end of file
+<ol class="breadcrumb"><li
+ tal:repeat="item view.items"><a
+ tal:omit-tag="not:item.label"
+ class="${'active' if repeat.item.end else None}"
+ href="${item.url}">${item.label}</a></li></ol>
\ No newline at end of file
--- a/src/pyams_default_theme/viewlet/tag/__init__.py Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/viewlet/tag/__init__.py Tue Dec 04 15:53:25 2018 +0100
@@ -10,16 +10,18 @@
# FOR A PARTICULAR PURPOSE.
#
-
__docformat__ = 'restructuredtext'
from pyramid.decorator import reify
+from zope.contentprovider.interfaces import IContentProvider
from zope.interface import Interface
from pyams_content.component.theme import ITagsInfo, ITagsManager
from pyams_sequence.reference import get_reference_target
from pyams_skin.layer import IPyAMSLayer, IPyAMSUserLayer
from pyams_template.template import template_config
+from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
+from pyams_utils.interfaces.tales import ITALESExtension
from pyams_viewlet.viewlet import ViewContentProvider, contentprovider_config
@@ -49,3 +51,19 @@
def tags(self):
tags = self.tags_info.tags or ()
yield from sorted(tags, key=lambda x: (x.order or 999, x.alt or x.label))
+
+
+@adapter_config(name='tags', context=(Interface, Interface, Interface), provides=ITALESExtension)
+class TagsTalesExtension(ContextRequestViewAdapter):
+ """tales:tags(context) TALES extension"""
+
+ def render(self, context=None):
+ if context is None:
+ context = self.context
+ provider = self.request.registry.queryMultiAdapter((context, self.request, self.view), IContentProvider,
+ name='pyams.tags')
+ if provider is not None:
+ provider.update()
+ return provider.render()
+ else:
+ return ''
--- a/src/pyams_default_theme/viewlet/tag/templates/tags.pt Tue Nov 20 15:19:28 2018 +0100
+++ b/src/pyams_default_theme/viewlet/tag/templates/tags.pt Tue Dec 04 15:53:25 2018 +0100
@@ -1,12 +1,12 @@
<div i18n:domain="pyams_default_theme"
tal:define="target view.search_target">
<tal:loop repeat="tag view.tags">
- <span class="label label-primary">
- <a tal:omit-tag="target is None"
- tal:define="href tales:absolute_url(target)"
- href="${href}/++tag++${tag.label}">
- ${tag.alt or tag.label}
- </a>
- </span>
+ <a tal:omit-tag="target is None"
+ tal:define="href tales:absolute_url(target)"
+ href="${href}?tag=${tag.label}">
+ <span class="badge badge-primary">
+ #${tag.alt or tag.label}
+ </span>
+ </a>
</tal:loop>
</div>
\ No newline at end of file