TL; DR: Microdata强制您在与此itemprops vaule的itemtype相同的元素上使用itemprop。如果你想将你的模板分解为部分,你如何处理这个问题?该元素可能只出现在两个位置中的一个位置,包含在包含模板中或包含的部分中,两者都不能很好地工作。
我正在使用带有haml的Rails,但我想我的问题适用于任何模板引擎,您可以将模板拆分为较小的部分。我大量使用partials,这意味着我的模板通常不超过10行代码。但是将微观数据拟合到这些中看起来过于复杂,那么你应该如何正确地使用微数据?
举个例子:
#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 }
现在有了微观数据:
#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
然后是什么?我必须在同一个div上添加VideoObject
itemtype,其中包含itemprop: 'video'
,因为这就是微数据的工作原理。所以:
#app/views/articles/_article.html.haml
%div{ itemprop: 'video', itemscope: true, itemtype: 'http://schema.org/VideoObject' }= render @article.video
但是我不能在视频部分中再次使用相同的itemtype。现在这将无效:
#app/views/videos/_video.html.haml
%div[ video, itemscope: true, itemtype: 'http://schema.org/VideoObject' ]
但是itemtype属于视频。我不想在每个容器元素中重复它。我希望能够在其他地方使用视频部分,并将其声明为带有微数据的视频。因此整个事情必须从文章中移出部分并进入vido部分,如下所示:
#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' }
同样,itemprop必须与视频项类型位于同一元素上。但为什么视频应该部分关注/知道如何调用itemprop它是值?
我唯一的解决方案是将itemprop传递给partial。这也意味着,如果没有传递,我们必须声明一个默认的itemprop。所以我们最终得到了这个:
#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' }
这看起来过于复杂。我发现将itemprop的名称传递给partial也很困惑,因此partial知道itemprop被调用的是什么值。这有多奇怪?在编程中没有其他地方我遇到了需要知道指向它们的东西的名称的对象。
那么有更好的既定方法吗?或者就是这样,我不应该对它如此痴迷? ☺
答案 0 :(得分:2)
不得不阅读它几次以获得问题的要点。这是一个很好的问题!
TL; DR:是的,你有点婊子,但是还好!使用装饰器或单元格使其看起来感觉更好但不幸的是,总是需要一种方式让两个范围进行交互,并使用父范围来影响嵌入的范围。
更长时间阅读:看看你的问题,它似乎主要是基于一个在其他编程领域也很常见的问题,它在计算中引起了很多讨论和不满(参见JavaScript范围)例)。我正在谈论对象的范围。在这种情况下,我们讨论的是两个元素的范围,其中一个元素在嵌入父元素时必须表现不同。
在问题的实际水平上;你是对的,部分应该负责向对象提供itemscope和itemtype。从对象的角度来看,这对我来说最有意义,并且与文章的顶级元素一致。作为查看它的方式,我会接近它。在这种情况下,它是最稳定的。
对于在嵌入时在该元素中提供itemprop的解决方案;如果从渲染的地方传递它似乎是最合乎逻辑的解决方案。我同意这看起来不像红宝石的方式"所以我建议你看看decorators或cells。这两个都可以帮助您清理您的视图/部分。由于您似乎已经进入部分方法,因此单元格可以在视图中为您提供额外的控制器层。非常有用。
我喜欢@jfornoff建议您创建更通用的解决方案,您也可以将其用于除视频之外的其他项目。还有solutions out there for microformats。微格式助手和Html架构似乎都试图帮助你实现这一目标,尽管两者都需要一些新的贡献。
答案 1 :(得分:0)
我认为你犹豫是否犹豫不决将div-business置于局部,因为它在语义上并不属于那里,如果你想在没有div的情况下将视频呈现在其他地方,你就会遇到麻烦。
所以这就是我的建议:
您可以考虑将视频对象(我认为它是某种模型)包装到装饰器中并在那里渲染div-business。
你甚至可以制作一个通用的微数据-div-partial,这可能类似于:
%div [ your-item-type ] { itemprop: propvar, itemscope: true, itemtype: typevar } render item
这可能在语法上太可怕了,抱歉。
所以基本上: [控制器]
@video.decorate
- > [查看]:
@video.render_with_micro
- > [Decorator]:使用@video作为项目和给定的itemprops,itemtypes呈现microdata-div-partial - > Itemprops,Itemtypes正在装饰器内维护(这是他们属于IMO的地方,它们是代表信息)。
我希望我的braindump有帮助, 干杯!