? ? ? Success
Referenced as Related to: # 4276

User tests: Successful: Unsuccessful:

avatar PAlexcom
PAlexcom
15 Aug 2014

plg_system_microdata

A Joomla 3.2+ system plugin that uses the JMicrodata library.
Created during the Google Summer of Code 2014.

If you want to keep your views separated from the logic, plg_system_microdata is system plugin for parsing the HTML markup and converting the data-* HTML5 attributes into the correctly formatted Microdata semantics.

The data-* attributes are new in HTML5, they give us the ability to embed custom data attributes on all HTML elements. So if you disable the library output, the HTML will still be validated. The default suffix that the library will search for is data-sd, where sd stands for structured data, but you can register more than one custom suffix.

Usage

Since the system plugin runs immediately before the final content is sent to the client, you can use the plugin syntax everywhere, including native and third-party extensions that allow HTML editing.

Markup Syntax

setType

ParserPlugin Syntax

The type defines which schema is being used for the following markup. The Type must always have the first character Uppercase to be correctly interpreted. If the type is a valid schema, the global scope for the page from this point onwards is updated to this schema. The plugin will replace the data tag with itemscope itemtype='https://schema.org/Type'.

Example:
<div data-sd="Article">
    <p>This is my article</p>
</div>

This will be output:

<div itemscope itemtype="http://schema.org/Article">
    <p>This is my article</p>
</div>
Specifying generic item properties

ParserPlugin Syntax

Once a schema has been declared, the next step is to declare individual properties – explaining the content and giving it semantic meaning.

The property must always have the first character as lowercase to be correctly interpreted. If the property is found to be part of the current schema, the plugin will replace the data tag with itemprop='property'. If the property is not found to be a valid property of the active schema, it will be ignored and the next available property will be parsed.

Example:
<div data-sd="Article">
    <p data-sd="articleBody">This is my article</p>
</div>

This will be output:

<div itemscope itemtype="http://schema.org/Article">
    <p itemprop="articleBody">This is my article</p>
</div>
Specifying schema—dependant item properties

ParserPlugin Syntax

Sometimes you may want to explicitly state a property which should only be used when a specific schema is active – for example, if the property has a specific property in one schema, which is called something different in another schema.

It is possible to achieve this by using a schema–dependant property. This works by using a combination between both Type and property, separated by a full stop. In short, if the current global scope is equal to Type and the property is part of that Type, the plugin will replace the data tag with itemprop='property'.

Example:
<div data-sd="Article">
    <p data-sd="articleBody">This is my article</p>
    <p data-sd="Article.wordcount">4</p>
</div>

This will be output:

<div itemscope itemtype="http://schema.org/Article">
    <p itemprop="articleBody">This is my article</p>
    <p itemprop="wordcount">4</p>
</div>

Using multiple properties

ParserPlugin Syntax

It is possible, using a combination of these, to specify multiple properties including some which are specific for a schema and others which are generic. The order of the building blocks isn't significant and a white space is used as a separator.

Example:
<div data-sd="Article">
    <p data-sd="articleBody">This is my article</p>
    <p data-sd="Article.wordcount">4</p>
    <p data-sd="Recipe.recipeCategory Article.articleSection description">Amazing dessert recipes</p>
</div>

This will be output:

<div itemscope itemtype="http://schema.org/Article">
    <p itemprop="articleBody">This is my article</p>
    <p itemprop="wordcount">4</p>
    <p itemprop="articleSection">Amazing dessert recipes</p>
</div>
Nesting schemas

Sometimes it is necessary to nest schemas – for example if you want to describe a person when you have the Article schema open. This is possible using nested schemas. To use this, simply append the schema preceeded by a full stop, after the property. Once you have finished using the nested schema, close the containing tag, and re-set the original schema.

Example:
<div data-sd="Article">
    <p data-sd="articleBody">This is my article</p>
    <p data-sd="Article.wordcount">4</p>
    <div data-sd="author.Person">
        <p data-sd="name">John Doe</p>
    </div>
    <p data-sd="Article keywords">Cake</p>
</div>

This will be output:

<div itemscope itemtype="http://schema.org/Article">
    <p itemprop="articleBody">This is my article</p>
    <p itemprop="wordcount">4</p>
    <div itemprop="author" itemscope itemtype="http://schema.org/Person">
        <p itemprop="name">John Doe</p>
    </div>
    <p itemprop="keywords">Cake</p>
</div>
The Algorithm:
  1. First the parser checks for setTypes. If one or more matches are found then the current global scope will be updated with the first match. At this point if there are no specific or generic properties the algorithm will finish and replace the data tag with the specified scope. Otherwise continue to point 2.
  2. The parser checks for specific item properties. If one or more valid matches are found, then the algorithm will finish and replace the data tag with the first match property. Otherwise go to point 3
  3. The parser checks for generic properties. If one or more valid matches are found, then the algorithm will replace the data tag with the first property that is matched, and complete the algorithm.

Semantically marking up 'on the fly' within HTML editors

To apply markup within articles simply use the data tag and the method explained above.

See below for an example.
plg_system_structureddata content editor usage

Incorporating into your extensions and templates

Let's suppose that somewhere in your code you need to add Microdata semantics to the following HTML which is part of an article (e.g. $scope='Article';).

<div data-sd="<?php echo $scope;?>">
    <!-- Title -->
    <span data-sd="Review.itemReviewed name">
        How to Tie a Reef Knot
    </span>
    <!-- Author -->
    <span>
        Written by
        <span data-sd="author.Person">
            <span data-sd="name">John Doe</span>
        </span>
    </span>
    <!-- Date published -->
    <meta data-sd='<?php echo $scope;?> datePublished' content='2014-01-01T00:00:00+00:00'/>1 January 2014
    <!-- Content -->
    <span data-sd='reviewBody articleBody'>
        Lorem ipsum dolor sit amet...
    </span>
<div>

The output will be:

<div itemscope itemtype='https://schema.org/Article'>
    <!-- Title -->
    <span itemprop='name'>
        How to Tie a Reef Knot
    </span>
    <!-- Author -->
    <span>
        Written by
        <span itemprop='author' itemscope itemtype='https://schema.org/Person'>
            <span itemprop='name'>John Doe</span>
        </span>
    </span>
    <!-- Date published -->
    <meta itemprop='datePublished' content='2014-01-01T00:00:00+00:00'/>1 January 2014
    <!-- Content -->
    <span itemprop='articleBody'>
        Lorem ipsum dolor sit amet...
    </span>
<div>

Instead, if you decide to change the current Type (e.g. $scope="Review";).

The output will be:

<div itemscope itemtype='https://schema.org/Review'>
    <!-- Title -->
    <span itemprop='itemReviewed'>
        How to Tie a Reef Knot
    </span>
    <!-- Author -->
    <span>
        Written by
        <span itemprop='author' itemscope itemtype='https://schema.org/Person'>
            <span itemprop='name'>John Doe</span>
        </span>
    </span>
    <!-- Date published -->
    <meta itemprop='datePublished' content='2014-01-01T00:00:00+00:00'/>1 January 2014
    <!-- Content -->
    <span itemprop='reviewBody'>
        Lorem ipsum dolor sit amet...
    </span>
<div>

There is also a standalone version of the plugin, which you can download and install from here: https://github.com/alexprut/plg_system_microdata/archive/master.zip

avatar PAlexcom PAlexcom - open - 15 Aug 2014
avatar jissues-bot jissues-bot - change - 15 Aug 2014
Labels
avatar jissues-bot jissues-bot - change - 15 Aug 2014
Labels Added: ?
avatar jissues-bot jissues-bot - change - 15 Aug 2014
Status Pending New
Labels Added: ? ?
avatar nicksavov nicksavov - change - 21 Aug 2014
Labels
avatar nicksavov nicksavov - change - 21 Aug 2014
Labels Removed: ?
avatar brianteeman brianteeman - change - 22 Aug 2014
The description was changed
Status New Pending
avatar brianteeman brianteeman - change - 23 Sep 2014
Category Plugins
avatar Hackwar
Hackwar - comment - 3 Feb 2015

Please fix the codestyle issue that Travis is complaining about and solve the merge conflicts.

avatar PAlexcom
PAlexcom - comment - 19 Feb 2015

@Hackwar Thanks, fixed.

avatar chmst
chmst - comment - 14 Mar 2015

Warning: DOMDocument::loadHTML(): Tag header invalid in Entity, line: 45, 870 121 and 208

avatar MMonia
MMonia - comment - 14 Mar 2015

Warning: DOMDocument::loadHTML(): Tag header invalid in Entity, line: 46,62,81,220


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/4118.
avatar brianteeman brianteeman - alter_testresult - 14 Mar 2015 - MMonia: Tested unsuccessfully
avatar brianteeman brianteeman - alter_testresult - 14 Mar 2015 - chmst: Tested unsuccessfully
avatar dnimooj
dnimooj - comment - 14 Mar 2015

@test works ok


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/4118.
avatar dnimooj dnimooj - test_item - 14 Mar 2015 - Tested successfully
avatar MMonia
MMonia - comment - 14 Mar 2015

I installed the patch (not the plugin) and added the line for the plugin to the database. When editing the plugin in backend, I get: The file microdata.xml could not be found.


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/4118.
avatar tecpromotion
tecpromotion - comment - 14 Mar 2015

@MMonia You have to apply the patch, go to Extensions -> Extenson Manager. Click Discover -> Discover -> Install the plugin. Enable the plugin and go to test.


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/4118.
avatar anibalsanchez
anibalsanchez - comment - 6 Jun 2015

Warning: DOMDocument::loadHTML(): Tag header invalid in Entity


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/4118.

avatar anibalsanchez anibalsanchez - test_item - 6 Jun 2015 - Tested unsuccessfully
avatar roland-d roland-d - change - 20 Aug 2015
Status Pending Information Required
avatar roland-d
roland-d - comment - 20 Aug 2015

Hello @PAlexcom

Thank you for your contribution.

The last comment here was on 7th June. So the question is, Is this issue/pull request still valid?
If no reply is received within 4 weeks we will close this issue.

Thanks for understanding!


This comment was created with the J!Tracker Application at issues.joomla.org/joomla-cms/4118.

avatar PAlexcom
PAlexcom - comment - 22 Aug 2015

Hello @roland-d, this PR is valid, but now, I don't think it should go in the official Joomla release, instead it should be distributed as an external plugin (so anyone who needs that plugin could install it).

avatar chmst
chmst - comment - 22 Aug 2015

I agree with PAlexcom. I like the idea of a plugin and keeping the core slim.

avatar roland-d
roland-d - comment - 22 Aug 2015

@PAlexcom Sounds like a plan to me, based on that, I will close this PR.

avatar roland-d roland-d - change - 22 Aug 2015
Status Information Required Closed
Closed_Date 0000-00-00 00:00:00 2015-08-22 20:54:39
Closed_By roland-d
avatar roland-d roland-d - close - 22 Aug 2015
avatar joomla-cms-bot joomla-cms-bot - change - 22 Aug 2015
Labels Added: ? ?
avatar alexprut alexprut - change - 6 May 2016
The description was changed

Add a Comment

Login with GitHub to post a comment