Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block request: post field #29173

Closed
carlomanf opened this issue Feb 20, 2021 · 13 comments
Closed

Block request: post field #29173

carlomanf opened this issue Feb 20, 2021 · 13 comments
Labels
New Block Suggestion for a new block

Comments

@carlomanf
Copy link

carlomanf commented Feb 20, 2021

This is a request for a new block, which I would consider naming something like "Post Field" or "Post Part" or "Post Section"

What problem does this address?

The main problem solved by this new block is that a post can only have one post content, but one post content may not always be sufficient.

For example, you might want to build a block-based theme where every post gets its own unique sidebar, rather than share the same sidebar with the rest of the site. This could be thought of as a "second" post content for the post.

What is your proposed solution?

This block would work similarly to the post content block, but each new instance of the block would require the user (or more likely, theme developer) to nominate a postmeta key to store the content. This would effectively let each post have multiple post content fields. It could look something like this:

<!-- wp:post-field {"key":"sidebar"} /-->

This block could be used directly within any singular template, within a query loop, or even within the post content as a kind of "local" reusable block. If it's used in the template, which I see as the biggest use case, its content can be edited using the template mode in the post editor.

@carolinan
Copy link
Contributor

Perhaps I am misunderstanding the example but you don't need post meta to add a sidebar to specific posts. Block templates and patterns have this purpose.

@aristath
Copy link
Member

aristath commented Mar 8, 2021

The example is indeed a bit confusing, but from what I understand this would be used to retrieve & print post-meta and any other field like that?
If so, then it would be extremely valuable! The only problem I can see here is how to show a list of post-meta available so the user can pick what they want, and also the fact that post-meta is not always a string but can be an array, an object, anything.
It will be useful to show simple post-meta, but if I'm building an e-commerce site for example then I'll want to be able to select the product-price for example which is also saved as a post-meta.
Or do we want to restrict this to the basic core metas, and then make it filterable for plugins in PHP so they can add their own post-meta to the list? That could work and make it in the MVP... 🤔

@carlomanf
Copy link
Author

The example is indeed a bit confusing, but from what I understand this would be used to retrieve & print post-meta and any other field like that?
If so, then it would be extremely valuable! The only problem I can see here is how to show a list of post-meta available so the user can pick what they want, and also the fact that post-meta is not always a string but can be an array, an object, anything.
It will be useful to show simple post-meta, but if I'm building an e-commerce site for example then I'll want to be able to select the product-price for example which is also saved as a post-meta.
Or do we want to restrict this to the basic core metas, and then make it filterable for plugins in PHP so they can add their own post-meta to the list? That could work and make it in the MVP... 🤔

It would retrieve and print post meta, but only in very limited circumstances. That is, it would always expect the meta value to consist of block markup. An e-commerce product price, a PHP serialised array, etc, would not work with this block.

The way I imagined restricting the meta keys accepted by the block is to add a prefix to the meta key, something like _blocks_ or _block_area_. A filter could also work, as you suggest, although I think the prefix is more lightweight.

In other words, the meta fields that work with this block are specifically to work with this block only. They wouldn't already exist prior to the introduction of this block, and probably wouldn't be updated through any other mechanism other than the user interacting with this block.

Showing a list of meta fields available would be done in a similar way to the reusable block and template part blocks.

@carlomanf
Copy link
Author

Perhaps I am misunderstanding the example but you don't need post meta to add a sidebar to specific posts. Block templates and patterns have this purpose.

The issue for me with block patterns is the permissiveness. I'm thinking of using this in a multi-user environment, where you might want a post author to be able to edit the main content of their post, and the sidebar of their post, but not be able to edit the structure of the template around those block areas. I'm aware of the "lock" feature, but it's too easy to circumvent for my liking.

I guess you could implement the sidebar using a reusable block or a template part that the post author has access to edit, but I imagine you'd have to use action hooks to dynamically instantiate it when a new post is created, and that seems cumbersome. Post meta seems like the most lightweight solution to me.

The other issue with that approach is it creates difficulty for the site manager to update the design. For example, you want to update the design and switch the columns around. If you use a block pattern, you would have to switch them around in every post one by one. The new block I'm requesting would allow you to set a common template and switch the columns in every post with one edit.

@eric-michel
Copy link

Just stumbled across this issue when searching for ways to interact with the postmeta table via blocks.

Or do we want to restrict this to the basic core metas, and then make it filterable for plugins in PHP so they can add their own post-meta to the list? That could work and make it in the MVP... 🤔

In my (admittedly brief) experiments with FSE, there are theme blocks that represent things like post title, author, publish date, etc. Is it currently possible to create custom versions of those that a block creator could connect to a postmeta value? It would be awesome if custom block creators had an API we could tap into to create custom theme blocks that would be exposed on pages that use the template they're added to (meaning show them on the page editor where they would appear rather than having the custom fields off in a metabox in the sidebar or beneath the editor).

This would allow the reuse of those fields in places like the Query block, or other templates dedicated to the same post type.

Maybe this is all currently possible and I haven't delved enough into FSE to know it!

@carlomanf
Copy link
Author

In my (admittedly brief) experiments with FSE, there are theme blocks that represent things like post title, author, publish date, etc. Is it currently possible to create custom versions of those that a block creator could connect to a postmeta value?

No, it's not, and that's mostly what this issue is about. The tricky part is that each field has its own unique needs with regard to input and output, and that makes it hard to provide a generic API that is useful. For example, the publish date needs a date picker for its input and the post title needs heading tags for its output, and so on.

My request is more limited in scope and only seeks to work with meta fields that act like post content, i.e. they take inner blocks on input and render inner blocks on output. It probably wouldn't solve all of your post meta needs but it would be a useful feature in some cases.

It looks like some people were finding it hard to make sense of that concept, but in the meantime, I found a ticket from several years back. It will be no surprise to anyone who opens it that I didn't read the whole thread, but I think it may be the same proposal from a pre-blocks era? @karmatosed

@eric-michel
Copy link

That totally makes sense. I'd love to see a built-in block that exposes a simple method of interacting with basic postmeta values, along with an API that would let custom block developers interact with the postmeta table using the editor's standard components.

@carlomanf
Copy link
Author

an API that would let custom block developers interact with the postmeta table using the editor's standard components.

I think you can already do that, as far as I'm aware. It's just that there's currently no way to do it through a built-in block.

@jeremyescott
Copy link

+1 on this feature, but I know it is a lot more work and a lot more complicated than the original reporter envisioned.

I understand how not all Post Meta is alike. It is easy to forget that if you're just developing themes with some ACF text fields. A plugin dev especially knows that there are lots of types of PostMeta that require pre-processing before it could be displayed, including:

  • Arrays
  • Objects
  • Otherwise serialized data
  • JSON strings
  • Formatted data that could come out of Post Meta as a string, but isn't useful, like a MySQL-formatted date
  • Booleans, which are stored as 1 if true, and not saved or 0 if false, but might present well as words like "yes" or "accepted"
  • and caches of these data,
  • and more.

Now, further, this feature needs to be more like a post template block like the FSE "Post Title" block, one that can be used in repeatable loops or block templates. Which poses the problem, on a hypothetical "post" or "post type" how do we know which post fields could even be available? The answer is that the plugin or theme that is generating the post meta should register the post meta, but the truth is there is no requirement that post meta be registered, and many plugin and theme developers do not take this extra step.

Yet, it is there that I see a partial solution available. I think this can be a "step 1"... and mind you, I'm spitballing here:

  1. Plugin developer uses register_post_meta() to register post fields that should be available to the block editor "post field" block. They need to pay attention to the subtype (ie: post, page, cpt), and type (string, integer, etc) and enable 'show_in_rest'
  2. The block editor reads registered post meta and determines a list of meta that are available to rest, have a name in the public space (doesn't start with underscore), and has a "stringy" data type of number, integer, or string.
  3. If the editor finds any available meta, the new post field block will show up, which has a drop-down selector of each field available.
  4. and/or, wether the editor finds available meta, the post field block will allow for a custom field be selected like we can unlock and select custom colors, etc, and the editor will run those data through a filter that ensures it is "stringy". This provides backward compatibility for users who made truly custom fields using the classic editor "custom fields" section (as so many tutorials say they should do) but I could also see this a reasonable place to not support this old behavior (gasp).

Like I said, step 1. This wouldn't be perfect.

That said, there are a lot of other use cases that would still be left out. If we look to Advanced Custom Fields, which a lot of people rely on to make custom fields, we'd be missing:

  • A boolean if/then based on post field, so labels before/after the field value are excluded when the field has no content
  • A post meta/field loop that loops through an array of multiple post meta data or array of items and presents each item.
  • A sub-meta/sub-field loop that reads an associative array data to present each set of items

And more. Also, there would still be no way at this time to support these use cases:

  • If a "stringy" data type needs some formatting, like numbers need commas, periods, and currency symbols in shops, real estate sites, etc, and MySQL-formatted dates need conversion to something readable.
  • If a number or integer is used for a boolean it would print in the "step 1" example as "1" or blank.

So, I'm still just spit-balling, but a "step 2" could be to:

  1. The post field block is like a paragraph that has some sort of inline placeholder. If the field doesn't exist the block does not display, and text added before or after the placeholder is also excluded (if/then functionality)
  2. Extend the register_meta() function with new args, including an arg hypothetically named bool $access_in_editor => true and callable $presentation_callback => null.
  3. The $access_in_editor arg alone would not do anything and defaults true, but if false would prevent the "step 1" automatic implementation from offering an otherwise eligible post field for inclusion. This is ideal for developers cleaning up the editor and keeping things that be shouldn't be offered out of the options.
  4. If set, the $presentation_callback is a custom callable by the developer that will manipulate the output of the data after it is retrieved from the database/cache but before it is passed to the template.
  5. Further, if $presentation_callback is set and the field is an array or object type but otherwise eligible for inclusion ($access_in_editor = true, $show_in_rest = true, $key doesn't start with underscore), then that field is now be available in the field selector in the Block Editor. Since $presentation_callback will run between db/cache but before it is passed to editor/template for inclusion, a developer can use an object or array to generate template ready strings or strings of html to pass through.
  6. For all times appropriate (pulling from REST for block editor, pulling from db on front-end block editor generated content, etc) run the raw data through the presentation callback. Provide a new core template function like the_post_meta() or the_post_field() that echos the value after the $presentation_callback and/or offer a new arg for get_post_meta() or function get_post_field() that does the above but returns a string instead of echos.

This "Step 2" will give developers of custom meta/fields the power to let WordPress save the data properly (using the sanitize callback) while being able to prepare it for proper formatted display without requiring end user effort. Here are some possibilities:

  • turn a MySQL-formatted time string into a M d, Y string, or other human-friendly date
  • turn a "truthy" field into the text "Accepted" or "Pending", or similar words
  • take a raw number or float and format it in a readable number, ie: 100000.00 becomes $100,000.00 or €100.000,00.
  • number-based formatting like converting a value of 5 and 14 into "5 days" and "2 weeks", etc.
  • handle objects, and create loops for array-based content

Ultimately, this still would not preclude plugin builders from their responsibility to build custom blocks for their plugin's custom post data if they need complicated stuff, but the goal with a post field block shouldn't be to cover every base, just the common ones, especially the ones by novice or non-coders.

@carlomanf
Copy link
Author

What is described in the comment above not only has nothing to do with this issue, but is just a bad idea in general. I would not request nor recommend a block that prints out anything that happens to exist in the postmeta table. This issue never had anything to do with ACF or "metadata" and the discussion is veering too far off-topic so I'm going to close it and open a new one.

@carlomanf
Copy link
Author

New issue opened: #41073

@jeremyescott
Copy link

With respect, in open source communities, once you put something out there, discussion may move away from where you think it should go, and that is the nature of collaboratively developing something like WordPress. I find your behavior in closing and re-opening your issue to come off as against the spirit of what we do here.

nominate a postmeta key to store the content. This would effectively let each post have multiple post content fields

Now let's make sure we're clear, a post field is one of the properties of the WP_Post class object. Note the list of fields in the comment of this documentation file.

So if developers want to add a property to the post that is stored in the database separately, we use post meta. You even acknowledge that your implementation would require post meta.

So my comment was to discuss how much we need post meta support in the Block Editor if we are going to be able to support the thousands of old plugins and themes that rely on post meta to function.

Your suggestion for a custom post field block is very helpful. I searched issues, and yours is the most recent on the topic. I agree your idea was simple in nature, but other commenters as well as myself we quick to point out that there are many layers of complexity when supporting anything in the post meta table.

And to be clear, if my thoughts are considered and begun to be implemented, you will get what you want, in addition to the rest of us getting what we need.

I would request you undo your anti-community, anti-collaborative actions of this morning and re-open this ticket while closing your duplicate that serves the singular purpose of burying comments you disagreed with.

@carlomanf
Copy link
Author

carlomanf commented May 16, 2022

I opened a new issue because this one has been labeled with "New Block" while the other one is about enhancing the existing Post Content block and will need to be labeled accordingly. Your and others' input here have demonstrated that the use of a separate block with the word "field" in its name is confusing and gives the impression that it's designed for something it's not, so I decided it would communicate the purpose more clearly to enhance the existing block. Plus, enhancing the existing block would avoid a lot of common code being duplicated, so it seems like the way to go.

I offer my sympathies that it wasn't the outcome you were aiming for, but asking me to withdraw my request to enhance the Post Content block is out of line. If you wish to continue pursuing your request for a "custom fields" block outside of this particular purpose, please do so somewhere else that does not have my profile attached to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
New Block Suggestion for a new block
6 participants