Closed bobbingwide closed 1 year ago
Oh nuts, the string "field_" may not be used at the start of a field name.
That's OK though - I can use the hyphen as originally planned: field-name
Looks like there's already a Meta Field Block plugin! https://wordpress.org/plugins/display-a-meta-field-as-block
I was having difficulty getting ACF to display a new field added to the Testimonials group.
I believe this was because the plugin is calling acf_add_local_field_group()
which must be overriding the definition I'd updated using the ACF Field groups. I'll have to look at the documentation for this API.
I'll have to look at the documentation for this API.
I've looked at the documentation and raised an request on ACF Slack #help channel. Had a reply but I'm none the wiser really. I can't yet see why my definition is allowed to override the user defined fields.
I can see a use for local fields when it comes to ACF blocks. Once the fields for a block have been defined they can be registered in response to acf/include_fields
and the Field Group can be manually removed from the admin.
BTW. In s.b/wordpress I've now created the acf-json
folder in the current theme ( Fizzie ).
See https://www.advancedcustomfields.com/resources/local-json/
In s.b/wordpress and s.b/cwiccer, having added the field group for Testimonials to the acf-json
folder in the Fizzie theme, in both environments there are two almost identical meta boxes for Testimonials.
<div id="acf-group_6461f5c4cde96" class="postbox acf-postbox">
, which is the field group registered from the Local JSON. <div id="acf-group_645a613de20b1" class="postbox acf-postbox">
, which is the field group registered by the plugin. if ( acf_is_local_field_group('group_645a613de20b1')) {
return;
}
One note of interest is that the placeholder for an empty field is the same in both meta boxes.
Had a reply but I'm none the wiser really.
I've made some more progress. Rather than doing manual database queries, I've used acf_get_raw_field_groups()
which will use the local JSON solution if configured, or access the acf-field-group
posts to return an array of field groups.
This can be done in response to either acf/include_fields
or acf/init
.
When the local JSON files aren't in use then the query performed is
[6] => Array
[0] => (string) "
SELECT wp_posts.*
FROM wp_posts
WHERE 1=1 AND wp_posts.post_type = 'acf-field-group' AND ((wp_posts.post_status = 'publish' OR wp_posts.post_status = 'acf-disabled'))
ORDER BY wp_posts.menu_order ASC, wp_posts.post_title ASC
"
[1] => (double) 0.00053000450134277
[2] => (string) "require_once('wp-admin/admin.php'), require_once('wp-load.php'), require_once('wp-config.php'), require_once('wp-settings.php'), do_action('init'), WP_Hook->do_action, WP_Hook->apply_filters, ACF->init, do_action('acf/include_fields'), WP_Hook->do_action, WP_Hook->apply_filters, oik_testimonials_acf_include_fields, oik_maybe_register_testimonials, acf_get_raw_field_groups, acf_get_raw_internal_post_type_posts, ACF_Internal_Post_Type->get_raw_posts, get_posts, WP_Query->query, WP_Query->get_posts"
[3] => (double) 1684169380.2613
[4] => Array
If the $raw_field_groups
array returned includes a group called Testimonials
then we don't try to register it using acf_add_local_field_group()
.
[0] => Array
[location] => Array
[0] => Array
[0] => Array
[param] => (string) "post_type"
[operator] => (string) "=="
[value] => (string) "oik_testimonials"
[position] => (string) "normal"
[style] => (string) "default"
[label_placement] => (string) "top"
[instruction_placement] => (string) "label"
[hide_on_screen] => (string) ""
[description] => (string) ""
[show_in_rest] => (integer) 1
[ID] => (integer) 3972
[title] => (string) "Testimonials"
[key] => (string) "group_6461f5c4cde96"
[menu_order] => (integer) 0
[active] => (boolean) 1
This solution enables the user to define the fields to be associated to the oik_testimonials
CPT and display whichever fields are needed using the generic ACF field block #7
I can't yet see why my definition is allowed to override the user defined fields.
I haven't dug any deeper into this problem. Basically, when the field was empty then the default value being displayed was the same even if the user defined default was different from the hardcoded version.
The prototype logic in dddc26e should be reworked:
oik_maybe_register_testimonials()
to oik_maybe_add_local_field_group()
acf_add_local_field_group()
within the function when the field group's not already registered.location
as well as the title
. Duplicating the ACF Field block and changing the Field name attribute leaves unwanted data values
Original block with field-name
set to author-image
<!-- wp:oik-testimonials/acf-field {"name":"oik-testimonials/acf-field",
"data":{"field-name":"author_image","_field-name":"field_645f589a88304"},
"mode":"preview"} /-->
After duplicating and changing the field name to author-image-id
the _field-name
attribute was unchanged.
In the block editor the original image was still being displayed.
<!-- wp:oik-testimonials/acf-field {"name":"oik-testimonials/acf-field",
"data":{"field-name":"author_image_id","_field-name":"field_645f589a88304"},
"mode":"preview"} /-->
After changing the field name to _oik_testimonial_name
it became
<!-- wp:oik-testimonials/acf-field {"name":"oik-testimonials/acf-field",
"data":{"field_645f589a88304":"_oik_testimonial_name"},
"mode":"preview"} /-->
Then, later on, the value disappeared
<!-- wp:oik-testimonials/acf-field {"name":"oik-testimonials/acf-field",
"data":{"field_645f589a88304":""},
"mode":"preview"} /-->
Front end rendering of fields of type image
needs to take into account the Return format of the image:
For some reason the image is already displayed in the block. Not sure why.
I've refactored again.
acf_get_possible_field_names()
lists the possible field names when a field can't be found acf_get_field_groups()
to list all the field groups, then acf_get_fields()
to get the fields for the group.name
.acf/include_fields
the acf-field-name
field is dynamically built to be a select
field with choices
set to the array of possible field names.includes\acf-field-names.php
In edit mode the block currently looks like this.
Now I have to eliminate fields which are only registered for blocks. In this example they're the first 6 in the drop down.
I changed the select list to only display the internal field name & key when SCRIPT_DEBUG is true and I improved the select list to eliminate fields which are only registered for blocks.
The logic includes fields for which the param
value is post_type
.
But the Field group name after the field name can be misleading... the Block Count field is associated with post type Plugin.
It would be better to list one or more post types for which the field is applicable. eg.
This is the ACF Field block in edit mode with SCRIPT_DEBUG true
I haven't converted the post_type to the post type name. Nor have a catered for Not equals to
I have now.
In this example I added a Location Rule of Post Type is not equal to Posts
acf/prepare_field/name=acf-field-name
choices
field to the array returned from acf_get_possible_field_names()
acf_get_possible_field_names()
to check the rule['operator']
, prepending the post type name with '!' when the operator is '!='get_post_type_object()
acf_process_field_group()
function is called in response to acf/filter_includes
some of the CPTs may not be registered, so get_post_type_object()
can return null.The logic to display a WYSIWYG field is to display the content ASIS. No esc_html()
.
The logic to display an oEmbed field is similar.
But there's are a couple of problems:
wpautop()
.style
attribute for the iframe
which hides the embedded content. [value] => (string) "<blockquote class="wp-embedded-content" data-secret="KnIp5reDKa">
<a href="https://herbmiller.me/about/">About</a></blockquote>
<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"
style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"
title="“About” — herb miller"
src="https://herbmiller.me/about/embed/#?secret=fUKEQ6mMbA#?secret=KnIp5reDKa" data-secret="KnIp5reDKa" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no">
</iframe>"
The style
attribute is added in wp_filter_oembed_result
, in wp-includes/embed.php by the following code.
This was part of work to oEmbed: Add extra hardening around allowed HTML for improved sandboxing.
if ( ! empty( $content[1] ) ) {
// We have a blockquote to fall back on. Hide the iframe by default.
$html = str_replace( '<iframe', '<iframe style="position: absolute; clip: rect(1px, 1px, 1px, 1px);"', $html );
$html = str_replace( '<blockquote', '<blockquote class="wp-embedded-content"', $html );
}
Note: The oembed works in the editor - I can see the iframe.
I suspect it's a JavaScript problem with wp-embed.js
not being enqueued.
Now adding support for gallery
but not sure exactly what HTML to generate.
Q: Should it be like the WordPress core/gallery
block?
When I added support for the link
type field I needed to implement similar logic to that of the Meta Field Block plugin. This required the post_id
parameter to be passed to the implementing function.
For improved extensibility I should do the following:
post_id
parameter to each acf_display_field_type()
functionFor ACF extensions see https://www.awesomeacf.com/
The acf-field block's enclosing div should include the usuals suspects for a WordPress block in the class
attribute.
Q: Does get_block_wrapper_attributes()
automatically add the anchor ID?
A: No, apparently not, though the documentation does suggest this is done automatically by this function.
See https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/
The block.json
file should be updated to include several of the more useful supports
attributes.
Now that the acf-field-block plugin has been developed it's time to disable the generic field block logic in oik-testimonials.
I need to do this soon since I've twice encountered problems where the logic in oik-testimonials overrides the logic in acf-field-block.
tab
field types from being listed in the select list of field names.Both of these were due to oik-testimonials trumping the output of acf-field-blocks.
Although part of the reason for the second problem was how I was hooking into the actions and filters.
I'd naively assumed that since that since the acf/include_fields
hook is called within init
then I could call load_text_domain()
within my own action hook for init
.
But this didn't take into account that ACF hooks into init
with a lower priority ( 5 ) than the default ( 10 ).
Therefore, ACF invokes acf/include_fields
before other plugins have had a chance to respond to init
.
One solution is to hook into init
with a lower priority, another is to call load_plugin_text_domain()
in the action hook response to acf/include_fields
. I chose the second solution.
Closing in favour of #8
The Author name block developed for #6 is a rather trivial block. Suppose I wanted to add an
_author_image
field to display next to the author name. I'd have to develop a new block similar to the first one. It wouldn't take much effort to copy and cobble the first block, but it would become laborious if I had to do this for lots of fields.Wouldn't it be better to create a generic
acf-field
block that could display the value / values of any field registered to ACF?Requirement
acf-field
blockProposed solution
oik-testimonials/acf-field
field-name
field where the user can enter the field name to be displayed.Note: I've not use
the_field()
for anything other than a text field so this is an opportunity for me to try each of the field types. Starting with an image.