I’m creating a gutenberg dynamic block. The problem is my I can’t access the attributes value outside of render.php , even in my main plugin random-jokes.php file.
My console is just outputting this
not the concatenated value that I want it to give me in output here is my plugin main file code:
<?php
/**
* Plugin Name: Random Jokes
* Description: Example block scaffolded with Create Block tool.
* Requires at least: 6.1
* Requires PHP: 7.0
* Version: 0.1.0
* Author: The WordPress Contributors
* License: GPL-2.0-or-later
* License URI: https://www.gnu.org/licenses/gpl-2.0.html
* Text Domain: random-jokes
*
* @package create-block
*/
/**
* Registers the block using the metadata loaded from the `block.json` file.
* Behind the scenes, it registers also all assets so they can be enqueued
* through the block editor in the corresponding context.
*
* @see https://developer.wordpress.org/reference/functions/register_block_type/
*/
function create_block_random_jokes_block_init() {
register_block_type( __DIR__ . '/build' );
}
add_action( 'init', 'create_block_random_jokes_block_init' );
//setup
function Joke_block_value(){
global $jokescategory;
$jokes_array = ['url'=>'https://api.chucknorris.io/jokes/random?category=' . $jokescategory];
wp_register_script( 'joke-script', plugin_dir_url( __FILE__ ).'/build/scripts.js', array(), '1.90.0',true);
wp_enqueue_script('joke-script');
wp_localize_script( 'joke-script', 'joke_value',$jokes_array);
}
add_action( 'wp_enqueue_scripts','Joke_block_value');`
Here is my block.json code :
`{
"$schema": "https://schemas.wp.org/trunk/block.json",
"apiVersion": 2,
"name": "create-block/random-jokes",
"version": "0.1.0",
"title": "Random Jokes",
"category": "widgets",
"icon": "smiley",
"description": "Example block scaffolded with Create Block tool.",
"supports": {
"html": false
},
"attributes": {
"joke":{"type":"string"},
"category":{
"type":"string",
"default":"food"
}
},
"textdomain": "random-jokes",
"editorScript": "file:./index.js",
"viewScript":"file:./scripts.js",
"editorStyle": "file:./index.css",
"style": "file:./style-index.css",
"render": "file:./render.php"
}
Here is my render.php code :
<div <?php echo get_block_wrapper_attributes();
global $jokescategory;
$jokescategory = $attributes['category'];
?>>
<p id="joke">
<?php echo $jokescategory?></p>
</div>
here is my scripts.js code :
console.log(joke_value)
I tried rechecking code. but still unable to find why main plugin file doesn’t concatenate the value of $jokescategory in to the console.
$jokes_array = ['url'=>'https://api.chucknorris.io/jokes/random?category=' . $jokescategory];
wp_localize_script( 'joke-script', 'joke_value',$jokes_array);
it’s been 5 hours since I am unable to find the solution please help !
3
Answers
sorry for late response, I updated my render.php and used session to pass php variable from one file to another but the problem is it works only if a user is logged in and has selected a category from the edit page > Random Jokes block.
it doesn't work on random users instead I get an error in my console Here is the updated codes of these files.The Block.json is unchanged. Note : I tried using different hooks but it's still not solving that error
scripts.js
render.php:
random-jokes.php(main-plugin-file):
Thanks
It seems like your function
Joke_block_value()
likely is not needed and obscures the real issue:Joke_block_value()
theglobal $jokescategory;
is initialized asnull
, hencenull
is passed to$jokes_array
.joke-script
recievesnull
as the functionJoke_block_value()
exists outside of the blocks render callback/scope – it would need to be inside render.php to access the default value of your blocks$attributes
.How to resolve the issue:
$attributes['category']
and remove the global variable.PHP
If the above scenario is what you are aiming for, having the block render with PHP may be redundant. The markup can be saved via JavaScript with the
save()
function from the Editor, eg:JSX
Hope this guides you in the right direction…
TLDR; follow S.Walsh’s suggestion and use client-side rendering in JavaScript.
I copied your code exactly (except for the accidental backquotes in the main file and block.json), added an empty
index.js
file for theeditorScript
property in block.json, built the bundles, enabled the plugin, and it worked. The console correctly displayedObject { url: "https://api.chucknorris.io/jokes/random?category=food" }
.In the main file, immediately after
global $jokescategory;
is declared,$jokescategory
had the value food (I printed the variable to a file to test).I did not use wp-scripts to build the bundles, but instead used a custom webpack configuration file. I’m using WordPress (6.2-RC2-55551).
For whatever reason S.Walsh’s explanation did not apply to my case. However, the advice to use client-side rendering in JavaScript follows what is preferred by WordPress. Look for Live rendering in the block editor in the WordPress documentation.
UPDATE
Your latest solution isn’t working because either:
wp_add_inline_script
is not loading (the presence ofjQuery
is assumed and not all WordPress installations use it), orjoke_category_value
constant from being in scope when needed byscripts.js
.Both problems can be solved by manually loading the block.json
viewScript
. Using block.json to automatically enqueuescripts.js
takes control out of your hands and prevents you from enqueuing thejoke_category_value
constant before thescripts.js
file. (As an aside: There has been some discussion about adding properties to block.json to control where block scripts are loaded. However, it doesn’t appear these new properties have been implemented yet.)One solution (updated code is below) is to control the enqueuing sequence manually via the
enqueue_block_assets
action hook.The code below has been tested, and it works except for one problem…
When the client initially requests the WordPress page, no cookie is sent (when session cookies are used), and the plugin has no value stored for
$_SESSION['jokes_category_php']
. Refreshing the window solves the problem because when the client makes a second request, it now has the cookie to send back to the server.Adding session management might unnecessarily complicate your solution. Therefore, I still recommend the client-side solution offered by S.Walsh.
In
block.json
note the use of the script handle for theviewScript
property. This handle was registered with thewp_register_script
function in PHP. Since the script is manually enqueued, the presence ofviewScript
inblock.json
might only be useful as documentation. The block works without it.random-jokes.php(main-plugin-file):
block.json