skip to Main Content

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 enter image description here

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


  1. Chosen as BEST ANSWER

    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.

    enter image description here

    it doesn't work on random users instead I get an error in my console enter image description here 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

    console.log(joke_category_value)
    let joke_fetch_api = `https://api.chucknorris.io/jokes/random?category=${joke_category_value}`;
    
    let jokes_line = document.getElementById('J_joke_block_line_id')
    let joke_fetch = fetch(joke_fetch_api);
    
    joke_fetch.then((response) => {
        // console.log(response.status)
        return response.json()
    }).then((joke_value) => {
        //   console.log(joke_value['value'])
        jokes_line.innerHTML = joke_value['value']
    
    })
    

    render.php:

    <div <?php echo get_block_wrapper_attributes(); 
    
    $jokes_category_php =  $attributes['category'];
    $_SESSION['jokes_category_php'] = $attributes['category'];
    ?>   class="joke_block_main "style=" background:#EDEDED;color:#333333;padding: 60px;
    position: relative;
    }" class="">
        <div class="category-content">
            <p id="J_joke_block_para_id" class="blockquote">Quote of the Day  </p>
            <p class="text-light otro-blockquote" id="J_joke_block_line_id"><blockquote> - Chuck Norris</blockquote> </p>
        </div>
    </div>
    

    random-jokes.php(main-plugin-file):

      <?php
        session_start();
        /**
         * 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/
         */
        
        // echo $jokes_category_php;
        
        $jokes_category_php_session = $_SESSION['jokes_category_php'];
        function create_block_random_jokes_block_init()
        {
            register_block_type(__DIR__ . '/build');
            global $jokes_category_php_session;
            wp_add_inline_script('jquery', 'const joke_category_value = "' . "$jokes_category_php_session" . '"', 'before');
        }
        
        // echo '<h5>' . $jokes_category_php_session . '</h5>';
        
        function B_scripts()
        {
        }
        
        add_action('init', 'create_block_random_jokes_block_init');
        add_action('init', 'B_scripts');
        
        // wp_add_inline_script('jquery', 'const joke_category_value = "food"', 'after' );
    

    Thanks

      [1]: https://i.stack.imgur.com/OYHXL.png
      [2]: https://i.stack.imgur.com/XBsax.png
    

  2. It seems like your function Joke_block_value() likely is not needed and obscures the real issue:

    • In Joke_block_value() the global $jokescategory; is initialized as null, hence null is passed to $jokes_array.
    • The localized joke-script recieves null as the function Joke_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:

    • In render.php, use the value of $attributes['category'] and remove the global variable.
    • If the joke is retrieved via AJAX, I would set the value of category as a data attribute and use JS to read the value; removing the need for wp_localize_script(), eg:

    PHP

    <p id="joke" data-joke-category="<?php echo $attributes['category']; ?>">...</p>
    

    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

    export default function save({ attributes }) {
        return (
            <p id="joke" data-joke-category={attributes.category}></p>
        );
    }
    

    Hope this guides you in the right direction…

    Login or Signup to reply.
  3. 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 the editorScript property in block.json, built the bundles, enabled the plugin, and it worked. The console correctly displayed Object { 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:

    1. the script from the call to wp_add_inline_script is not loading (the presence of jQuery is assumed and not all WordPress installations use it), or
    2. the loading order of the scripts prevents the joke_category_value constant from being in scope when needed by scripts.js.

    Both problems can be solved by manually loading the block.json viewScript. Using block.json to automatically enqueue scripts.js takes control out of your hands and prevents you from enqueuing the joke_category_value constant before the scripts.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 the viewScript property. This handle was registered with the wp_register_script function in PHP. Since the script is manually enqueued, the presence of viewScript in block.json might only be useful as documentation. The block works without it.

    random-jokes.php(main-plugin-file):

    <?php
        session_start();
        /**
         * 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/
         */
    
        // echo $jokes_category_php;
    
        global $jokes_category_php_session;
        $jokes_category_php_session = $_SESSION['jokes_category_php'];
    
        function create_block_random_jokes_block_init()
        {
            register_block_type(__DIR__ . '/build');
        }
    
        // echo '<h5>' . $jokes_category_php_session . '</h5>';
    
        function B_scripts()
        {
        }
    
        add_action('init', 'create_block_random_jokes_block_init');
        add_action('init', 'B_scripts');
        add_action( 'enqueue_block_assets', 'enqueue_block_scripts' );
    
        // wp_add_inline_script('jquery', 'const joke_category_value = "food"', 'after' );
    
        /**
         * Enqueue block script manually.
         */
        function enqueue_block_scripts() {
            global $jokes_category_php_session;
            $post_id = get_the_ID();
            $post = get_post( $post_id );
    
            // Assets for create-block/random-jokes.
            if ( ! is_admin() && is_object( $post ) && has_block( 'create-block/random-jokes', $post_id ) ) {
                $asset_info = require( plugin_dir_path( __FILE__ ) . 'build/scripts.asset.php' );
                $dependencies = $asset_info['dependencies'];
                $version = $asset_info['version'];
    
                $inline_script = "const joke_category_value = '${jokes_category_php_session}';";
    
                wp_register_script(
                    'create-block-random-jokes-script',
                    plugins_url( 'build/scripts.js', __FILE__ ),
                    $dependencies,
                    $version,
                    true
                );
    
                wp_add_inline_script( 'create-block-random-jokes-script', $inline_script, 'before' );
                wp_enqueue_script( 'create-block-random-jokes-script' );
            }
        }
    

    block.json

    {
        "$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": "create-block-random-jokes-script",
        "editorStyle": "file:./index.css",
        "style": "file:./style-index.css",
        "render": "file:./render.php"
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search