Open dshanske opened 7 years ago
thanks for summing this up!
hey, great! happy to talk wherever. and expanding to also include wordpress element markup sounds fine too.
i do still think we need to support priority, though. the micropub plugin, for example, needs to be able to render all mf2 properties that it handles, but it also should defer to any other feature-specific plugin that handles an individual mf2 property, since those plugins will generally be better.
i think we also need this coordination to work regardless of which specific plugins are installed. SemPress users, for example, often won't have this uf2 plugin, but should still be able to use micropub and other feature-specific plugins together happily.
given all that, the global variable approach seems to have two flaws:
i'm not excited about the feature approach described in https://github.com/pfefferle/SemPress/issues/51#issuecomment-303311143 either. it requires all plugins that use it to check and use the filter return value correctly. still, it may be the least bad option we have so far...?
@snarfed That's why I suggested this repo as the 'canonical' place for any microformats2 in wordpress discussion. The lack of single place to discuss things.
This is really where plugin dependencies would help a great deal, but saying that doesn't help with this. But why can't SemPress users, Micropub users, and Post Kinds users be encouraged to install this plugin, especially if it doesn't activate the extra features if the theme says it already supports them?
I'm worried about not only creating confusion for us, but for new people(who already find it confusing). I don't think there is an easy answer, but what we have now isn't working exactly.
My idea:
I agree with @snarfed, every plugin should handle it's properties, the best it can.
The main other authority for the rendering is the theme, so I would start defining the add_theme_support( 'microformats2-rendering', array( 'mf2_photo', 'mf2_name' ) );
discussed here: https://github.com/pfefferle/SemPress/issues/51#issuecomment-303132817
If a plugin like indie-post-kinds want to overwrite micropub functionality, it should be done individually be remove actions or filters or with changes done by filters and actions.
I might not want to. @snarfed's rendering could be nicer than mine.
Why 'mf2_photo' as opposed to 'photo' ?
If the theme is the only authority it is even better.
The syntax of the theme support was only a first shot, I would highly recommend to discuss and change the feature flags!
The theme being the top authority makes sense...as long as the theme knows how to do something. If it doesn't, it needs to fall back on something.
sure, and that can be handled with more granular theme support flags.
So, 'microformats2' as a theme_supports flag will have arguments for WordPress properties..For example, author, content, etc.
'microformats2_rendering' would have arguments for properties that don't directly map to WordPress properties? Or do we want to combine them into one single microformats2 flag with the differences set in properties?
We still, either way, end up with collision.
exactly. i would use microformats2
(because of its adoption) for both
Then prefixing the mf2 properties with mf2_ makes sense, I suppose.
ah, now I know why I proposed a new rendering flag... Let me think about that... perhaps we should create a section on the wiki, where we collect the different ideas and where we can define the flags. I hope @snarfed is ok with this too.
Why not have all possible plugins register support, and have the user specify their priority for applying them if both have support for that property? For example, both Post Kinds and Micropub register they support rendering checkins. The user specifies in configuration that they'd prefer rendering in the event of both?
-1 to putting the onus on the user to specify priority. They aren't going to want that responsibility, they just want an integrated experience. Just sounds like opening up a bad UX with a ton of options and configurations.
I'm suggesting 1 option...who has priority. Not on a per property basis.
We can call it, "Specify Default Rendering Plugin." or such. Rather than saying that each plugin sets a priority on a per property basis. It seems like that is too many low level settings.
https://indieweb.org/WordPress/Data - Is where we've put this stuff on the wiki before. I'll go garden a bit.
Playing devil's advocate, a user is going to ask why would I need to specify default rendering? We already hear routinely "why not just one plugin". Requiring a user to specify even once what plugin gets priority is just going to exacerbate that.
Then we're right back at, why not spin rendering out of all plugins into its own?
I don't begin to have an answer to the how, and as I stated in chat, it's a hard problem you are trying to solve with multiple plugins. But one worth tackling. I'm just trying to provide some perspective from user stand point based on feed back I've seen and read.
But that is what I meant... the main renderer is the plugin itself but it can be disabled by the theme... if a second plugin thinks it's a better renderer it should handle it individually using hooks and actions...
do we have cases where a plugin uses data from an other plugin?
Yes, Post Kinds uses any data stored in mf2_ whether it stored it or not. Micropub also stores there. But as I documented, there are some issues.
I mentioned that in a comment above and you corrected me:
If a plugin like indie-post-kinds want to overwrite micropub functionality, it should be done individually by remove actions or filters or with changes done by filters and actions.
Perhaps a misunderstanding...but as I said, this can be done individually, like we do with webmentions and semantic linkbacks https://github.com/pfefferle/wordpress-semantic-linkbacks/blob/master/semantic-linkbacks.php#L52 or am I wrong?
It can. I just want to brainstorm all options before we adopt. It is harder to change later.
ok, got you, but we shouldn't over engineer the feature on the other hand! plugins working really good together at the moment and we only have a problem to identify if a theme supports render features or not!
... and we should fix that in time... at least before we start investing time in new wp-uf2
features, because we currently only know if a plugin supports microformats2 or not and this might cause issues like with sempress and micropub.
hey @kraftbj, you've been interested in indieweb recently, any chance you could give us some expert guidance here? no good deed goes unpunished, and all that. :P
we're still discussing the exact goals, but broadly, we're trying to figure out how multiple plugins/themes should coordinate and decide, at post render time, which one renders a specific piece of mf2. here are some constraints:
options we've considered:
i'm sure other people have figured this out before, but i haven't had much luck googling for it (e.g. wordpress multiple plugins coordination :/). any ideas?
thanks in advance!
That's a dilly of a pickle. I would venture that this is something that's ripe for a filter--it already has the built-in priority system.
With both issues, it requires buy-in from other plugin/theme authors to use a common format/scheme. I think the filter is more akin to WordPress thinking. Let me read through this issue, the core ticket that was attempted for mf2 support, etc with more thought some.
another thought: is there any way to get the full list of callbacks registered for a given filter, along with their priority? if so, we could use that and just call the first one. kind of goes against the philosophy, i know, but still.
i didn't find anything like that in the docs, so i'm guessing not, but figured it was worth checking.
The problem with filters/actions is: As a theme developer I would not want to disable a lot of filters to remove micropub, semantic linkbacks or indie post kinds rendering, because I never know which other or new plugin might highjack the rendering.
We could get the list of filters by accessing the $wp_filter
global directly. IIRC, $wp_filter['hook_name']
has an array of all of the callbacks. That said, I'm hesitant to suggest that. It would make it a real pain for other developers debugging since that's really atypical, Core doesn't want folks poking around the global, and could have breakage if Core changes the structure (which they would do without worry about backwards compat since they aren't expecting folks to interact with the global).
That said, I would suggest themes use a plugin for this rendering. I'm basing this recommendation on my experience with Jetpack and Open Graph tags. OG tags are the Facebook-made quasi-standard for informing social media platforms what title, featured image, etc to use when sharing. Jetpack renders some in our head
and other plugins can/do as well (Yoast, All-in-One SEO, etc).
Often, to be frank, themes that attempt to add their own do a pretty poor job of it. No filters, no ways to stop it, no way to extend it, may not keep up with current best practices for the tags, etc. At Jetpack/Automattic, we see them as firmly plugin territory for all these reasons.
Within Jetpack, we keep an array of plugins that we know also output these tags--one hardship is duplicate tags will break Facebook rendering, thus fail to share if trying to post via an API or fail to display as expected when shared manually. ( Our array of OG providers: https://github.com/Automattic/jetpack/blob/master/class.jetpack.php#L200-L258 ).
When one of those plugins are present, we try to be good neighbors and deactivate ourselves. We also have a filter to either force on our tags ( also a one-line plugin in the repo: https://wordpress.org/plugins/always-use-jetpack-open-graph/ ) or force them off, which other plugins can use if either we don't list them or they want to play it safe ( https://github.com/Yoast/wordpress-seo/blob/23d33beb51ddedd4c3f8a7e45183f7e691e3a63b/frontend/class-opengraph.php#L45 ).
Likewise, Jetpack's OG implementation includes plenty of filters so if others want to extend our tags further, say in this case, another indieweb plugin is adding support for something not currently handled by wordpress-uf2, it can build on top of this instead of trying to start fresh.
As for SemPress and themes, my understanding is the theme repo does not allow you to require a plugin to use your theme, but you can throw a notice that a plugin is required for full functionality. Automattic themes do this pretty often when relying on or adding in special support for features only in Jetpack. Example: The Panel theme relies on the Jetpack Comic CPT for the fancy features https://wordpress.org/themes/panel/ .
Another more-recently updated example (3 weeks ago) is the Boardwalk theme. It includes this file to determine what plugin dependencies are needed and to throw an admin_notice
to ask site owners to install/activate the requested plugins: https://themes.trac.wordpress.org/browser/boardwalk/1.0.13/inc/plugin-enhancements.php
With a list of other known microformat2-producing plugins, we can try to attempt coordination -- to play nicely -- though on some level, it will still come down to site owners not installing conflicting plugins.
Thoughts?
@kraftbj thanks for the long answer and thanks for sharing the jetpack example and I like how jetpack works together with other plugins.
For themes I see it a bit different. I don't think we should recommend plugins in themes, that is what the IndieWeb plugin is for. If someone wants to enable IndieWeb tech he would start with the plugin I think. If we do it on several level, the user distraction is getting even worse. I also think a theme should be the main authority for rendering code, that said, we should implement mf2 stuff directly in themes and the mf2 plugin should only be a fallback for "normal" themes.
What I am missing is a way to tell other plugins what the theme is able to render. for example the micropub post-metas, or even more generic, the mf2_photo
post-meta.
I would phrase it different. The theme is responsible for the presentation of the data. The output of the data itself is between Core, plugins, and themes. Microformats is a kinda bit between worlds. Ideally, though, if more theme devs can get on board with Indie ideas, we hopefully would have people find themes first, then the plugin later. Genesis added Schema.org, which is how some people discovered structured data, etc. FWIW, I'm operating that I'm (and other end users) are going to pick themes that "look pretty" or were built for them by developers, who may or may not know anything about indie web. I have no inclination to change the design styling of my website and still want to be a first-class indie web citizen. Presentation before functionality in a theme.
Could the theme suggest the IndieWeb plugin, even perhaps which of the features/plugins offered by the IndieWeb plugin? If the community-suggested plugin had hooks that the theme then could disable, or even in an array, e.g. $microformat_support = array( 'photo', '...', etc);
The Indieweb (or wordpress-uf2, etc) plugin would have a serious of has_microformat_support( $feature )
type functions, add_microformat_support( $feature)
, etc that are used to short-circuit plugin output. The theme uses these functions with proper function_exists checks. Basically mimic the theme_supports
series of functions.
OK, but if a theme is not developed with IndieWeb principles in mind, they would not suggest the IndieWeb plugin either... if they are, it is not that difficult to directly integrate MF2 support...
I would also vote against:
If the community-suggested plugin had hooks that the theme then could disable, or even in an array, e.g. $microformat_support = array( 'photo', '...', etc);
As I said, I see the theme as main authority for markup and it you have only one theme installed at a time. With plugins it is different, you could have several plugins that might want to render the same data and the number of plugins might raise with the popularity of the IndieWeb. So it is nearly impossible to deactivate all plugin hooks and it is way easier to define a constant in the theme that tells the plugins to not render specific data, like with has_theme_support
. I would also vote against has_microformat_support( $feature )
as a wp-uf2
feature, because you can't get sure that this plugin is installed. I for example do not use it, because I have no benefits at the moment. I also do not use the IndieWeb plugin, because it has also no benefits for me.
I would recommend to build a toolset that works without forcing the users to install a bunch of different plugins. If I only use the SemPress theme with the Indie Post Kinds and Micropub plugin it should work the same way as if I use the whole IndieWeb plugin stack.
Maybe I have a gap in understanding. Why would anyone install a microformat plugin when using a theme that already provides microformats? Would it be easier, in your case, to have SemPress throw an admin notice to let folks know that "Looks like you're using this theme at the same time as XYZ plugin, which duplicates our functionality. For best results, please deactivate XYZ plugin"?
Another alternative would be to determine what does it mean to have "microformat support" in a theme and explore getting that added to the theme_support functions. That would be a longer road though.
@kraftbj this plugin just was added to the IW community repo and updated, so there wasn't a focus on it. Now a theme could use this plugin to handle the heavy lifting for adding things like h-entry
to post classes for instance, then build in deeper mf2 support. At least that's how I understand it. We are only talking about a handful of themes that do mf2 at this point afaik.
That's why I think this conversation has diverged a bit from the initial issue and become diluted with thoughts of merging all of the plugins into a master plugin.
@kraftbj now we are speaking the same language :)
It might be possible that SemPress and the wp-uf2 plugin might be installed at the same time, because of a possible future IndieWeb plugin bundle...
Another alternative would be to determine what does it mean to have "microformat support" in a theme and explore getting that added to the theme_support functions. That would be a longer road though.
That is what I tried to propose at the top of the conversation ;)
First step:
Second step:
But I am not sure the second step is really possible...
Alright, hmm, What about:
has_theme_support
for now. Long-term, use has_theme_support
check_theme_support
functioncheck_theme_support
looks for a filter -- indieweb_has_mf2_support
. It defaults to false.indieweb_has_mf2_support
check_theme_support
. If true, it aborts whatever is the agreed upon definition of support.Agreed that plugins can handle it internally.
Agreed the second step would be hard. I need to think on that one more.
But we have to be more specific:
Maybe some system like the following pseudocode:
function has_theme_support( $feature ){
if ( apply_filters('mf2-no-plugin-rendering', false ) ) { // kill switch to indicate the theme supports everything and the plugin shouldn't do anything that is checking for support.
return true;
}
$return = false;
$supported = apply_filters('mf2-features', array() );
if ( in_array( $feature, $supported ) {
$return = true;
}
return apply_filters( 'mf2-features-' . $feature, $return ); // dynamic filter so individual features can be easily added on the fly, e.g. add_filter( 'mf2-features-photo', '__return_true' );
}
The plugin would then just check for has_theme_support( 'photo' );
before outputting those particular tags and the theme author can add selective or absolute indicators of what it will handle, etc.
...and the function should be implemented by the theme?
The theme could just add a add_filter('mf2-no-plugin-rendering', '__return_true' );
. The uf2 plugin adds the code in the previous comment and adds the has_theme_support
(needs a better name) checks before outputting.
Likewise, the plugin can also check for the mf2-no-plugin-rendering
filter early and return out before doing anything at all.
If a theme is only dealing with a few mf2 fields, then a:
add_filter( 'mf2-features', 'bk_mf2_features' );
function bk_mf2_features( $features ) {
$features[] = 'photo';
$features[] = 'something';
return $features;
}
why not a more granular add_theme_support? https://github.com/pfefferle/SemPress/blob/master/sempress/functions.php#L102
Same thing really. I thought the issue was needing more specificity, add_theme_support
I don't think allow for multiple declarations (e.g. add_theme_support('something', array(...);
followed by another one later with different values in the array... I could be wrong on that.
With the idea above, your theme could kill all processing from anywhere as well as another plugin could say that it is outputting a certain type (say to override the indieweb plugin's implementation of something specific). Filter priorities would determine what happens in the end, so if you really want to ensure nothing happens, remove_all_filters
and add only yours, etc (assuming it fires later enough).
add_theme_support
and get_theme_support
doesn't allow for all of that IIRC.
My intention was to kill all plugin processing if the theme already supports this type of rendering.
add_theme_support( 'microformats2' , array( 'author', 'mf2_photo' ) );
should tell all plugins that the theme supports author-markup and that it can render the mf2_photo
post-metas for example... so plugins should skip rendering for these two features.
I don't like the add_filter('mf2-no-plugin-rendering', '__return_true' );
because this results in the same problem we have now... mf2 rendering can only be "on" or "of", but we need a more granular system.
What a theme could provide is something like add_filter( 'mf2-features', array( 'author', 'mf2_photo' ) );
, so the plugin can check by adding the apply_filters( 'mf2-features' );
but this feels a bit like the wrong way round...
but this feels a bit like the wrong way round...
I can't speak to how it fits core philosophy, but from someone who would be a consumer of that filter, it makes sense.
It makes sense for you that a bunch of plugins have to init the exact same filter and one single theme is setting it?
I think this might cause some serious race condition problems, because you do not have a priority on the apply_filters
, only on the add_filter
.
If you switch it around, so that the theme applies the filter, the theme has all the knowledge, that the plugins need.
I don't like the add_filter('mf2-no-plugin-rendering', '__return_true' ); because this results in the same problem we have now... mf2 rendering can only be "on" or "of", but we need a more granular system.
Trying to give theme authors a master kill switch. It was an afterthought to avoid a theme author needing to declare everything if they wanted total control...trying to meet you in the middle on our philosophical divide on if the theme should be the end-all of markup :)
add_theme_support( 'microformats2' , array( 'author', 'mf2_photo' ) ); should tell all plugins that the theme supports author-markup and that it can render the mf2_photo post-metas for example... so plugins should skip rendering for these two features.
Right, but if there's another plugin that extends upon wordpress-uf2, it can't redeclare add_theme_support
afaik if it needs to.
What a theme could provide is something like add_filter( 'mf2-features', array( 'author', 'mf2_photo' ) );, so the plugin can check by adding the apply_filters( 'mf2-features' ); but this feels a bit like the wrong way round...
I think this is basically my idea, but the plugin would have a helper function to deal with it. For example, a theme author could do the full declarative array (like your example, but would need a callable since the array can't be declared directly there), but could easily just do add_filter('mf2-features-author', '__return_true');
if it wanted to.
I think this might cause some serious race condition problems!
It all depends on where it is hooked. All of the add_filter
happen as the plugins/themes are loaded and helper function (with the apply_filters) fire on runtime within the_content
, etc action... it should work.
@snarfed, @pfefferle and I were discussing the problem of various plugin interoperability in https://github.com/pfefferle/SemPress/issues/51
It occurred to me, if we are going to set this up, this repo is probably the better place to keep the discussion and possibly any functionality or such we want to support it.
Right now, Micropub takes over rendering if add_theme_support( 'microformats2' ) is not set. This plugin loads microformats2 compatibility functions(add h-entry, etc) if the same flag is set.
So, the add theme support flag should, in future, be used solely to discuss a theme's support for marking up standard WordPress elements, as opposed to properties stored solely in meta. We can be more granular in future if needed.
Rendering microformats2 properties from Post Meta probably requires a global variable(the same way that add_theme_support, register_post_type, etc are in reality global variables).
The issue that was being discussed was priority on any given feature. WordPress registration does this with the last one to register, as registration is done by hook. Same can apply here.
While I still think we can combine our rendering efforts, for now, I want to try to build this as a class here in Microformats 2, which could then be included in the other plugins. Thoughts?