Include image assets in a WordPress Gutenberg Block Plugin - wordpress

I am creating a custom WordPress Gutenberg block and I want to use image assets (PNGs, JPGs) from my plugin folder, to be shown in both the Gutenberg editor and on the rendered page.
I am using Webpack to bundle my files for JS and SCSS. I tried adding the webpack image loader, which saves images into an 'assets' folder in my main plugin directory.
However, when I try to use my image assets from my Block's main JS file, I cannot find a way to access the full URL path of my images as running on my WordPress server, currently running in a docker container on localhost.
My hope was to find a WordPress method to return the path of my plugin directory, and use that to point to the image assets regardless of how they are bundled, but I have not been able to find a solution in the documentation.
It's possible to get the plugin directory using PHP using WordPress' built-in function:
function _get_plugin_directory() {
return __DIR__;
}
This seems like it could help, however I do not know if it's possible to pass the returned plugin path into my JS file.
My plugin structure looks like this:
/assets // generated by Webpack
- image.png
- main.js
/blocks
/block-example
- image.png // <-- My image asset
- index.js // <-- I want to use image.png here
- index.js // loads in my block
blocks.php
The index.js file is where I want to show the image, using the standard WordPress edit and save functions:
import image from './image.png';
edit: props => {
...
<img src={image} />
}
In the WordPress Gutenberg editor, images point to just the image file name (./image.png or assets/image.png etc), instead of the full path of the image where it sits inside the plugin directory (ie localhost:8080/plugins/my-blocks/assets/image.png) which results in the image not being found.

I'm still looking into whether there's an official Gutenberg way to do this, but for now I've got this working in my plugin with wp_localize_script.
This works to pass data from PHP into enqueued Javascript so that data usually only accessible in PHP is accessible in Javascript as well.
So (likely inside blocks.php from your example), you would have something like:
wp_enqueue_script(
'my-main-script',
plugins_url( 'assets/main.js', __FILE__ ),
array( 'wp-blocks', 'wp-i18n', 'wp-element', 'wp-editor', 'wp-components' ),
'20190804',
true
);
You can then enqueue any values you want to pass into your JS:
wp_localize_script(
'my-main-script',
'js_data',
array(
'my_image_url' => plugins_url( 'blocks/block-example/image.png', __FILE__ )
)
);
This will ensure that the image path is accessible to javascript. Then from within your block itself, you can reference it:
<img src={js_data.my_image_url} />
You should now see your static image asset rendered within your block.

Popping this in here for anyone that land here:
You can directly import images into react apps using webpack.
So assuming you're using some kind of webpack configuration (#wordpress/scripts, create-guten-block, or your own custom setup), you would simply import your image into the block file like so, assuming your image is in the same folder as the file you're importing into:
import image1 from "./image1.jpg"
And then use it like a URL wherever you need:
<img src={image1} alt="my image" />

You can also acheive the same thing using the newer wp_add_inline_script function.
From the WordPress docs
Though localization is the primary use, it (wp_localize_script) was often used to pass generic data from PHP to JavaScript, because it was originally the only official way to do that. wp_add_inline_script() was introduced in WordPress Version 4.5, and is now the best practice for that use case. wp_localize_script() should only be used when you actually want to localize strings.
Here's the code I used to pass an image url into a custom Gutenberg block using wp_add_inline_script. The below code was placed inside blocks.php as per the example.
In wp_enqueue_script code sample, _get_plugin_url() is my own custom function to retrieve the path for my plugin.
wp_enqueue_script(
'my-main-script',
_get_plugin_url() . $block_path,
[],
filemtime( _get_plugin_directory() . $block_path )
);
I set up an array for the data I wished to pass in, eg
$js_data = array(
'image_url' => _get_plugin_url() . '/assets/images/BACK.png',
);
Then used the wp_add_inline_script function
wp_add_inline_script(
'my-main-script',
'var jsData = ' . wp_json_encode( $js_data ),
'before'
);
Inside the /block-example/index.js file which registers the block and defines its behaviour, I can access that variable like:
jsData.image_url

Related

How to create a template if site is using Divi?

I am doing some work on a site and everything is made in Divi.
I just want to build out a few custom woocommerce templates for product page etc.. using code but when I add the templates to the theme folder it doesn't override the product page.
When I look in debug query it shows the et page builder template is being used instead of regular product template.
Their docs are all geared up for non-coders and only code related stuff is on making modules.
How do I just make a normal template override from a child theme?
You just have to make sure your path to the template files is correct. For instance, if you're trying to overwrite the single-product template, which is located at:
wp-content/plugins/woocommerce/templates/single-product.php
just copy it to:
wp-content/themes/{your-child-theme}/woocommerce/single-product.php
and make your changes there.
For any template files, just match the path minus the templates folder.
If you have any caching plugins installed, you may need to clear your cache before the changes show up.
To test it, I copied single-product.php and product-image.php and made the following changes.
And you can see the result here:
If that doesn't work for you, make sure your child theme is set up correctly.
Edit: Divi's Theme Builder, once activated, causes the site to no longer use page templates. So there is no way (short of rewriting the Theme Builder) to override it with your own template files.
However, you can customize the Divi modules that are used by the Theme Builder, although editing them is a bit more complicated.
The modules are found in:
wp-content/themes/Divi/includes/builder/module/
For example, I'll override the WooCommerce Title module.
wp-content/themes/Divi/includes/builder/module/woocommerce/Title.php
First, copy that file into your child theme and place it in a new folder:
wp-content/themes/Divi-child/custom-modules/Title.php
Next, add the following code your child theme's functions.php to replace the existing module:
function divi_child_theme_setup() {
if ( class_exists('ET_Builder_Module')) {
get_template_part( 'custom-modules/custom-title' );
$TE_ct = new Custom_ET_Builder_Module_Woocommerce_Title();
remove_shortcode( 'et_pb_wc_title' );
add_shortcode( 'et_pb_wc_title', array($TE_ct, '_shortcode_callback') );
}
}
add_action('wp', 'divi_child_theme_setup', 9999);
Call your variable ($TE_ct) and the module (Custom_ET_Builder_Module_Woocommerce_Title) whatever you want.
Finally, edit the module in your child theme. Make sure the class name matches what you used in functions.php.
...
class Custom_ET_Builder_Module_Woocommerce_Title extends ET_Builder_Module {
/**
* Initialize.
*/
public function init() {
echo "<h1>CUSTOMIZED!!</h1>";
$this->name = esc_html__( 'Woo Title', 'et_builder' );
$this->plural = esc_html__( 'Woo Titles', 'et_builder' );
$this->slug = 'et_pb_wc_title';
$this->vb_support = 'on';
...
Here, I've added a simple echo to show that the module is being overridden.
Result:

Apply CSS file from activated WordPress Plugin

I am new to wordpress and want to know best way to add css from installed and activated plugin.
I have one activated plugin called "social-media" and in that plugin i have created one css file called "social-login-style.css"
I want to include this css file and apply style to my content. How should I add css file in any page so that I can see the effects.
In Short, I want to add social-login-style.css on wp-login.php file.
Whether it is theme or plugin, css or js, any custom addition, wp_enqueue_scripts is the only acton you need for all.
https://codex.wordpress.org/Plugin_API/Action_Reference/wp_enqueue_scripts
function additional_custom_styles() {
/* Enqueue The Styles */
wp_enqueue_style( 'custom-login-style', plugins_url( 'social-login-style.css', __FILE__ ) );
}
add_action( 'wp_enqueue_scripts', 'additional_custom_styles' );
If you it to be added only on login screen then use the following condition,
if ( $GLOBALS['pagenow'] === 'wp-login.php' ) {
// We're on the login page!
}
Hope this one help :)
UPDATE
Please check login_enqueue_scripts. it is designed to add custom scripts into login page only. Works well without any login condition.
https://codex.wordpress.org/Plugin_API/Action_Reference/login_enqueue_scripts
Without saying what you want to achieve is impossible, it certainly is against how WordPress is designed to work. Plugins are supposed to be modules that add to or modify how WordPress works. The folder of a plugin should only hold files pertaining to what the plugin does and, if it's a public plugin, its contents are controlled by a versioning (SVN) system.
In short, adding a file to an existing plugin will not have any effect, regardless of whether the plugin is active or not. And you should not add files to plugins you haven't developed yourself.
To load a CSS file on the login page, one should add an action hook to login_enqueue_scripts, as instructed in Customizing Login Form page of the codex. The stylesheet itself should be placed in either a custom plugin (you could create for your use-case) or inside the current theme folder.

Generate dynamic css with option page (ACF)

I'm currently working on an option page (ACF Pro v5) for wordpress that dynamically generates a css file. When I'm testing this locally it works fine; only on a live server the dynamic css couldn't generate by wordpress.
Am I missing something? Is there something white the rights that wordpress can't write the file. I've a clean custom-style.css placed in the right folder with chmod 777.
This is the code I've written in my functions.php:
function generate_options_css() {
$ss_dir = get_stylesheet_directory();
ob_start(); // Capture all output into buffer
require($ss_dir . '/styles.php'); // Grab the custom-style.php file
$css = ob_get_clean(); // Store output in a variable, then flush the buffer
file_put_contents($ss_dir . '/Library/css/custom-styles.css', $css, LOCK_EX); // Save it as a css file
} add_action( 'acf/save_post', 'generate_options_css' ); //Parse the output and write the CSS file on post save
wp_enqueue_style( 'custom-styles', get_template_directory_uri() . '/Library/css/custom-styles.css' );
May be your live server is running with a child theme and your local setup has no child theme. This is why your local version is working and the live is not working. The most probable reason is that you are using both funtions get_template_directory_uri() and get_stylesheet_directory(); and both will point to the same '/Library/css/custom-styles.css' file only if your current active theme is not a child theme.
So, it is wiser to use any one based on your demand and not both together :)

Load CSS and JS files only to a specific module Drupal

I’m developing a custom module, but need that only in the page where I use this module add some CSS and JavaScript files, I know how to do this from template.php using a condition to specific node, but I need do it more generic, that the condition can stay in .module file, or some similar solution.
I have a little code in my .module file:
function mymodule_init() {
$url = request_uri();
$path = drupal_get_path('module', 'module_name');
if ($url == 'xxxx') {
drupal_add_js($path . '/js/animations.js');
}
}
This work very well, but I’m limiting, because I need know the URL where the module will used.
Rather than checking for the URL, you should add your drupal_add_js when you initialize the code your module will be using on a given page.
For example, if you are adding a block, you could add it to hook_block_view. If you're adding a theme template, you could do it in hook_preprocess for that theme template.

WordPress Plugin Localization

I've just built my first plugin for WordPress, and even if it's not a great "code poetry" it works as it should. It's a plugin that transform the default wp gallery using the GalleryView 3.0 jQuery plugin (http://spaceforaname.com/galleryview).
The only thing I'm not able to do is localization.
Localization for this plugin in means translating the admin interface, where someone can configure the jQuery plugin options to change the aspect of the resulting gallery.
I've tried to follow the millions of tutorials present on the web, read a lot of posts about this issue on forums and followed the guidelinees of codex... but still with no luck.
this is what I've done:
every text line is inside a gettext function ( __ and _e )
using poedit I created the .po and .mo file scanning the plugin directory (everything went ok), then i added translations on that file.
I named the .po file like that NAME-OF-THE-PLUGIN-it_IT.po (the .mo file was generated with the same name)
I've put the translations files inside the plugin folder/languages (name of the folder is the same of the plugin and of the translations files)
then I've tried to add the load_plugin_textdomain function inside the main plugin file. I've tried because there's no way to get it working.
The only thing on which I'm not sure is the fact that the plugin I've created is not under a class+constructor functions... just because I'm still not so good in coding.
But I've put the load_plugin_textdomain inside an init add_action, like this:
add_action('init', 'gw_load_translation_file');
function gw_load_translation_file() {
// relative path to WP_PLUGIN_DIR where the translation files will sit:
$plugin_path = dirname(plugin_basename( __FILE__ ) .'/languages' );
load_plugin_textdomain( 'gallery-view-for-wordpress', false, $plugin_path );
}
the lines above are not inside a logic, they are just in the main plugin file, like that.
this is an example of my use of gettext functions:
<h3><?php _e('Panel Options','gallery-view-for-wordpress') ?></h3>
What did I not understand?
My mistake was on language files path declaration.
this fixed:
$plugin_path = dirname( plugin_basename( __FILE__ ) ) . '/languages/';
this was wrong:
$plugin_path = dirname(plugin_basename( __FILE__ ) .'/languages' );
I was answered on Wordpress Stack Exchange
Contrary to my previous statement, I've succeeded using this filename: gallery-view-for-wp-it_IT.mo
Strange, though - themes use just it_IT.mo.

Resources