Add support for embeds in the theme template hierarchy

Description

oEmbed embeds (introduced in #32522) use wp-includes/embed-template.php as the template file. The embed_template filter is available to override this.

The addition of an embed.php file to the template hierarchy should be considered, to make it easier for theme developers to style the output. Portions of the current embed template (particularly the share dialog markup) could be split into template functions to aid this.

Change History (57)

It's worth noting that the embed template isn't just a regular theme template. For example, there's no wp_head, but a do_action( 'oembed_head' ); instead. That's why I hesitated to introduce a get_embed_template function and add it to the "waterfall" in template-loader.php.

Happy to reconsider this, but we need to make sure people don't mess it up.

I like this, but I agree that because it's not a regular theme template it does become somewhat of an outlier. It will be the only template in the default template hierarchy that acts differently to others.

Maybe we need an example template for Twenty Fifteen or Twenty Sixteen, in order to see if this works well in practice.

Yeah, wp-embed.php sounds better for the theme template, though I wouldn't necessarily move the core default template to wp-includes/theme-compat/ as the files in that directory are deprecated and only there for backwards compatibility reasons.

Maybe we need an example template for Twenty Fifteen or Twenty Sixteen, in order to see if this works well in practice.

Attached is a demo of a custom embed template in Twenty Sixteen. Although most of the styling can be done using the various hooks in place, having complete control over the template made it easier to customize it.

One risk would be that plugin would have a hard time adjusting the template when themes remove those hooks.

BTW, the "embed_template" filter is a bad filter name because it is shared with the *_template filter in get_query_template. If you hook to embed_template and then call get_query_template('embed') from inside that function, you have created an infinite loop without knowing why. Ran into that this morning.

I'd kind of prefer embed-post_format, honestly. For post types, embeds really don't make a heck of a lot of sense except in special cases, and filters would work better for adding special formats to go with the post types. For themes that support post formats though, special templates for embed per format make more sense.

I'd kind of prefer embed-post_format, honestly. For post types, embeds really don't make a heck of a lot of sense except in special cases, and filters would work better for adding special formats to go with the post types. For themes that support post formats though, special templates for embed per format make more sense.

I tend to think the same, but post formats are currently not really taken into account in the template hierarchy. Themes are usually using get_template_part() for different post formats. embed-format-{post-format}.php could be an option though.

Other than that, 34278.get_embed_template.patch​ looks good. We just need to make sure nothing breaks when checking for is_embed() before is_404() and that customizing the embed template is actually easy enough.

For themes that support post formats though, special templates for embed per format make more sense.

I understand your logic, different embed templates for text, video, audio and other formats. It's nice. But the problem with post formats is that it's a closed list of formats. Developers can't add new formats. And (my) clients usually skip the formats - they prefer to add another taxonomy term for videos.

Also, I work with israeli startups and almost all my projects use custom post types (+95%). With post types I can create new "formats" like code snippets, presentations, maps, polls, etc. Post types provides more control to developers with single-{post-type}.php and archive-{post-type}.php.

Each one of those new post-types needs a different embed template. This is why I think embed-{post-type}.php is better - its consistent with the current template hierarchy.

More to the point, post types don't need a hierarchy for embeds, because that's not the purpose of post types. A custom Post Type is not just some special kind of "Page" after all.

Custom post types should not be considered for inclusion in this hierarchy at all. It doesn't make sense to include them:

I have many examples why you should considered post-types and why it makes sense to include them:

Code snippets post-type, when embedded, will show the code in a beautiful code editor, with it's own JS and CSS. I can do it easily using embed-snippet.php.

Maps post-type, when embedded, will show only the map. I don't need the site title, the description, or the other elements the default embed template present. With embed-map.php I can embed only the map.

Video post-type, when embedded, will show a player like youtube. The player has it's own embed button. We don't want to use the the default embed buttons. embed-video.php is the solution.

Presentations post-type, when embedded, will show the presentations player using embed-presentation.php.

The new embed-templates for specific post-types will make it easier to build complex application using WordPress.

Post types are created in plugins. If you need to include a special embed format for a post type, then that format should really be in the same plugin that contains the post type. It doesn't make a whole lot of sense to include post-type support for them in the theme, because the theme doesn't necessarily need to know about the post types. Post types and themes don't really mix well.

I'm not saying that post types can't get special embed handlers, but separation of concerns means that it makes more sense to include said embed handler in the plugin where the post type is created in the first place.

For example, for your code snippet post type, the plugin that adds this could hook in and include the embed-code in that plugin, and then the theme would remain independent of it and available for use elsewhere.

Again, I understand the logic, post types are plugin territory. So why do we support single-{post-type}.php and archive-{post-type}.php in themes? And if WordPress already supports those template files, why not embed-{post-type}.php?

But just because some existing part is wrong doesn't mean we should continue along those lines. Post types should be the domain of plugins, really. Making themes have additional knowledge of them is bad in general.

Plugins can just as easily add custom templates too. That's not really the issue.

The issue is one of separation of presentation and content. Themes should not have special cases for custom post types because post types are a form of content and themes are the means by which the content is presented. If the content is tied tightly to the theme, then that's a form of lock-in. It limits the ability to change the theme (alter the presentation) without losing some portion of the content. That limitation should be avoided when it is possible to do so.

But just because some existing part is wrong doesn't mean we should continue along those lines. Post types should be the domain of plugins, really. Making themes have additional knowledge of them is bad in general.

I think the current WordPress structure is consistent, templates for CPT's are {archive|single}-{post-type}.php. My proposal in comment 26 is to maintain this consistency with {archive|single|embed}-{post-type}.php.

Pages are an exception, let's not further complicate the theming experience by adding another. It's logical that if a theme does not style a CPT it falls back to the default.

@swissspidy We can't just remove the embed_template filter, we need to support it for back-compat. Otherwise, looks pretty good, other than that I'd probably also add a check on $object following initialization with get_queried_object().

@swissspidy Oh, nvm. I forgot about comment:20. In that case, we should consider whether a special case should be added in get_query_template() for the expected theme-compat path that precedes the hook currently, even though it was changed in 4.5.

@swissspidy We can't just remove the embed_template filter, we need to support it for back-compat. Otherwise, looks pretty good, other than that I'd probably also add a check on $object following initialization with get_queried_object().

Regarding the $object check, that's not done in any/most of the other template functions like get_category_template() or get_single_template().

As for the filter, I'm not sure it's worth it / really needed. Let me think about it for a bit.

Thought this through a little bit and conferred with @swissspidy, and the consensus is that we never should have introduced the embed_template hook in 4.4 because of the conflict pointed out in comment:20

The good news is that @obenland has kindly checked a slurp of the themes repository and it looks like no themes have yet implemented embed.php templates, which means we're in the clear to dump the explicit embed_template filter and simply rely on the fallback behavior in locate_template() to infer the /theme-compat/embed.php path put in place in [36693].

Disclaimer: If it turns out some theme somewhere outside the themes repository is using an embed.php template, I would think we've done due diligence to ensure backward compatibility in terms of the template hierarchy. @obenland is simply the ack master in this scenario and makes no guarantees nor grants liability for the results of his search.