• I got a file that includes some CSS but its extension is .php because I need to write PHP inside it, let’s called this file styling.php. I enqueue styling.php in the main PHP file called main.php inside the plugin folder with the hook wp_enqueue_scripts.

    Inside the styling.php, I need to use the $wpdb but the file is outside the WordPress scope because it’s already enqueued to the frontend, therefore the $wpdb won’t work (undefined).

    The only way I could think of is to manually include the wp-config.php inside the styling.php, but I have read many articles that say this is a bad practice for calling WordPress instead of WordPress calling the plugin like here: https://wordpress.stackexchange.com/questions/159347/best-way-to-include-wp-config-php

    But I couldn’t think of a better way, is there any better solution?

    For reference, here is the code for main.php:

    add_action( 'wp_enqueue_scripts', 'styling_1' );
    
    function styling_1() {
       wp_register_style( 'product_css', plugins_url( 'Testing/Styling/styling.php' ) );
       wp_enqueue_style( 'product_css' );
    }

    Here is the code for styling.php:

    <?php
    $table_name = $wpdb->prefix . 'newdata';
    $results = $wpdb->get_var($wpdb->prepare("SELECT name FROM $table_name WHERE id = 1"));
    
    header("Content-type: text/css; charset: UTF-8");
    ?>
    
    .single_button {
       background-color: <?php echo $results; ?>;
    }
Viewing 15 replies - 1 through 15 (of 15 total)
  • Include wp-load.php and you have the whole WordPress-Core available for your custom style-file.

    Dion

    (@diondesigns)

    Loading a PHP script to output a single line of CSS is a bad idea. Loading WordPress in that script would mean you’re doubling the server load because you would be executing WordPress twice on every frontend page.

    Please try something like this instead:

    add_action( 'wp_head', 'styling_1' );
    
    function styling_1() {
    	global $wpdb;
    	$table_name = "{$wpdb->prefix}newdata";
    	$results = $wpdb->get_var("SELECT name FROM $table_name WHERE id = 1");
    	echo "<style>.single_button {background-color: $results;}</style>\n";
    }

    I removed $wpdb->prepare() because there is nothing in your query that needs escaping. The \n is to “prettify” the output; it can be removed.

    Thread Starter ace0930

    (@ace0930)

    @threadi This is working but I’m not sure it’s great for performance and considered a good practice.

    Thread Starter ace0930

    (@ace0930)

    @diondesigns The CSS is so long that I can’t write them all here, the reason I’m only writing one of them here is to give a general idea of what I’m doing and why I need $wpdb.

    A more perfomanent idea would be:
    You are obviously reading something from a database table. You could therefore generate the CSS file every time something changes in the content of the table. An event for this could be found if you describe what kind of table it is and how its contents are generated. You write the CSS file with always the same file name into the file system and include it like you did it with the PHP file.
    This way the load for generating the CSS file lies with the change to the database table and not with the user who loads the page.

    Dion

    (@diondesigns)

    If this is for your own personal site, then you already know the database credentials. So add them to your PHP script and use mysqli functions to access the values in the database. Just make sure to close the DB connection at the end of your script.

    Please be aware that you’ll need some sort of cache control header…otherwise the PHP script would run on every page load, which is a bad idea.

    Thread Starter ace0930

    (@ace0930)

    @threadi I actually made one form and users can field the form to update the information, I store this information in the database. I then use the value of the column to style on the frontend.

    For example, the first input of the form is main color, when the user field with blue, it is then saved to the database, I then pull this value to style the site.

    Its’ MySQL btw.

    Then create the CSS file exactly when the user updates this data. Will surely be an input form in the WordPress backend? Seems to be already an individual solution that you can also customize in this regard.

    Thread Starter ace0930

    (@ace0930)

    @diondesigns But is there any similar way to get the specific data like get_var? I’m developing a plugin and I think I cannot know the database credential of the user who installs it. Any example is much appreciated to accomplish what I’m doing as I’ve shown.

    Thread Starter ace0930

    (@ace0930)

    @threadi Yes, the form is in the backend and not frontend. Can you elaborate more or maybe give some reference on how to generate the CSS file every time something changes in the content of the table? I haven’t heard of this and therefore have no idea how to actually do this.

    This is actually quite simple. You just have to write the CSS code via file_put_contents() to a location inside your plugin or theme from where you then load them.

    Simple example:
    file_put_contents('path/to/style.css', '.selector { background-color: #'.$variable.'; }');

    https://www.php.net/manual/de/function.file-put-contents.php

    … and that’s more or less where you write the value into the database anyway.

    Dion

    (@diondesigns)

    If this will be a plugin for other users, then saving the CSS file as @threadi mentions is the best way to proceed. However, you’ll need a “cachebuster” value to append to the URL of the CSS file; otherwise, you could update the file but users will not load it until the version in their browser cache expires. The easiest way to generate a “cachebuster” value is to create one every time you update your CSS values:

    update_option('my_cachebuster', time());

    You can then append the cachebuster value like this:

    $url = '(URL for stored CSS file)';
    $cachebuster = get_option('my_cachebuster');
    $url .= "?v=$cachebuster";

    In this way, users will reload the CSS file every time it changes.

    You don’t need to set up an extra option for something like this. This can also be done when including the file by using its modification time. Example:

    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() .'/style.css', array(), filemtime(get_stylesheet_directory() .'/style.css'), 'all' );

    Dion

    (@diondesigns)

    Using filemtime() is how I used to create cachebusters, but it has some drawbacks. The most serious is that filemtime() counts against any IOPS limitations imposed by the host (mostly an issue with shared hosting). Since autoload options are cached, there is no system overhead when retrieving them from a plugin. I also prefer to manually append the cachebuster to the URL, but if one wants to specify it separately, this would work:

    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() .'/style.css', array(), get_option('my_cachebuster'), 'all' );
    
    Thread Starter ace0930

    (@ace0930)

    @diondesigns @threadi Working like a charm, thank you so much!

    @diondesigns If I put it into one line like:
    update_option( 'my_cachebuster', date( 's-d-m-Y', time() ) );

    wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() .'/style.css', array(), get_option('my_cachebuster'), 'all' );

    I’m not sure this will impact the performance because the version number is changing every second when I inspect the page source. How do I only update the file when the file is updated like the input value is successfully saved into the file by file_put_contents?

    Something like this?

    update_option('my_cachebuster', time());
    
    if( isset( $_POST['color'] ) ) {
       file_put_contents(
          plugin_dir_path( __FILE__ ) . 'css/styling.css',
          'body { background-color: ' . $_POST["color"] . '; }'
       );
    
       get_option('my_cachebuster');
    }
    
Viewing 15 replies - 1 through 15 (of 15 total)
  • The topic ‘File is outside WordPress Scope after enqueue’ is closed to new replies.