Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Microdata: How to use with templates/partials?

TL;DR: Microdata forces you to use the itemprop on the same element as the itemtype that is this itemprops vaule. How do you deal with this, if you want to break up your template into partials? The element may only appear in one of the two places, either in the containing template or the included partial, both of which does not really work well.

I am using Rails with haml, but I guess my question applies to any templating engine, where you can split up your template into smaller partials. I am heavily making use of partials, that means my templates are usually no longer than 10 lines of code. But fitting microdata into these seems overly complicated, so how are you supposed to use microdata properly with partials?

Take this example:

#app/views/article/show.html.haml
%p Hey, Welcome! Read This wonderful article:
= render @article

#app/views/articles/_article.html.haml
%div[ article ]
  %h1= @article.title
  %p= @article.description
  %div= render @article.video

#app/views/videos/_video.html.haml
%div[ video ]
  %h2= video.file_name
  %video{ src: video.url }

And now with microdata:

#app/views/articles/_article.html.haml
%div[ article ]{ itemscope: true, itemtype: 'http://schema.org/Article' }
  %h1{ itemprop: 'name' }= @article.title
  %p{ itemprop: 'description' }= @article.description
  %div{ itemprop: 'video' }= render @article.video

And then what? I have to add the VideoObject itemtype on the same div, that has the itemprop: 'video' because, that's how microdata works. So:

#app/views/articles/_article.html.haml
%div{ itemprop: 'video', itemscope: true, itemtype: 'http://schema.org/VideoObject' }= render @article.video

But then I can't use that same itemtype again in the video partial. This would now be invalid:

#app/views/videos/_video.html.haml
%div[ video, itemscope: true, itemtype: 'http://schema.org/VideoObject' ]

But the itemtype belongs to the video. I don't want to repeat it in every single container-element. I want to be able to use the video partial everywhere else and still have it declared as a video with microdata. So the whole thing has to move out of the article partial and into the vido partial like this:

#app/views/articles/_article.html.haml
%div= render @article.video

#app/views/videos/_video.html.haml
%div[ video ]{ itemprop: 'video', itemscope: true, itemtype: 'http://schema.org/VideoObject' } 

Again, the itemprop has to be on the same element as the video itemtype . But why should the video partial care/know how the itemprop is called that it is the value of?

The only solution I have, is to pass the itemprop into the partial. This also means, we have to declare a default itemprop in case none is passed. So we end up with this:

#app/views/articles/_article.html.haml
%div= render @article.video, itemprop: 'video'

#app/views/videos/_video.html.haml
itemprop ||= nil
%div[ video ]{ itemprop: itemprop, itemscope: true, itemtype: 'http://schema.org/VideoObject' } 

That seems overly complicated. Also I find it quite confusing to pass the name of an the itemprop into the partial, so the partial knows what the itemprop is called that it is the value of. How weird is that? Nowhere else in programming have I encountered objects that needed to know the name of the thing that points to them.

So is there a better established way to do this? Or is that just how it is and I should not not be so whiny about it? ☺

like image 706
Conkerchen Avatar asked Sep 05 '14 06:09

Conkerchen


1 Answers

Had to read it a couple of times to get the gist of the question. And a good question it is!

TL;DR: Yes you're bitching a bit, but with good right! Use either Decorators or Cells to make it look at feel better but unfortunately there will always need to be a way for the two scopes to interact and the parent-scope to influence the embedded one.

Longer read: Looking at your problem it seems to be mostly based about a problem also common in other areas of programming and it has caused a lot of discussion and grievances within computing (See JavaScript scopes for example). I'm talking about scoping of objects. In this case we're talking about scoping of two elements where one has to behaves different when it is embedded into a parent element.

On a practical level of your problem; you are right that the partial should have the responsibility of providing itemscope and itemtype to the object. This makes most sense to me from an object perspective and is consistent with the top level element the article. I would approach that as the way to look at it. It's the most consistent you could get in this case.

For a solution of providing itemprop in that element when it's embedded; You're solution if passing it from the place it is rendered seems most logical. I do agree this does not look "the ruby way" so I would suggest indeed have a look at either decorators or cells. Both of these can help you clean up your views/partials a lot. As it seems you're into the partial approach cells can offer you an extra layer of controllers inside a view. Very usefull at times.

I like @jfornoff 's suggestion that you create more generic solution that you can also use for items other than just videos. Also there are solutions out there for microformats. Both the microformats helper and Html-schema seem to sort of try and help you in going that way although both are in need of some fresh contributions it seems.

like image 97
yopefonic Avatar answered Nov 16 '22 00:11

yopefonic