Skip to content. | Skip to navigation

Navigation

You are here: Home / Support / Guides / Tools / Plone / Add Products to Plone / reStructured text (youtube)

Personal tools

Add Products to Plone

reStructured text (youtube)

reStructured text and YouTube

Overview

It'd be handy to be able to embed YouTube videos in our favoured reStructured text. You can't do it by default in Plone 3.3.5 or, more accurately, you can't do it with the version of docutils that is bundled with Plone 3.3.5 although you may be able to do it with newer docutils releases.

In docutils speak we want to be able to say:

.. youtube:: fIZpjWM6ZYw

as in

There's more on viewlets discussion Changing Layout.

Create the Plone package

We need to use paster to create the Plone package we're going to edit:

cd .../zeocluster/src
../bin/paster create -t basic_package example

So that on the command line where we entered example we got a subdirectory of src called example. Then there is the name of the product, example which create subdirectories to give:

.../zeocluster/src/example/example

Change into that directory.

configure.zcml

Nothing seems to work without .zcml files everywhere so:

cp ../configure.zcml .

youtube.py

Here's the action!

# Taken from http://countergram.com/articles/youtube-in-rst/

from docutils import nodes
from docutils.parsers.rst import directives

CODE = """\
<object type="application/x-shockwave-flash"
       width="%(width)s"
       height="%(height)s"
       class="youtube-embed"
       data="http://www.youtube.com/v/%(yid)s">
   <param name="movie" value="http://www.youtube.com/v/%(yid)s"></param>
   <param name="wmode" value="transparent"></param>%(extra)s
</object>
"""

PARAM = """\n    <param name="%s" value="%s"></param>"""

def youtube(name, args, options, content, lineno,
           contentOffset, blockText, state, stateMachine):
   """ Restructured text extension for inserting youtube embedded videos """
   if len(content) == 0:
       return
   string_vars = {
       'yid': content[0],
       'width': 425,
       'height': 344,
       'extra': ''
       }
   extra_args = content[1:] # Because content[0] is ID
   extra_args = [ea.strip().split("=") for ea in extra_args] # key=value
   extra_args = [ea for ea in extra_args if len(ea) == 2] # drop bad lines
   extra_args = dict(extra_args)
   if 'width' in extra_args:
       string_vars['width'] = extra_args.pop('width')
   if 'height' in extra_args:
       string_vars['height'] = extra_args.pop('height')
   if extra_args:
       params = [PARAM % (key, extra_args[key]) for key in extra_args]
       string_vars['extra'] = "".join(params)
   return [nodes.raw('', CODE % (string_vars), format='html')]
youtube.content = True
directives.register_directive('youtube', youtube)

As noted, taken from Countergram.

__init__.py

One last thing. We need to register the code as a new docutils directive:

from youtube import youtube
from docutils.parsers.rst import directives

def initialize(context):
   """Initializer called when used as a Zope 2 product."""

   directives.register_directive('youtube', youtube)

buildout

Finally, add example to the eggs and zcml sections and src/example to the develop section.

Fix up the site's HTML Filtering

Go to Site Setup; HTML Filtering

Remove from Nasty tags:

  1. object
  2. embed

Remove from Stripped tags:

  1. object
  2. param

Warning

You may have to restart your Plone instance to get it to implement the changes.

Document Actions