Plone Mockup is an attempt to separate Plone, the user interface, from Plone, the server. It leverages Patterns to create a library of rich interaction patterns triggered by CSS classes and configured via HTML5 data attributes.

The mockup is a fully functional prototype of Plone and its bundles. As it is realised entirely in HTML5 and Javascript, it can be run in a browser without the need for a full Plone installation; therefore making it easy to showcase Plone's UI or developing a new theme. Using diazo it is possible to integrate other backends alongside (or instead of) Plone.

Use it now!

The only requirements to bootstrap Plone mockup are git and npm .

Make sure you use latest version of nodejs and npm.

Then check out the repository from GitHub:

              git clone git://github.com/plone/mockup.git

And bootstrap your environment:

              cd mockup
              make bootstrap

To build all bundles just do:

make

And you can run tests with:

make test

Right now tests are Build Status.

See it in action!

Here are all the interactions we have, listed in alphabetical order:

AutoToc

Generates a TOC by parsing the HTML of the page and identifying sections (via h[123456] tags).

Demo

DateTime

Allows the user to select a date (with or without time) through a calendar.

Demo

Expose

Exposes the focused element by darkening everything else on the page. Useful to focus the user attention on a particular area.

Demo

Modal

Creates a modal dialog (also called overlay).

Demo

Select2

An advanced selection widget, useful for tags, autocompletes, multiple or single selections from any kind of data source (with search!).

Demo

Bundles

TODO

Current CMFPlone ECMA scripts status: Google doc for keeping track of current status of CMFPlone/ecma_scripts stuff

Patterns

Patterns are a set of conventions to configure interaction via markup. If you have developed some Javascript interaction (for example, a dropdown menu) it's quite likely that you've already used the basic concept behind patterns.

Basically, almost every jQuery plugin expects a certain kind of markup to be present, and then expects you to initialize the widget by picking out the root element of the widget and pass some options to it. For example you might have this very basic markup for a datetime widget:

<input id="foo" />

And then you are expected to call some Javascript to initialize it (and set options):

$('#foo').datetime({
  format: 'mmmm d, yyyy',
  formatSubmit: 'yyyy-mm-dd'
});

Then you might find it a little bit tedious to call that Javascript for every date widget that's there, so you mark all the <input /> tags that you want to turn into datepickers with a specific CSS class, and call that line of code just once when the DOM is loaded.

<input id="date-picker-1" class="date-picker" />
<input id="date-picker-2" class="date-picker" />
$(document).ready(function() {
  $('input.date-picker').datetime({
    format: 'mmmm d, yyyy',
    formatSubmit: 'yyyy-mm-dd'
  });
});

If you got at this stage already in your Javascript code, you are already using the basic idea behind patterns.

Why is Patterns better than this?

Patterns has of course more to offer than just this basic approach: automatic binding (and re-binding after reloads), taking the options from the DOM via data-* attributes, and a unified, coherent approach.

Is this related to Patternslib?

TL;DR
Yes. But we provide a different set of interactions.
Long story kept long
TODO

Automatic binding

Automatic binding relieves us of the problem of initializing a widget from the markup. In our initial example, we actually had to manually bind the initialization routine to the page loading (therefore, when the page is loaded, all the elements marked as interactive widgets will be initialized). This works fine as long as we don't start replacing parts of the DOM with HTML coming from the backend or, say, Javascript templates.

If we start doing that, and especially if the replaced parts of the DOM contains one or more interactive widgets, we have to rebind them all, which is quite a tedious thing to code.

Patterns instead, will automatically initialize, upon page loading, all the interactive widgets it find in the document, and you can also tell it to rebind all the widgets it finds in a particular section of the page, when for example we have replaced the content of that section:

define([
  'jquery',
  'js/patterns/base',
  'jam/Patterns/src/registry'
], function($, Base, registry, undefined) {
  // Stuff etc
  var rerender($element) {
      $element.load(
          'http://example.com/my-html',
          function(response.status, request) {
              // Rebinds every pattern found in the AJAX-loaded HTML
              registry.scan($element);
          }
      );
  }
});

This is a great improvement over the "manual" way, where rebinding could take tens of lines of code or even more for complex examples: here, we're down to one line that will always work even if we have no idea of which widgets will get in.

Pattern options

Patterns can take options in two ways: from the DOM or via the jQuery interface. It is highly recommended to use the DOM interface, since it offers a lot more flexibility compared to the jQuery approach. Also, if we wish to use the automatic binding and rebinding functionality, the DOM approach is more straightforward and hassle-free.

If we put options in the DOM, we have to use HTML5 data attributes. It's not necessary to put the options directly on the root node of the widget (the one with the pat-* class), since Patterns will also scan all the parents of that node from the bottom upwards, so we can for example put the options just once on the <body /> tag and have all the widgets use the same set of options:

<body data-datetime-format="d-mmmm-yyyy@HH:MM"
      data-datetime-ampm="true"
      data-datetime-pickadateMonthSelector="false">
  <!-- Both widgets use the same options -->
  <input class="pat-datetime" />
  <input class="pat-datetime" />
<body>

But if we need to override some options for a certain widget (or an entire DOM section) we can just put it on the node or on whatever DOM element wraps the section:

<body data-datetime-format="d-mmmm-yyyy@HH:MM"
      data-datetime-ampm="true">
  <input class="pat-datetime" />  <!-- There's a month dropdown here -->
  <div data-datetime-pickadateMonthSelector="false">
    <input class="pat-datetime" /> <!-- but no month dropdown here! -->
    <input class="pat-datetime" /> <!-- And here as well -->
  </div>
<body>

jQuery interface

Patterns can also be used as a jQuery plugin, passing options as with any other jQuery plugin:

$('.pat-datetime').patternDatetime({
  pickadateYearSelector: true
});

In this case the options passed to the jQuery function will take precedence over the ones defined in the DOM, although the parents will still be scanned and the options defined there will be picked up if they are not overridden in the jQuery call:

{
  showAMPM: true,
  format: "d-mmmm-yyyy@HH:MM",
  pickadateMonthSelector: false,
  pickadateYearSelector: true
}

Making a pattern

TODO

Testing the pattern

TODO