indieweb / wordpress-uf2

add "Microformats 2" classes to your WordPress theme
https://wordpress.org/plugins/wp-uf2/
23 stars 5 forks source link

Microformats 2 Rendering #30

Open dshanske opened 7 years ago

dshanske commented 7 years ago

@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?

miklb commented 7 years ago

It makes sense for you that a bunch of plugins have to init the exact same filter and one single theme is setting it?

Well, when you put it that way, no 😄

I'd guess there would be priority on the filter, which would help, I think @snarfed said he'd want micropub to only output if no other plugin was using the data for instance.

I was looking as a consumer of the code add_filter( 'mf2-features', array( 'author', 'mf2_photo' ) ); in that it makes sense when I read that filter.

pfefferle commented 7 years ago

I am not sure we are talking about the same things (sorry I am German) ;)

With the add_theme_support I, as a theme developer, want to have a way to disable some renderings of plugins! The add_theme_support should not be extended or changed by any plugin and it should not be a global registry where plugins should hook in, to register themselves for a specific use case. If two or more plugins are fighting for the same output, this should be their way to find a solution (for example with remove filters and/or priorities) and I am not sure if there should/can be a generic way, because the data for these specific renderings might differ so much between the different use cases.

pfefferle commented 7 years ago

Ok, perhaps it makes sense to try to have a generic way also for plugins, put I am not sure if we should mix both.

pfefferle commented 7 years ago

@kraftbj who should provide the apply_filter wrapper? And don't forget that the content is not the only place where data is changed.

kraftbj commented 7 years ago

I apologize for the delay. Headed out of town for a vacation next week so trying to get everything at work packaged up. I meant to draw a diagram of how this all fits together. If I'm not making sense after this comment, I'll do that for when I'm back :)

The indieweb/wordpress-uf2 plugin (wherever, the "plugin"):

  1. Has the has_mf2_support function I psuedo-coded above wrapped in a function_exists call.
  2. The code that outputs microformats checks has_mf2_support( 'photo') before outputting.
  3. In short, "apply_filters" would happen in the plugin, but all within that helper function to 1. help keep logic in once place and allow for both kinds of filters I outlined (or all three if you include the kill switch, but I'm fine with ditching that).

Any theme that wants to declare support:

  1. Has a add_filter call in functions.php ( as demo'd in https://github.com/indieweb/wordpress-uf2/issues/30#issuecomment-312116320 )

As far as loading:

  1. The plugin wraps the call in an function_exists just to be safe in case something else is declaring it too... a forked version of the plugin or whatnot.
  2. The theme is only using add_filter, so it doesn't really need to care if the plugin is installed or not. Worst case, it's a filter added that's never checked. No biggie.
  3. As long as the rendering is happening after the theme is loaded (anytime after after_theme_setup), it should be fine. The only problem would be if a plugin is declaring support and does it in some odd hook (vs just when the file loads). Any rendering would be happening later, after the query is parsed, etc,.
  4. Any confusion of priority would be resolved using WP Hook's filter priority system, if such a situation would even come up.

The theme could disable the plugin by passing the features you support. If there is some specific setups where a feature needs to be disabled in specific contexts, a plugin/theme can add a filter later, e.g.

add_action('pre_get_posts', 'bk_selective_disable');
function bk_select_disable(){
if ( is_page() ){
add_filter( 'mf2-features', 'bk_mf2_features' );
}
}
function bk_mf2_features( $features ) {
$features[] = 'photo';
$features[] = 'something';
return $features;
}

In other words, it can wait until the query is parsed and the conditional functions are available, then declare support if there is only support in certain contexts. Hooking on pre_get_posts or wp or something between plugins/theme loading and wp_head should allow for things to be modified before output.

pfefferle commented 7 years ago

I would prefer a solution that can be implemented without relying on a third party plugin! If someone have not installed the wp-uf2 plugin, the whole functionality will not work. And until we have no IndieWeb plugin bundle, we could not control this case.

miklb commented 7 years ago

As a follow up, per a conversation in #indieweb-wordpress with pfefferle:

"so I see uf2 not as a manager, but as another participant, like semantic-linkbacks, micropub and indie post kinds."

I hadn't caught that in the thread, and think it helps clarify the discussion.

I thought the idea was to move to the mf2 plugin playing a larger role in the ecosystem, and with the ability to have themes "turn off" certain features, there would be encouragement to run it along side a microformats2 theme.

kraftbj commented 7 years ago

I don't understand the comment about the third-party plugin. This solution would mean the theme would 100% work stand alone OR alongside any plugin that uses this framework. I mean, sure, use theme-supports instead. Same idea just most limited with less flexibility.

If any plugin wanted to go along with this idea, it can include the same function wrapped in a function_exists call to avoid double-declaration.

Another alternative is just straight up say a theme works with a third-party plugin or say it doesn't period.

At the end of the day, I don't understand. We want a functionality that works with third-party plugins but using a third-party plugin is a non-starter?

kraftbj commented 7 years ago

When I'm back from vacation, I'll put together a basic suite showing the interaction in code.

snarfed commented 7 years ago

thanks so much for talking and working through this, everyone! sounds like you may actually all be agreeing on the same general idea, and disagreeing at most on terminology and semantics. good sign!

you're all closer to wordpress than i am, so i trust you and i'll happily follow (in the micropub plugin) whatever you all settle on. especially hoping it satisfies these three goals of mine, but even if not, i'm flexible.

  • for each piece of mf2 in the post, we want at most one thing to render it, either the theme or a single plugin. (if nothing is available to render it, that's fine.)
  • we don't want to assume that any one specific plugin or theme is installed. (ie, we don't have a single obvious master coordinator.)
  • we want plugins/themes to declare their own priority, and have the highest priority win and render.

thanks again all!

snarfed commented 7 years ago

checking back in here. is there a conclusion on the common design we all want to implement in our plugins and themes? i'm ready to implement it in the micropub plugin!

snarfed commented 7 years ago

friendly ping!

pfefferle commented 7 years ago

Sorry, but I off for vacation for the next two weeks...

snarfed commented 7 years ago

no worries at all. enjoy!

snarfed commented 7 years ago

friendly nudge! @dshanske @kraftbj @miklb @pfefferle do we have a conclusion here on a design we all agree on yet?

pfefferle commented 7 years ago

not that I know...

dshanske commented 6 years ago

It just occurred to me. If we want to surface this to a user, that means shouldn't we be using the options table? It is a user option.

So, in the event an option isn't set, there are now 2 ways to set the default.

  1. The old way: get_option - https://developer.wordpress.org/reference/functions/get_option/
  2. The new way: register_setting - https://developer.wordpress.org/reference/functions/register_setting/

What about:

No matter what, every plugin and theme would have to implement code the logic regarding it, although we could have a repo with the code in question and include it as a dependency. If we write it correctly, then it shouldn't need to be changed.

miklb commented 6 years ago

Just so I understand:

I write a theme and I set an option saying "This theme handles all mf2 output."

Someone installs and activates this plugin (wordpress uf2). They get an admin notice telling theme "hey your theme is already configured to output mf2 data, you do not need to activate this plugin."

User then activates hot new IndieWeb plugin. Hot new plugin sees that the theme is handling output and doesn't display anything on the front end?

That's then assuming the theme author is familiar with hot new plugin and the user will still get the desired result?

Or does that just signal to the plugin, "hey this theme is mf2 ready, fire output at will."

Or something entirely different?

dshanske commented 6 years ago

All really good points. So...

  1. The option is that the theme supports microformats2. One would assume that themes that care would, over time, set themselves up with specific properties they support in the same option. But initially, shouldn't the assumption be, without any other data, they know what to do?
  2. User activates new plugin, and I wouldn't say the new plugin couldn't, on activation, surface an input to the user to setup configuration options if it wants?

No matter what, new things will break old things. This has to be a change we'll all support some form of as soon as possible, no matter which one we go with. So, with that in mind, anyone who doesn't support this new option, however we implement it, what should we do? The safest thing is to back off if they didn't declare more.

miklb commented 6 years ago

I guess from a theme maker standpoint, as long the plugins have a way for the theme to override a plugin output, default to outputting by the plugin would make sense. So if Hot New plugin displays something my theme doesn't, in a future theme update I could override the plugin and display it differently if necessary.

snarfed commented 6 years ago

woo! we all met today and agreed to try out this proposal: https://github.com/indieweb/wordpress-uf2/issues/30#issuecomment-312375228 .

we also discussed the broader plan for indieweb wordpress plugins and themes in general. we settled on doing more in the official indieweb plugin, ideally focusing on a wizard style UX. @dshanske and @miklb let me twist their arms into eventually drafting a design doc for how that should look.

thanks everyone!