I have a custom post type with a few advanced custom fields. I'm trying to access these custom field values from within a Gutenberg block.
I've added the following to my register_post_type function
'show_in_rest' => true,
'supports' => array( 'title', 'editor', 'custom-fields' ),
I can successfully retrieve the custom posts from within my Gutenberg block using:
select('core').getEntityRecords('postType', 'customType')
but I'm not seeing the custom fields or their values.
Here's my block's JavaScript:
const { __ } = wp.i18n;
const { registerBlockType } = wp.blocks;
const { withSelect } = wp.data;
registerBlockType('cgb/block-press-block', {
title: __('Press Block'),
icon: 'awards',
category: 'common',
keywords: [
__('press-block'),
],
edit: withSelect((select) => {
return {
posts: select('core').getEntityRecords('postType', 'press')
};
})(({posts}) => {
return <p>Content</p>;
}),
});
Is there a way to access the custom post's advanced field values on the editor side or a way to pass that data to the block?
As you're using Advanced Custom Fields already, are you able to rather than registering your own block independently, use acf_register_block instead? That way you can access fields from ACF in PHP based templates.
Here are some useful links about this:
ACF 5.8 – Introducing ACF Blocks for Gutenberg
acf_register_block()
This code is taken from the ACF blog post above and posted here for completeness in case the above link changes.
Register the ACF block:
add_action('acf/init', 'my_acf_init');
function my_acf_init() {
// check function exists
if( function_exists('acf_register_block') ) {
// register a testimonial block
acf_register_block(array(
'name' => 'testimonial',
'title' => __('Testimonial'),
'description' => __('A custom testimonial block.'),
'render_callback' => 'my_acf_block_render_callback',
'category' => 'formatting',
'icon' => 'admin-comments',
'keywords' => array( 'testimonial', 'quote' ),
));
}
}
A callback function to include your block template:
function my_acf_block_render_callback( $block ) {
// convert name ("acf/testimonial") into path friendly slug ("testimonial")
$slug = str_replace('acf/', '', $block['name']);
// include a template part from within the "template-parts/block" folder
if( file_exists( get_theme_file_path("/template-parts/block/content-{$slug}.php") ) ) {
include( get_theme_file_path("/template-parts/block/content-{$slug}.php") );
}
}
The HTML of your block:
<?php
/**
* Block Name: Testimonial
*
* This is the template that displays the testimonial block.
*/
// get image field (array)
$avatar = get_field('avatar');
// create id attribute for specific styling
$id = 'testimonial-' . $block['id'];
// create align class ("alignwide") from block setting ("wide")
$align_class = $block['align'] ? 'align' . $block['align'] : '';
?>
<blockquote id="<?php echo $id; ?>" class="testimonial <?php echo $align_class; ?>">
<p><?php the_field('testimonial'); ?></p>
<cite>
<img src="<?php echo $avatar['url']; ?>" alt="<?php echo $avatar['alt']; ?>" />
<span><?php the_field('author'); ?></span>
</cite>
</blockquote>
<style type="text/css">
#<?php echo $id; ?> {
background: <?php the_field('background_color'); ?>;
color: <?php the_field('text_color'); ?>;
}
</style>
This creates a basic testimonials block as a simple starting point. ACF handles the JavaScript handling within Gutenberg so all you have to do is worry about the PHP side of things.
That means you get to use get_field() and the_field() function like we're (ACF fans) are used to. Mixing ACF and Gutenberg without using this native way may cause headaches and possibly require a plugin to access fields via the WordPress REST API.
Note: ACF support for Gutenberg blocks requires ACF version 5.8 or higher.
Related
Do you have any initial ideas as to why custom sidebars would stop displaying in a Wordpress theme after update 4.4? Our login/join page showed a custom sidebar with the login/join form on the right of the page and other up until the update. This is not a custom sidebar plugin, it's part of the theme. Any thoughts? MANY thanks!
The default sidebar can be enabled, but any custom created sidebars are rendered blank.
Code registering the sidebar within functions.php:
include('includes/sidebar/sidebar.php');
Code within sidebar.php:
include('functions/custom-sidebars.php');
Full code from custom-sidebars.php:
`//// GETS OUR CUSTOM SIDEBARS
$sidebars = get_option('dd_custom_sidebars');
//// IF THEY EXIST
if($sidebars) {
//// LOOPS AND REGISTERS THEM
foreach($sidebars as $sidebar) {
$args = array(
'name' => $sidebar.' — Custom',
'id' => us_get_sidebar_id($sidebar),
'description' => $sidebar.' — Custom Sidebar',
'before_widget' => '<div class="sidebar-item">',
'after_widget' => '</div>',
'before_title' => '<h4>',
'after_title' => '</h4>',
);
//// REGISTERS IT
register_sidebar($args);
}
}
/// FUNCTION TO GENERATE OUR FRIENDLY NAME
function us_get_sidebar_id($phrase) {
$result = strtolower($phrase);
$result = preg_replace("/[^a-z0-9\s-]/", "", $result);
$result = trim(preg_replace("/[\s-]+/", " ", $result));
$result = trim(substr($result, 0, 20));
$result = preg_replace("/\s/", "-", $result);
return $result;
}`
I had the same problem because my code that was creating custom sidebars was wrong in my sidebar.php file.
I was using this …
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('Block 3') ) : ?>
Instead of this
<?php if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar('block-3') ) : ?>
which is the id of the sidebar from my functions.php file
As a usable workaround (but not an answer to why the custom sidebar code is not working) I'm now dumping all the various widgets into the default sidebar which works and using the plugin Display Widgets to determine which page the widgets are shown on.
I'm using both the "Types" and the "Advanced Custom Fields" plugins for Wordpress. With "Types" I have created a custom post and when you click "add new" you create a new post by filling out the text areas and drop-downs that I created using "Advanced Custom Fields".
Currently, when I click on my post in the sidebar there is a filter to sort my subposts (sorry for the horrendous lack of proper terminology; I'm new to wordpress) by date added. I also want to be able to sort by some of the custom fields I have created in the dropdown box.
Also, there are two columns labelled "title" and "date". Is it possible to add a couple more?
Writing PHP
You can write some PHP as outlined by the developer of Advanced Custom Fields (Elliot Condon) in this blog post.
The following code taken from the post will display an image and a true / false field in the admin screen:
function my_page_columns($columns)
{
$columns = array(
'cb' => '<input type="checkbox" />',
'thumbnail' => 'Thumbnail',
'title' => 'Title',
'featured' => 'Featured',
'author' => 'Author',
'date' => 'Date',
);
return $columns;
}
function my_custom_columns($column)
{
global $post;
if($column == 'thumbnail')
{
echo wp_get_attachment_image( get_field('page_image', $post->ID), array(200,200) );
}
elseif($column == 'featured')
{
if(get_field('featured'))
{
echo 'Yes';
}
else
{
echo 'No';
}
}
}
add_action("manage_pages_custom_column", "my_custom_columns");
add_filter("manage_edit-page_columns", "my_page_columns");
To be able to sort the true / false column you can use the following code as outlined in the post:
function my_column_register_sortable( $columns )
{
$columns['featured'] = 'featured';
return $columns;
}
add_filter("manage_edit-page_sortable_columns", "my_column_register_sortable" );
Using a Plugin
Alternatively, without any PHP programming, you can do this using the Admin Columns by Codepress plugin.
I'm having trouble figuring out how to display a template that lives inside of my custom module.
This is what I have:
<?php
function brl_footer_theme($existing, $type, $theme, $path) {
$theme = array();
$theme['brl_footer'] = array(
'render element' => 'content',
'template' => 'brl-footer',
'path' => drupal_get_path('module', 'brl_footer'),
);
return $theme;
}
/**
* Implements hook_block_info().
*/
function brl_footer_block_info() {
$blocks = array();
$blocks['brl_footer'] = array(
'info' => t('Custom Footer'),
);
return $blocks;
}
I have a template file in the module called brl-footer.tpl.php
It contains very basic HTML:
<h1>here's some content</h1>
Is it possible to display my template through the custom block 'brl_footer' that's being created?
The custom block is active and has been assigned to the proper region.
Any help on this would be hugely appreciated -
You'll need to implement hook_block_view to define what gets displayed in your block.
Also, if your template is just static content, you don't need to specify a "render element" or "variables" for your theme hook (though you could still make variables in a preprocess function).
I'm trying to figure out a way for members on my Wordpress (Buddypress) site to pick their "favorite movies, books, etc."
It would be nice if, instead of members simply typing a list of these things, they could select from books already in the system, and add more as the please in the future.
I'm hoping that there is an easy answer to this, such as a plugin that I can use, or, at least, modify. Does anyone know of anything that I can look into?
Your title asks how to add a user profile field. Here is the code to add as many fields as you like. Once you add the field, you can easily place additional inputs or options on the custom tab page for users to enter their own favorites.
function my_test_setup_nav() {
global $bp;
$parent_slug = ‘test’;
$child_slug = ‘test_sub’;
//name, slug, screen, position, default subnav
bp_core_new_nav_item( array(‘name’ => __( ‘Test’ ),’slug’ => $parent_slug,’screen_function’ => ‘my_profile_page_function_to_show_screen’,'position’ => 40,’default_subnav_slug’ => $child_slug ) );
/* Add the subnav items to the profile */
// name, slug, parent_url, parent slug, screen function
bp_core_new_subnav_item( array( ‘name’ => __( ‘Home’ ), ‘slug’ => $child_slug, ‘parent_url’ => $bp->loggedin_user->domain . $parent_slug.’/', ‘parent_slug’ => $parent_slug, ‘screen_function’ => ‘my_profile_page_function_to_show_screen’ ) );
bp_core_new_subnav_item( array( ‘name’ => __( ‘Random Page’ ), ‘slug’ => ‘random’, ‘parent_url’ => $bp->loggedin_user->domain . $parent_slug.’/', ‘parent_slug’ => $parent_slug, ‘screen_function’ => ‘my_profile_page_function_to_show_screen234′ ) );
}
function my_profile_page_function_to_show_screen() {
//add title and content here – last is to call the members plugin.php template
add_action( ‘bp_template_title’, ‘my_profile_page_function_to_show_screen_title’ );
add_action( ‘bp_template_content’, ‘my_profile_page_function_to_show_screen_content’ );
bp_core_load_template( apply_filters( ‘bp_core_template_plugin’, ‘members/single/plugins’ ) );
}
function my_profile_page_function_to_show_screen_title() {
echo ‘wptaskforce title’;
}
function my_profile_page_function_to_show_screen_content() {
echo ‘wptaskforce content’;
}
//random page content:
function my_profile_page_function_to_show_screen234() {
//add content here – last is to call the members plugin.php template
add_action( ‘bp_template_content’, ‘my_profile_page_function_to_show_screen234_content’ );
bp_core_load_template( apply_filters( ‘bp_core_template_plugin’, ‘members/single/plugins’ ) );
}
function my_profile_page_function_to_show_screen234_content() {
echo ‘This is a random page.’;
}
add_action( ‘bp_setup_nav’, ‘my_test_setup_nav’ );
i am using this code to create a new page when my plugin is activated:
function create_policy() {
$my_post = array(
'post_title' => 'mobile page',
'post_content' => 'this is my content',
'comment_status' => 'closed',
'post_type' => 'page',
'post_status' => 'publish',
'post_author' => 1,
'post_category' => array( 3,4 )
);
wp_insert_post( $my_post );
}
register_activation_hook( __FILE__, 'create_policy' );
what i want to do is :
1) use my own code in the 'post_content', not regular text.
2) clear all the page and leave only the GET_header
i want a blank page with my code.
any advice ?
in addition to the comments:
this is the admin pannel code:
<?php
// create custom plugin settings menu
add_action('admin_menu', 'zeev_create_menu');
function zeev_create_menu() {
//create new top-level menu
add_menu_page('zeev movile redirect', 'zeev mobile', 'administrator', __FILE__, 'zeev_settings_page', 'favicon.ico');
//call register settings function
add_action( 'admin_init', 'register_mysettings' );
}
function register_mysettings() {
//register our settings
register_setting( 'zeev-settings-group', 'zeev_tracking_code' );
}
function zeev_settings_page() {
?>
<div class="wrap">
<form method="post" action="options.php">
<?php settings_fields('zeev-settings-group'); ?>
<table class="form-table">
<tr valign="top">
<td><textarea name="zeev_tracking_code" cols="90"><?php echo get_option('zeev_tracking_code'); ?></textarea></td>
</tr>
</table>
<p class="submit">
<input type="submit" class="button-primary" value="<?php _e('Save Changes') ?>" />
</p>
</form>
</div>
<?php }
and this is the veriable what need to find himself on a blank page someware (and to work)
<?php echo get_option('zeev_tracking_code'); ?>
There are a few ways to get custom layouts in Wordpress on a page-by-page basis, but the most common is to create a new, custom template. In the theme folder, create a new file named what you like:
my-custom-template.php
The easiest way to start is to copy what you find in page.php into that directory. That will give you the structure with the headers and footers which are useful. Right at the top of the file, put:
<?php
/*
*
* Template Name: [My template]
*
*/
?>
Doing this will tell WP to automatically make this template an option when creating a new page. Now, when you create a page, you can select this template from the dropdown, and the page will use that. Inside the template itself, you can put whatever PHP or HTML code you need inbetween the get_header() and get_footer() you like, to style it, or just to show your two buttons.
If you want a totally blank page, you can remove the get_header() and get_footer() altogether.