Wednesday, June 28, 2017

Plone 5 custom views using Rapido 1.1.1

After you've created a custom content type through the web (TTW), you'll want a custom view to go with it. In this simple example we create a custom youtube page content type and a supporting view all TTW.

Step 1 - Create a new content type

Start by creating the content type through the Dexterity Types control panel.

Site Setup > Dexterity Types

Select and clone the "Page".

.. ..
Then add a "youtube_url" field.

After adding your first "Youtube page" you'll notice that the default view isn't showing us the "youtube_url" field that we added. We'll fix that in the next step.

Step 2 - Create a custom rapido view

To create a custom view (sometimes called an "extra view"), start by creating a rapido app, we'll call ours views and to this we'll add a youtube-page block.
See the structure in the gist below:
.. ..
The video below explores the building blocks of our custom view. After some tinkering we settle on the id youtube-page-view for our view.
.. ..

Gotchas with registering view ids

What was not recorded in the video was the fact that the view id youtube-page had been used in the context of a different rapdio block (I was practicing before the real recording). If you were paying careful attention to the demo video you may have noticed some unusual behaviour when trying to use the view named youtube-page. When you define a view id and then change it later on, the id expects to work with the originally registered block. I've found that restarting the instance resolves this issue.

Wednesday, June 14, 2017

Plone theming: Injecting a class into an existing tag with Diazo and xsl

In a recent post (https://community.plone.org/t/textareas-not-displaying-existing-content-when-my-theme-is-enabled/4117/2?u=pigeonflight) I mentioned a Diazo rule where I was injecting a new class into a tag, I used an <xsl:template>.

The following example adds a special class "gl-textarea" to all <textarea> elements it uses a Diazo <replace> directive instead of an <xsl:template>.
... ....

If you've done enough xslt then you probably know that this could have been achieved with an <xsl:template> element, the problem is that <xsl:template> elements won't work in all scenarios when using Diazo. 

A note about Diazo, <xsl:template> and nested scenarios

<xsl:template> elements in nested rules will fail silently. This also means that externally included files will also fail because rules in externally included files are implicitly nested.
So something like this, if located in the main rules.xml file, should work:
<rules>
    <xsl:template>
    ...
    </xsl:template>
</rules>

This will fail, because it is in a nested <rules> element.
<rules>
    <rules>
          <xsl:template>
          ...
         </xsl:template>
     </rules>
</rules>

On the other hand, Diazo's <replace> directive can be used as a work-alike to the <xsl:template> element and it works in nested scenarios.

Don't do this

Here's the <xsl:template> approach which works in very specific scenarios.
 ... ...

When you can do this

For comparison, here again, is an example that uses the <replace> directive and should work in most scenarios.
... ....
Don't forget to include the apply-template, it is needed.

Wednesday, June 7, 2017

Reading other people's code - first hour towards building custom tiles for plone.app.mosaic

TL;DR looking at other people's code - my first steps in getting started with creating custom tiles for Mosaic involved looking at how other people did it.

Mosaic is a layout solution for Plone which allows end users to create custom page layouts within a Plone website (video) using a simple drag and drop.  There are ready made tiles for common situations, however I am starting to come across situations where the default tiles aren't what I want.

I decided it was time to explore the creation of custom tiles. I figured the best way to get going would be to look at how others have created custom tiles. I knew that custom tiles were used in the creation of the Plone 2016 conference website and that the source code for the site was published on github. I started by inspecting their code.

I setup Plone 5.0.7 with Mosaic 2.0rc5 and also the ploneconf2016 site profile (https://github.com/plone/ploneconf2016.policy). The code for the tile configuration is here: https://github.com/plone/ploneconf2016.policy/tree/master/ploneconf2016/policy/tiles

Once everything was installed I was able to create a fake conference website and add presentations, persons (speakers/presenters) and a few other content types.

The policy defines two custom tiles

  • A slider tile 
  • A presentation tile

I was able to use both custom tiles without issue, the slider custom tile doesn't work out the box, meaning I could define the slides but the actual sliding didn't work. The slider depends on other components that are provided by the ploneconf2016 theme. It shouldn't be too hard to add the right CSS and JS to my own theme to get the slider working the way I want.

One note, when I cheated by not including a speaker on my presentation item, things "broke". To be fair this is to be expected since the presentation content type does have a red dot indicating that speakers are required items on presentations.

I got this error on the console

```
...
  Module zope.component._api, line 120, in queryMultiAdapter
  Module zope.interface.registry, line 245, in queryMultiAdapter
  Module zope.interface.adapter, line 541, in queryMultiAdapter
  Module plone.jsonserializer.deserializer.converters, line 69, in from_unicode_converter
  Module zope.schema._field, line 322, in fromUnicode
  Module zope.schema._bootstrapfields, line 183, in validate
  Module zope.schema._field, line 338, in _validate
ConstraintNotSatisfied: (u'350d0a34ffcb4fc4943efdcf4bdb9f03', 'content_uid')
```

A quick guess... the content_uid was probably referring to the missing speaker.

I consider this a great first experiment. I have all the pieces working and I know how the code was put together. My next steps are 1) customize one of the conference tiles 2) create and register a brand new tile of my own.

Sunday, December 4, 2016

Here come the Bash clients for Let's Encrypt - Acme.sh, Dehydrated and creating SSL Certificates

I was recently working on a server with a pretty old OS. In the past I've configured SSL using EFF's Certbot, a Python based client for managing Let's Encrypt's certificates, but Certbot requires Python 2.7 or better and the server only shipped with Python 2.4. I initially started on the journey of "jumping through hoops" getting Python 2.7 installed on the old system but then I discovered bash based clients for Let's Encrypt. So here are some short notes for my future self which might save some time.

In terms of shell scripts that re-implement the Certbot client there are two shell scripts that I currently know of, one called dehydrated and the other, which I discovered a day or two later, is called acme.sh.  I ended up using acme.sh, I found the acme.sh implementation to be a bit simpler than the dehydrated implementation. If you're interested in using dehydrated, there's reasonable documentation on how to install and use it at https://www.aaflalo.me/2016/09/dehydrated-bash-client-lets-encrypt/.

Acme.sh

Acme.sh promotes itself as follows:

  • An ACME protocol client written purely in Shell (Unix shell) language.
  • Full ACME protocol implementation.
  • Simple, powerful and very easy to use. You only need 3 minutes to learn it.
  • Bash, dash and sh compatible.
  • Simplest shell script for Let's Encrypt free certificate client.
  • Purely written in Shell with no dependencies on python or the official Let's Encrypt client.
  • Just one script to issue, renew and install your certificates automatically.
  • DOES NOT require root/sudoer access.
It basically installs itself in the home folder of the active user and also adds itself to the PATH.
Installation is as easy as:

curl https://get.acme.sh | sh
Or:
wget -O -  https://get.acme.sh | sh

After that you can create an SSL certificate for the domain with the following command:
acme.sh --issue -w /home/mysite/public_html/example.com -d example.com -d www.example.com
Unfortunately, while the certificate was created without a problem, the server was so old that the version of OpenSSL didn't support multiple domains on the same IP address according to this article I needed at least OpenSSL v0.9.8j. 

Truth be told the best course of action will be to upgrade the server since it is otherwise vulnerable. The knowledge won't be lost as I can use it on other projects on newer servers.

Wednesday, November 30, 2016

Small Plone team ready for interesting problems




Starting December 1, 2016 the Alteroo team will be available for new Plone gigs.

Our team members are ready to dive into modern Plone development including Diazo and Mosaic on Plone 5. We also have experience with older versions of Plone.

If you're into checking boxes we also have experience with Javascript/ReactJS/Webpack/Babel, Pyramid/Kotti, Firebase, QA, Linux server administration and General Design skills.

Send an email to newgigs - [ at ]- alteroo.com.

Monday, November 28, 2016

Dear future ReactJS using self, thanks to IE11, you will need to know about babel-pollyfil

Hello future self. This is a quick note on how to use the babel-polyfill.
Perhaps it is so far enough into the future that all browsers now support all of ES6 or better natively. Just in case you're still needing to support the few stubborn Internet Explorer 11 (IE11) users then you'll find this helpful.

It is November 2016 and we now use polyfills to make browsers support futures that they otherwise would not.  Here's how to use the babel-polyfill to help to make your project IE11 compatible.

In my case the specific issue was that my production code was shipping with calls to Object.assign(). Unfortunately IE11 has no idea what .assign() is. In the meantime Chrome just worked, this is how I used the polyfill approach with babel-polyfill to trick IE11 into doing Object.assign().

1. Install it with npm

This command is run in the directly that contains the package.json file:
npm i babel-polyfill --save-dev

2. Edit your webpack.config.js file to make use of it

The snippet below shows how the babel-polyfill is added to the entry array.

module.exports = {
  ...,
  entry: [
    'webpack-hot-middleware/client',
    'babel-polyfill',
    './app/client.js'
  ],

3. Import it into your project

Here's what importing babel-polyfill looks like in my project file which is located at app/client.js:
import 'react-toolbox/lib/commons.scss';
import React from 'react';
import ReactDOM from 'react-dom';
import 'babel-polyfill';
import App from './App.js';

There you go future self, if you found this helpful, you're welcome. I still need to check if this fixes IE10 compatibility issues.

Thursday, November 17, 2016

Installing Plone 5 on Windows: Part 2 - Installing Plone

This is part 2 of installing Plone 5 on Windows. The following instructions are specific to installing Plone 5 on Windows. Part 1 covered preparing your Windows machine for Plone.

Assumptions




You now have all the tools needed to build a full Plone environment. Plone uses a tool called "buildout" for managing builds, this makes it possible to distribute build configurations using git or other revision management tools. The folder where your build configuration exists is also referred to as a buildout. We will checkout an existing buildout called "themedev.buildout". The intention of the "themedev.buildout" is to provide all the tools needed for Plone theme development.

In the steps below you will clone the buildout then run an initializaton script called "setup.bat"

Step 1 - Install Virtualenv

Launch git bash and run the following to install virtualenv.

pip install virtualenv

Step 2 - Clone the buildout, run the setup script and bin/buildout


git clone https://github.com/collective/themedev.buildout
cd themedev.buildout
./setup.bat
bin/buildout

Day to Day Usage

To launch the instance run the following:

bin/instance fg




Sign up for my upcoming Plone 5 Book & Video tutorials

plone 5 for newbies book and videos