Been playing with Views for Drupal 7 lately and one thing I noted is that support for RDFa would be real nice to have.

For example, I have working on a new frontpage for http://nutshell.nu that uses Views instead of teasers. The node teaser have the following code:

<div id="node-52" class="node node-blog node-promoted node-teaser clearfix" about="/blog/thomas/2010/07/30/drupal-7-for-production-websites-part-1-drupal-7-core" typeof="sioc:Post sioct:BlogPost">
  <h2 property="dc:title" datatype="">
    <a href="/blog/thomas/2010/07/30/drupal-7-for-production-websites-part-1-drupal-7-core">Drupal 7 for Production Websites Part 1: Drupal 7 Core</a>
  </h2>
  <div class="meta submitted">published by <span rel="sioc:has_creator"><span class="username" xml:lang="" about="/users/thomas" typeof="sioc:UserAccount" property="foaf:name">thomas</span></span> on <span property="dc:date dc:created" content="2010-07-30T02:51:26+02:00" datatype="xsd:dateTime">Fri, 07/30/2010 - 02:51</span>
  </div>
  <div class="content clearfix">
    <div class="field field-name-body field-type-text-with-summary field-label-hidden clearfix">
      <div class="field-items">
        <div class="field-item even" property="content:encoded"><p>This is the first post of three about when Drupal 7 will be ready to be deployed on production (live) websites. The other two parts will be posted during the next few days. See end of post for index.</p>
        </div>
      </div>
    </div>
  </div> 
  <div class="link-wrapper"> 
    <ul class="links inline"><li class="node-readmore first last"><a href="/blog/thomas/2010/07/30/drupal-7-for-production-websites-part-1-drupal-7-core" rel="tag" title="Drupal 7 for Production Websites Part 1: Drupal 7 Core">Read more</a></li> 
    </ul>
    <ul class="links inline"><li class="blog_sitenames_blog first last"><a href="/blog" title="Read the latest nutshell.nu blog entries.">nutshell.nu blog</a></li> 
    </ul>
  </div> 
</div> 

All of the above RDFa markup is straight out of the Drupal 7 box.

It would be such a nice feature if it was simple to get the same markup when using Views, especially since it will have a positive impact on SEO.

I am no expert on RDFa, yet at least, but I tried to emulate some parts. For example using the "Output this field as a link" option for the title and setting prefix:

<h2  property="dc:title" datatype="">

But when I looked at the source code "dc:" had been filtered out.

I do realise that adding RDFa support is probably a big task, and maybe it should be done in a separate module. Having support for is going to be important though.

Is there any plans for this, or do you know of any other projects going on adding it to Views?

Comments

bojanz’s picture

Fixing title.

Also like the idea.

tsvenson’s picture

Title: Support for DRFa » Support for RDFa

Thanks, just noticed it myself.

dawehner’s picture

Do i see it right, that the field handler would need options for many different attributes?

Would this fix the issue?

Anonymous’s picture

I had a conversation about this with one of my advisors in relation to SPARQL Views. I think that this is a great idea, I'll try to make time to work on this.

(thanks to bojanz for pinging me on this)

Anonymous’s picture

Do i see it right, that the field handler would need options for many different attributes?

This would probably work for basic functionality. However, one thing to watch out for is that people frequently use CURIEs, which are abbreviated term names. This means that

<a property="http://xmlns.com/foaf/0.1/name">Lin Clark</a>

becomes

<html .... xmlns:foaf="http://xmlns.com/foaf/0.1/">
.
.
.
<a property="foaf:name">Lin Clark</a>

We would probably want to provide some support for figuring out which namespaces are used and adding those when hook_rdf_namespaces is fired.

Anonymous’s picture

Stéphane showed up in Galway for surprise drinks and we discussed this issue.

He said he suggested using the mappings that were already defined for the bundle as the mappings for the fields in the view. This would mean that there is no RDF Mapping UI in Views UI, all mapping would happen on the node itself and not on a view by view basis.

This definitely has some advantages. It works best with the RDF conceptual model, which has a node-centric view of the world. It also makes it easier to maintain consistency and ensure that all of the RDF on the site is output in the SPARQL endpoint.

Potential Problem

However, this may not cover all practical use cases, such as:

  1. When the mapping the user wants to use for a particular field doesn't exist on the node
  2. When a query backend other than Drupal is used
  3. I can't think of a use case, but it may also be possible that the mapping on the node is different than the one that should be used in the view

Use case 1

For instance, imagine a conference site where multiple years of the same conference are archived on the site. On this site:

  • Papers are input as nodes
  • The year that the paper was in the conference is a field on the node. This would be appropriately be mapped to something like dc:dateCopyrighted
  • A list of the papers in each proceedings is created as a view, filtering on the year.
  • The site admin might then want to use the view URI as the URI for the proceedings and relate each paper to the proceedings with dc:isPartOf

Use case 2

Imagine the conference is using Twitter Views to bring in a stream of tweets from conference organizers, using a particular hash tag. The site admin may want to say that the tweet is sioc:about the conference. However, as the tweet isn't a bundle in Drupal, there would be no mapping.

Potential Solution

There could be a mapping UI in Views as well. This could use the bundle's mappings for fields by default, but also allow for additional input. The mapping for the fields in the view would then be stored separately.

tsvenson’s picture

Preserving the RDFa markup would of course be preferred, but there will be times when this might not work in Views. For example when using the "Strip HTML" option on a field. Since the RDFa markup is embedded in those tags, they would be gone as well. Maybe two options (radio buttons) would be the solutions for this:

- Strip all HTML
- Strip HTML except RDFa

The RDFa markup could then strip the original tag and instead put the RDFa markup in a span tag for that field.

Another situation I can see this become a little messy is when you rewrite the output, both for single fields and multiple fields. For multiple fields it will sometimes be needed to have an RDFa wrapper around the field.

Same goes for a lot of situations with views where you will need a wrapper around each row it outputs.

One such case is if you have a list of calendar events, then each row will need for example the typeof="cal:Vevent" ical markup.

Anonymous’s picture

has there been work on this issue? a colleague showed me a site with a View that she has been working on and it has properties in the output.

dawehner’s picture

afaik not.

Anonymous’s picture

I'm realizing that she was using fields and fields output the attributes (which contain the RDFa). This creates a bug where incorrect RDFa is output, because the fields aren't necessarily tied to the node that they are attached to.

I'm going to figure it out tomorrow and will post an update.

merlinofchaos’s picture

This is made even harder; for the most part, the field.tpl.php output is undesirable in Views. We're going to have to find a way to get this information into Views so it can attach it directly to the tags that it provides.

tsvenson’s picture

Thanks for the update Earl. Great to hear that you are trying to figure out a solutions to this.

merlinofchaos’s picture

I think I will be more likely be in a mentoring position on this one, where I will happily guide but I think someone else (primarily someone familiar with RDFa) will need to do the real work. I'm happy to talk and discuss and get this in. Ideally we'll have good RDFa support before we hit -rc but that's going to require someone dedicated to doing it.

tsvenson’s picture

I get ya. Might be worth checking with Arto, the maintainer of the http://drupal.org/project/rdf module about this. That module is going to provide an UI and other things for D7 and it sounds like a lot would be gained to see how it could help improving support for RDFa in Views.

Update: Just noticed that the active developers for the RDF module is Stéphane Corlosquet and Lin Clark. Lin has already commented on this issue and can most likely help pointing in the right direction on how to get this support into Views.

Anonymous’s picture

merlinofchoas, does this mean that if we don't do anything here, the RDFa totally goes away? ... this may come as a surprise, but that might not be a bad thing.

I have thought about this and had a hard time coming up with the best way to approach it. There are a number of factors that make it hard... for instance, RDFa is very dependent on the nesting of HTML elements within other elements. When Views is pulling fields from other entities in (say, node references), I don't know how easy it is to maintain the proper nesting structure.

For instance, imagine a relationship where the View pulls information about a node and about the node's author into the View.

Since the relationship info that was part of a different entity (the user) in Drupal's table structure becomes part of a single row with other entities, it is very hard to get the proper nesting structure for RDFa. I don't think that the relationship information can easily be used to alter the field rendering. This is especially true when you consider Panel Views and Display Suites, where people can put the fields wherever they want.

There is a part of me that thinks that the best way for this to work is for us to tell users to simply use Node View if they want RDFa in their Views. That maintains the element structure necessary for RDFa. RDFa is also not necessary for every single part of a site, so I'm not sure there are a tremendous number of use cases where someone would really need to have RDFa in their Views. The RDFa will still be expressed as RDFa on the entity page, so all the same data will be exposed, and users can make it centrally available for applications to consume using a SPARQL endpoint (scor has a simple SPARQL endpoint module).

Having said all this, I'd be happy to work on figuring this out, if it is decided that it is necessary. I've been knee deep in Views plugins and handlers for the past few weeks, porting SPARQL Views from D6 to D7 (it exploits the Views way of doing things much more this time), and I can hand-write RDFa, so I think I may be uniquely qualified on this one.

So folks, any thoughts? Do we really need RDFa output for Views?

EDIT: I had to fix a couple of times to make the sentences make sense. Sorry, it's late in Ireland :-/

bojanz’s picture

I was thinking about how I'd do GoodRelations output in Views, and decided to not have it at all (the specification doesn't require it, and without a node view it's impossible to get complete markup, other than telling people "you need THESE fields").

So I agree with you.

merlinofchaos’s picture

it doesn't totally go away.

1) teaser views will still have RDF
2) If you choose to keep the field.tpl.php markup (it's a checkbox) then I presume it will contain all of the RDFa tags.

The thing is, the field.tpl.php markup is really heavy, and a lot of people don't want it, and there are contexts where it's actually useless (such as putting fields inline). I predict something like only 5% of fields will want to use the field.tpl.php markup with Views, so we have to assume that mostly will not happen.

In short: It may be best to have RDFa markup primarily in teaser views. I believe we can do different build modes and therefore do teasers with more/less fields, though there are other aspects of teasers that I think are harder to control just from the UI.

Anonymous’s picture

Sorry, I meant to include Teaser View when I said Node View. I guess it is called Content now, and is the other option in Format besides Field.

This brings up a question for me... when you use Full content view (as opposed to Teaser view), I would expect that the RDFa would still be included and that both node.tpl.php and field.tpl.php would be used. Is that correct?

Basically, as long as the rendering goes through the entity's .tpl.php, RDFa should be fine, but as soon as individual fields contain RDFa without any connection to the entitiy template, the RDFa can get buggy. The entity provides the scope for properties, so without it, the properties apply to who knows what. Because this is the case, we might need to focus on getting the RDFa out of fields in Views rather than in to them.

Sidenote: Sometime last year, I did use a Full content build to create a View with proper RDFa (and even nested node references with proper RDFa) for the International Semantic Web Conference web site. If they still work the same, custom view modes can be quite handy for creating the proper RDFa with Views.

merlinofchaos’s picture

Yeah, the 'node' view runs nodes with a build mode, i.e, 'teaser', 'full'. They should basically all render normally, so I think those will work as is.

I can see how RDFa might be both complicated but still desirable when building views out of fields. Some people like to use the fields view to build node teasers rather than the templates, so I think RDFa support might still be interesting.

1) If I want to add RDFa properties to the row style, how would I retrieve that information?
2) If I want to add RDFa properties to a field (and this isn't just field api fields; title and author, for example, clearly have RDFa properties associated) how would I retrieve that information?

Anonymous’s picture

The RDF mapping for each bundle is handled as an array which is stored in rdf_mappings in the database. There are also default settings for different entities, such as node, if the bundle doesn't explicitly declare a mapping.

You can see an example of this array at http://api.drupal.org/api/drupal/modules--rdf--rdf.module/group/rdf/7

rdf_mapping_load can be used to retrieve the mappings for a bundle.

Within that bundle, the rdftype is similar to a class. The rest of the elements in the array are field instances on that bundle. The predicates array lists the typed links between the entity and the field value... for instance, the relationship between a user and a user name is 'foaf:name'.

The title element is handled through the use of a title_attributes_array that is set in rdf_node_preprocess.

In some places in core, there are special cases where predicates are declared for other things that are not actual fields. You'll note this with the author, which is defined by the name element in node_rdf_mapping. This requires it's own special handling in rdf_preprocess_node.

All fields that are related to a single entity (for instance node/1) need to either be nested within an element that has the about attribute set or needs to have about set within the tag. So if I want to say that user 1 follows user 2, and have it be shown as a link to user 2, it could look like this with nested elements...

<div about="user/1">
Follows:
  <ul>
    <a rel="sioc:follows" href="user/2">merlinofchaos</a>
  </ul>
</div>

or it could be ...

Follows:
<a about="user/1" rel="sioc:follows" href="user/2">merlinofchaos</a>

It would be possible to use the second method to avoid the problem with nesting elements. It would simply mean reiterating the about attribute on every single field. However, this would increase the number of characters on a page (for people who worry about that).

There are also a few other attributes to consider (RDF types, content, and datatype), but those can come later. The biggest issue is going to be figuring out how to get the relationship between the entity and the field.

Anonymous’s picture

Also, I forgot to mention that the RDF mapping is included with the entity for anything that calls entity_load.

Anonymous’s picture

In thinking of what you said in IRC about table rows, the following could work for a complex query. It introduces spans around any field that is connected to the entity through a relationship. If a field is connected to the entity through a field which is excluded from view... another span is introduced to maintain the relationship chain even though a link is missing.

Say you have a query to get posts, username of the author, and the company that employs the author. For this, you have 4 entities represented. We are not including any information about the person, but just using it to get from the user account to the employer.

Post > User Account > Person > Employer

Your table would look something like this

Post Title Author Employer
Foo linclark DERI Galway

Your RDFa could look something like this

Post Title Author Employer
<tr about="node/1"> <td property="dc:title">Foo</td>
<td rel="sioc:has_creator">
  <span about="user/2" 
  property="foaf:name">linclark
  </span>
</td>
<td about="user/2" rel="sioc:account_of">
  <span about="person/2" 
  rel="rel:employedBy">
    <span about="company/9" 
    property="foaf:name">DERI Galway
    </span>
  </span></td>

The employer span tag is encapsulated by another element, the person span tag. Even though there is no field with information about the person, this maintains the relationship.

There is a chance it might not be as hard to do this as I thought.

davidseth’s picture

Going back to the original issue:

I am no expert on RDFa, yet at least, but I tried to emulate some parts. For example using the "Output this field as a link" option for the title and setting prefix:

But when I looked at the source code "dc:" had been filtered out.

I am having this same problem with using 'Rewrite the output of this field'. I want this

<a href="[url]" about="[url]" property="geo:lat_long" content="[field_voc_location_field_lat_long]">[title]</a>

But the output of views takes out the geo: part. Without the other complications that have been brought up in this thread, how can this be fixed? How can ['alter']['text'] be set to allow for ':' to appear? This doesn't even have to be an RDFa issue, just a text replacement issue.

Cheers,

David

merlinofchaos’s picture

Possibly filter_xss_admin() in core needs to be modified to allow RDFa keys through. Search the core issue queue and see if there is something about that?

davidseth’s picture

Thanks for the pointer. I have found this: http://drupal.org/node/732992 which talks about using a variable that can be overridden.

return filter_xss($string, variable_get('filter_xss_allowed_tags_admin', filter_xss_allowed_tags('admin')));

at comment 39: http://drupal.org/node/732992#comment-4352952

Still not sure how to get the ":" in though.. will keep on looking.

ELS Landscape’s picture

I am not expert either and in fact a relative newbie to Drupal., but I think Views is stripping everything, RDFa and tags Generated by the Meta Module.
All my non-views pages have the RDFa and Meta Tags.
Oddly when I log on to the site, they show up.

This is the case for Http and HTTPS pages.

ELS Landscape’s picture

I am wondering if Views could be used in this manner.

Specifying a person, place and date
foaf:name "Albert Einstein" .
dbp:dateOfBirth "1879-03-14"^^xsd:date .
dbp:birthPlace .

Or

Albert Einstein
1879-03-14

Federal Republic of Germany

Where someone can create a relative term referance from dbpedia.org

I suspect that is what Sparql views will do.

Anonymous’s picture

Yes, I would suggest watching the documentation screencasts on the SPARQL Views homepage. The RDFa output being discussed in this thread isn't related to accessing external content, it's just about producing RDF.

Any other questions regarding this kind of stuff should probably go in either the RDFx queue or the SPARQL Views queue, or you could ask on http://groups.drupal.org/semantic-web... the Views queue gets extremely busy, so we try to not bother the Views maintainers with other stuff :)

Anonymous’s picture

If anyone has the same issue and doesn't understand why RDFa isn't added to Panels or Views pages, please read my blog post about microdata support for Views/Panels.

As I've written about before, the way that Drupal core's RDFa works is by relying on the default entity/field template relationships. It places the structured data about the entity in the entity wrapper, placed by the entity template, and the structured data about the field in the field wrapper, which is placed by theme_field... Views and Panels generally don't use the entity template, but instead allow you to place different entities' fields willy-nilly about your page.

If you enable the entity template and the field template in Views/Panels output, then you will have the appropriate RDFa. Otherwise, it isn't supported for RDFa. It is, however, supported in microdata.