Coder Social home page Coder Social logo

ftw.theming's Introduction

Add the package as dependency to your setup.py:

setup(...
      install_requires=[
        ...
        'ftw.theming',
      ])

or to your buildout configuration:

[instance]
eggs += ftw.theming

and rerun buildout.

The SCSS registry is configured with ZCML and contains all SCSS resources from ftw.theming, addons, the theme and policy packages.

The @@theming-resources (on any navigation root) lists all resources.

The registry allows to register resources to a list of fix slots. These are the available slots, sorted by inclusion order:

  • top
  • variables
  • mixins
  • ftw.theming
  • addon
  • theme
  • policy
  • bottom

Adding SCSS resources is done in the ZCML of a package. The SCSS should always go into the same package where the styled templates are.

<configure
    xmlns:theme="http://namespaces.zope.org/ftw.theming"
    xmlns:zcml="http://namespaces.zope.org/zcml"
    i18n_domain="ftw.tabbedview">

    <configure zcml:condition="installed ftw.theming">
      <include package="ftw.theming" />

      <theme:scss
          file="resources/tabbed.scss"
          slot="addon"
          profile="ftw.tabbedview:default"
          />
    </configure>

</configure>
  • file: relative path to the SCSS file (required)
  • slot: name of the slot (see slots section, default: addon)
  • profile: Generic Setup profile required to be installed (default: no profile, e.g. my.package:default)
  • for: context interface (default: INavigationRoot)
  • layer: request layer interface (default: Interface)
  • before: name of the resource after which this resource should be ordered (within the same slot).
  • after: name of the resource before which this resource should be ordered (within the same slot)
<configure
    xmlns:theme="http://namespaces.zope.org/ftw.theming"
    xmlns:zcml="http://namespaces.zope.org/zcml"
    i18n_domain="plonetheme.fancy">

    <include package="ftw.theming" />

    <theme:resources
        slot="theme"
        profile="plonetheme.fancy:default"
        layer="plonetheme.fancy.interfaces.IFancyTheme">

        <theme:scss file="resources/foo.scss" />
        <theme:scss file="resources/bar.scss" />

    </theme:resources>

</configure>
  • slot: name of the slot (see slots section, default: addon)
  • profile: Generic Setup profile required to be installed (default: no profile, e.g. my.package:default)
  • for: context interface (default: INavigationRoot)
  • layer: request layer interface (default: Interface)
  • file: relative path to the SCSS file (required)
  • before: name of the resource after which this resource should be ordered (within the same slot).
  • after: name of the resource before which this resource should be ordered (within the same slot)

Each resource has an automatically generated name, which can be looked up in the @@theming-resources-view. The resource has the format [package]:[relative path].

The SCSS resources are ordered when retrieved from the registry, so that the order is as consistent as possible.

Ordering priority:

1. the resource's slot (see the slot section below) 1. the before and after options (topological graph sorting), within each slot. 1. the ZCML load order of the resources

Be aware that the ZCML load order is usally random.

A resource factory is a callable (accepting context and request) which returns a DynamicSCSSResource object. Since the callable instantiates the resource, it's content can be created dynamically.

<configure
    xmlns:theme="http://namespaces.zope.org/ftw.theming"
    xmlns:zcml="http://namespaces.zope.org/zcml"
    i18n_domain="plonetheme.fancy">

    <include package="ftw.theming" />

    <theme:scss_factory factory=".dynamic_resource_factory" />

</configure>
from ftw.theming.interfaces import ISCSSResourceFactory
from ftw.theming.resource import DynamicSCSSResource
from zope.interface import provider

@provider(ISCSSResourceFactory)
def dynamic_resource_factory(context, request):
    return DynamicSCSSResource('dynamic.scss', slot='addon', source='$color: blue;',
                               cachekey='1')

When generating the SCSS is expensive in time, you should subclass the DynamicSCSSResource class and implement custom get_source and get_cachekey methods. The get_cachekey should be very lightweight and cheap: it is called on every pageview. It should return any string and only change the return value when the get_source result will change.

from Products.CMFCore.utils import getToolByName
from ftw.theming.interfaces import ISCSSResourceFactory
from ftw.theming.resource import DynamicSCSSResource
from zope.annotation import IAnnotations
from zope.interface import provider


class CustomSCSSResource(DynamicSCSSResource):

      def get_source(self, context, request):
          return 'body { background-color: $primary-color; }'

      def get_cachekey(self, context, request):
          portal = getToolByName(context, 'portal_url').getPortalObject()
          config = IAnnotations(portal).get('my-custom-config', {})
          return config.get('last-change-timestamp', '1')

@provider(ISCSSResourceFactory)
def dynamic_resource_factory(context, request):
    return CustomSCSSResource('my.package:custom.scss', slot='addon')

When ftw.theming is installed, a control panel is added, listing the SCSS resources and the default SCSS variables. The controlpanel views are available on any navigation root.

ftw.theming provides a portal type icon registry. The default iconset is font-awesome.

Portal type icons are declared in the scss file of the addon package. It is possible to support multiple icon sets by declaring icons for each iconset:

@include portal-type-font-awesome-icon(repository-folder, leaf);
@include portal-type-icon(repository-folder, "\e616", customicons);

Using those mixins does not generate any CSS yet, nor does it introduce dependency to those iconset. It simply stores this information in a list to be processed later.

A theme or policy package may change the iconset. The standard iconset is font-awesome. Changing the iconset should be done in an SCSS file in the variables slot.

$standard-iconset: customicons;

The default iconset is font-awesome, which is automatically loaded and the necessary CSS is generated when the $standard-iconset variable is font-awesome.

For having custom iconsets an SCSS file must be registered in the bottom slot. This is usually done by a theme or policy package.

The SCSS file should apply the necessary CSS only when the $standard-iconset is set to this iconset:

@if $standard-iconset == customicons {

  @font-face {
    font-family: 'customicons';
    src:url('#{$portal-url}/++theme++foo/fonts/customicons.eot?-fa99j8');
    src:url('#{$portal-url}/++theme++foo/fonts/customicons.eot?#iefix-fa99j8') format('embedded-opentype'),
    url('#{$portal-url}/++theme++foo/fonts/customicons.woff?-fa99j8') format('woff'),
    url('#{$portal-url}/++theme++foo/fonts/customicons.ttf?-fa99j8') format('truetype'),
    url('#{$portal-url}/++theme++foo/fonts/customicons.svg?-fa99j8#opengever') format('svg');
    font-weight: normal;
    font-style: normal;
  }

  .icons-on [class^="contenttype-"],
  .icons-on [class*=" contenttype-"] {
    &:before {
      font-family: 'customicons';
      content: "x";
      text-align:center;
      position: absolute;
    }
  }

  @each $type, $value in get-portal-type-icons-for-iconset(font-awesome) {
    body.icons-on .contenttype-#{$type} {
      &:before {
        content: $value;
      }
    }
  }
}

The embed-resource function embeds a resource (e.g. svg) as base64 encoded url.

Example:

.something {
    background: embed-resource("images/foo.svg");
}

The function is able to fill colors in SVGs. This can be done with either XPath or CSS selectors.

Since lxml is used for filling the SVGs and SVGs are namespaced XML documents, the expressions must be namespaced as well. This leads to problems when converting certain CSS selectors since CSS does not support namespaces.

Example:

.foo {
    background: embed-resource("soccer.svg", $fill-css:('#pentagon', red));
}

.bar {
    background: embed-resource("soccer.svg", $fill-xpath:('//*[@id="black_stuff"]/*[local-name()="g"][1]', red));
}

It is also possible to fill multiple different colors at once by repeating the selector, color pattern.

.foo {
    background: embed-resource("soccer.svg", $fill-css:('.black-stuff', black, '.red-stuff', red, '.white-stuff', white));
}

ftw.theming provides mixins for most common media queries:

  • small (480px)
  • medium (800px)
  • large (1024)

Example usage:

#container {
    width: 1600px;

    @include screen-medium {
        width:1000px;
    }
    @include screen-small {
        width:500px;
    }
}
@include font-face($name: 'VerdanaRegular', $path: '++resource++nidau.web/fonts/Verdana');

The file-extension for the $path argument is going to be concatenated automatically. Both woff and woff2 must be provided.

The mixin then produces the following css code:

@font-face {
  font-family: 'VerdanaRegular';
  font-style: normal;
  font-weight: normal;
  src: url("++resource++nidau.web/fonts/Verdana.woff2") format(woff2),
    url("++resource++nidau.web/fonts/Verdana.woff") format(woff);
}

@font-face {
  font-family: 'VerdanaBold';
  font-style: normal;
  font-weight: bold;
  src: url("++resource++nidau.web/fonts/Verdana-Bold.woff2") format(woff2),
    url("++resource++nidau.web/fonts/Verdana-Bold.woff") format(woff);
}

This package is copyright by 4teamwork.

ftw.theming is licensed under GNU General Public License, version 2.

ftw.theming's People

Contributors

jone avatar bierik avatar maethu avatar elioschmutz avatar nachtalb avatar mbaechtold avatar lowks avatar

Stargazers

Tiberiu Ichim avatar

Watchers

Thomas Buchberger avatar Timon Tschanz avatar Lukas Graf avatar  avatar Philippe Gross avatar 4teamwork Jenkins avatar James Cloos avatar Bernhard Bühlmann avatar Murat Tokmak avatar  avatar Linus Luginbühl avatar Furkan Kalınsaz avatar  avatar Fabian Guyer avatar Nicola Lorenz avatar Marco Baumgartner avatar  avatar Daniel Jowett avatar

Forkers

lowks starzel

ftw.theming's Issues

What about libsass-python?? Instead of pyScss

The reason why I come up with this is:
I experienced some strange behavior with mixins and calculations spreaded over multiple scss files.

I guess those are issues with pyScss. Could it be a good idea to switch?

Make theming.css URL available through traversing

The function which generates the theming.css URL (with the right cache key) is currently importable as function.
But when it should be used in a custom template it would be nice to be able to reach it through traversing, so that it could be done directly in the template.

Example:
Loading the CSS in the TinyMCE iframe:
OneGov/plonetheme.onegovbear#44

Reinstall Problem

After installing plonetheme.blueberry.standard (1.8.5) together with ftw.theming (base) (1.9.0), all is fine with the new theme.

But if you reinstall ftw.theming (base) under portal_quickinstaller, the theme will break.. site will go back to Sunburst theme and impossible to recover plone instance to the new theme.

Using Plone 4.3.12

Earlier I was trying to upgrade ftw.theming 1.7.1 to 1.9.0

hyphons mixin, incl. fallback

The chrome fallback should be integrated in the ftw.theming hyphens mixin.
This term:

@media screen and (-webkit-min-device-pixel-ratio:0) and (min-resolution:.001dpcm) {
word-break: break-all;
}

So the default behaviour should include the fallback. But I would recommend to have a parameter to change this behaviour @include hyphens(false).

More safe SCSS loading.

Issue:

  • Deployment from source
  • git pull may remove a scss from the filesystem
  • But the registry still tries to access the file, which leads to a broken theming.css.

Can we make this more safe? The issue is obviously only there if a file will be removed. Adding a new one is OK still the registry don't know the file yet.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.