Experimental Project

This is a sandbox project, which contains experimental code for developer use only.

embedder.screenshot.png

(Currently in sandbox phase)

An alternative to a number of older token-based 'embedders'. Re-imagining the job they all have in common and seeing if a persistent, semantic, XHTML-valid syntax (instead of limited, made-up pseudo-tags) could be a way forward.

eg

<div e:element="node" e:display="teaser" e:nid="1"></div>

not

[embed:nid:1|layout=teaser]

Currently, it includes a wysywyg plugin for managing the embedded items, with a UI.

Motivation / roadmap write-up

Formatting to come, this is a dump from my internal README notes. It's a sandbox proposal, alright?

Yet another element embedder.

Objective

  • to allow WYSIWYG (or HTML) editors to embed common Drupal elements
    such as blocks, files, images, node teasers, panels and views into the content (body)
    areas of their pages
  • NOT to use any pseudo markup [inline:] {block:} filters to do that, but use
    real XHTML that is round-trip safe for WYSIWYG and will render meaningfully
    in the editor area
  • Be completely XHTML-compliant
  • Save meaningful HTML equivalents in the stored text data, so that turning off
    the filter or the module will not result in data loss, merely static versions
    of the desired content.
  • Be compatible with a WYSIWYG plugin for management.
  • Learn from the many many attempts at this sort of job that have come before:

Challenges

Caching

Reptag used to be great, but ended up developing its own alternative to Drupal
input filters just to ensure that 'dynamic' content was kept up to date.

Caching is a tricky one, if the content being embedded really does have to be
more up-to-date than the Drupal system expects its text fields to be.

Security

Insert View module http://drupal.org/project/insert_view got into trouble by
allowing users to embed any view in the page - without regard to the intended
visibility restrictions. I think this is an admin issue rather than a true
security issue, but some of these issues will need to be addressed.

Previous examples

Highly respected/popular

  • rep[lacement]tags http://drupal.org/project/reptag

    Example syntax:

    {block:user:1}

    - We can embed a number of Drupal elements into textareas, using markdown.
    - I really liked this, as it was a straightforward solution to a simple task.
    It was strongly extensible for any Drupal element via its own plugins.

  • Inline http://drupal.org/project/inline

    Example syntax:

    [inline:filename.jpg] [upload|file=file2.pdf]

    Inline module allows users to display uploaded files and images inline, i.e. place links to files into a content using a simple [inline:filename.jpg] tag.

    - A strong contender with a far-reaching approach, similar to what I want.
    - Only the pseudo-tag syntax is letting it down for me.
    - defaults to looking at the current node for file attachments to embed - which
    usually makes sense. Allows a shorthand to refer to attachments by number.
    - No GUI AFAIK, though it was on the roadmap in 2008.
    - Much talk on the historical Inline API discussion - but nothing seems to have come of it.
    - Probably lessons to be learned there.

  • Embedded Media Field http://drupal.org/project/emfield

    - assists embedding of rich media content
    - Driven only by pasting media-target URLS such as YouTube/Slideshare/Flickr bookmarks. The module figures out the rest from there.
    - This type of UI is the most-user-friendly I can imagine. Not sure how well it integrates with Drupals own content though.

  • Image Assist http://drupal.org/project/img_assist

    - Grand-daddy of embedded item assistance modules
    - Full WYSIWYG button and edit dialog
    - A (once-only) choice between using its custom pseudo-tag syntax and saving as real HTML.
    - image browser (views-driven).
    Example syntax:

    [img_assist|nid=2|title=My title|desc=My description|align=right|width=200|height=150|link=url,http://www.google.com]

    ... and this is what bugs me. We can do exactly that in HTML! Why invent an irregular syntax to replace it?

  • Insert http://drupal.org/project/insert

    - Provides a GUI button to tightly integrate filefield attachments on a node with a mechanism to insert them into the page content.
    - imagecache options and default preferences for resizing of attached images is strong.
    - good config options.
    - Image embeds only. No round-trip support

Others

  • IMCE http://drupal.org/project/imce

    - Doesn't do anything special to the embedding of images
    (It produces raw HTML img tags), but does enhance WYSIWYG with a better file
    browser and resizer to help manage them.
    - Plus lots more. Just images though.

  • Insert View http://drupal.org/project/insert_view

    Example syntax:

    [view:name of view=x=arg1,arg2,arg3]

    Insert View is a filter that allows users to embed content lists generated by the Views module into node bodies and blocks using relatively simple tag syntax.

    - fine, I just have no liking for the 'tag' syntax. Square brackets, and both colons AND equals in its parameter list.
    - limited to 'views' of course.

  • Views embed filter http://drupal.org/project/views_emb_filter

    Example syntax:

    [viewsembfilter]view_name[\viewsembfilter]

    - Otherwise basically the same thing as Insert View, with less options.

  • Embed Views display http://drupal.org/project/embed_views

    - not actually an embedder, just a tool that provides views that may be embedded later via php snippets.

  • Views Embed http://drupal.org/project/views_embed

    - dead

  • Image Insert http://drupal.org/project/img_insert

    -dead

  • Image filter http://drupal.org/project/image_filter

    Example syntax:

    [image:nodeid]

    - doesn't look too popular
    - Does one simple job well - embedding image.module images.

  • insertFrame http://drupal.org/project/insertFrame

    Example syntax:

    [[[<url> width=<w> height=<h> scrolling=<yes|no|auto> className=<class> ID=<id> offset=<offset> transparency=<true|false> wrapper=<html|htmlpage|text>]]]

    This filter allows to insert a frame (or iframe) in a node, block, panel, ...

  • Iframe filter http://drupal.org/project/iframe_filter

    Example syntax

    <!-- width="w" height="w" -->

    - Not quite the same task, or what the name would suggest, this appears to embed itself as an iframe, not embed iframes in itself.

  • Embed filter http://drupal.org/project/embedfilter

    - not quite sure what it achieves, but it appears to allow you to use 'object' or 'embed' code from youtube etc without opening up the security hole that allowing any 'object' embed code would entail.

  • Multimedia Element http://drupal.org/project/aef_multimedia_element

    Example syntax

    <!--:Element_Multimedia:[^-]*-->

    - Appears to go a long way in the right direction, allowing editors to place rich elements in their content areas.
    - Provides/supports a suite of rich elements that can be embedded - Easy View, imagecache, lightbox, carousel
    - No WYSIWYG support yet?
    - Good theming support & style options for the embedded elements

  • Embed Widgets http://drupal.org/project/embed_widgets

    - is a provider of embeddable elements, designed to allow this function to happen on remote, non-Drupal sites (a-la Google Gadgets). Look to this for some examples on getting the Drupal elements to embed in pages.
    also Web Widgets http://drupal.org/project/web_widgets

  • Node Reference/Embed Media Browser http://drupal.org/project/nrembrowser

    Example syntax

    [[nid:1]]

    - Didn't come up in my searches, so I found it late (when investigating wysiwyg plugins).
    - Has a wysiwyg integration button!
    - Still uses pseudo-tags as its method internally, so spends a lot of effort converting from and to that syntax.
    - Very powerful browser pop-up, includes built-in search thumbnails by node type widget, and a create-on-the-fly subform.
    - Very extensive behind-the-scenes code. A bit intimidating to hook into, though it seems very modular in places (overengineered in others)

  • http://drupal.org/project/wysiwyg_imageupload

    - Also discovered late. Looks rich

  • Inline http://drupal.org/project/inline

    - Intended to abstract the embedding of objects (flash essentially)
    - Dead

  • http://drupal.org/project/attach

    Example syntax

    [attach_node|nid=1]

    - Very standard yet-another markdown filter for embedding nodes and files.
    - First release Feb 2011
    - Has potential security issues - no access checks as the data is pulled up and rendered.
    - Reasonably clean (potentially extensible) architecture internally.

  • Drupal Markup Engine http://drupal.org/project/dme

    Example syntax

    <dme:image number=0 align="left" />

    - Though its heart is in the right place, it's got issues
    It proposes a new markup that is HTML-shaped (uses attributes sanely),
    yet based around custom tags, and therefore maybe unsafe for WYSIWYGs
    - It is at least well (though not fully?) namespaced.
    - The internal architecture is good, the way it extensibly publishes plugin info
    to the module list. It's similar to how I'm doing it.
    - It's more focused on 'macro' like filters or display tweaks than element
    embedding, but embedding could maybe be thought of as a subset of what dme
    structure could provide.
    - Not very popular. Good roadmap docs though.
    - Provides an example WYSIWYG plugin button. Excellent

Prior art and standards

What I need to aim at is something that gives the extensible functionality of,
say, the old HTML <embed> or <object> tag, with
data elements or param sub-tags.

But to be WYSIWYG-safe and editable, I'll look at using microformats in a div instead.
Or maybe RDF or at least namespaced attributes?

Approach

The metadata - attributes should probably remain hidden by default, so there is not much advantage in microformats.
Using RDFa is wordy, but assuming there is to be a WYSIWYG tool, it's probably the most robust.
However, can I use an XHTML-safe shorthand that's only a little different from all the pseudo-tags that have come before, and a lot more workable to folk that understand HTML?

RDFa

RDFa can deal with an empty tag that defines both a @property and a @value attribute.

<div typeof="drupal:block" xmlns:drupal="http://drupal.org/elements#">
  <span property="drupal:module" content="user"></span>
  <span property="drupal:delta" content="1"></span>
  <!-- actual block contents of block:user:1 goes here -->
</div>

Microformats prefers @class and @title, and doesn't do namespaces (very well).

Microformats

<div class="drupal:block" >
  <span class="module" title="user"></span>
  <span class="delta" title="1"></span>
  <!-- actual block contents of block:user:1 goes here -->
</div>

Custom XML namespace?

Is this problematic? It seems to be legal and is one of the valid ways to extent XHTML with new functionality.

<div xmlns:e="http://drupal.org/project/embedder#" e:element="block" e:module="user" e:delta="1">
  <!-- actual block contents of block:user:1 goes here -->
  <p>This content should still be XHTML, not our custom namespace</p>
</div>

HTML4 data-* attributes

I'm not too interested in the @data attribute from HTML5, but it's a direction to be aware of.

Update - In recent years, the HTML5 data-* extension has started being supported better. It's now browser-safe, and the stated purpose of it - for internal, implementation-specific uses (So, for your own CMS only, not intended to be shared) - is actually a better fit than either microformats OR a custom XML schema.

<div data-embed-type="block" data-block-module="user" data-block-delta="1"  >
  <!-- block contents of block:user:1 goes here -->
</div>

<div data-embed-type="entity" data-entity-type="node" data-entity-id="101" data-view-mode="teaser" >
  <!-- teaser of node 101 goes here -->
</div>

The parsing and filtering

100% XML DOM based.
I'm just sick of regular expressions trying to un-hash nested HTML tags.
I don't want to write a tokenizer, just use the PHP5 DOM.

Permissions?

Reptag overdid it with the permissions, setting different roles to get access to different features. I'll avoid that question for now, and layer in access control later if needed.
The object is to add functionality to be used by trusted admins and editors. This is not a user-facing tool.

References

A good discussion over in wysiwyg_fields about some pros and cons of this approach - where this project manifesto-roadmap was first made public.

Project Information