I'm trying to figure out how to pass attributes into a react based plugin in Wordpress(using @wordpress/scripts).
my main.php file:
<?php
defined( 'ABSPATH' ) or die( 'Direct script access disallowed.' );
define( 'ERW_WIDGET_PATH', plugin_dir_path( __FILE__ ) . '/widget' );
define( 'ERW_ASSET_MANIFEST', ERW_WIDGET_PATH . '/build/asset-manifest.json' );
define( 'ERW_INCLUDES', plugin_dir_path( __FILE__ ) . '/includes' );
add_shortcode( 'my_app', 'my_app' );
/**
* Registers a shortcode that simply displays a placeholder for our React App.
*/
function my_app( $atts = array(), $content = null , $tag = 'my_app' ){
ob_start();
?>
<div id="app">Loading...</div>
<?php wp_enqueue_script( 'my-app', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-element' ), time(), true ); ?>
<?php
return ob_get_clean();
}
So if I want to load the app with this shortcode [my_app form="login"], how do I pass this attribute to wp_enqueue_script() ? and how can I display a content according to this attribute in react side? I'm trying to display a register form if the attribute is 'register'
my react main file:
import axios from 'axios';
const { Component, render } = wp.element;
class WP_App extends Component {
constructor(props) {
super(props);
this.state = { username: '', password: '' };
this.handleUsernameChange = this.handleUsernameChange.bind(this);
this.handlePasswordChange = this.handlePasswordChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
render() {
return (
<div class="login">
<form onSubmit={this.handleSubmit} class="justify-content-center">
<div class="form-group">
<label htmlFor="username">
Username
</label>
<input
class="form-control"
id="username"
onChange={this.handleUsernameChange}
value={this.state.username}
type="email"
/>
</div>
<div class="form-group">
<label htmlFor="password">
Password
</label>
<input
class="form-control"
id="password"
onChange={this.handlePasswordChange}
value={this.state.password}
type="password"
/>
</div>
<button class="btn btn-primary">
Submit
</button>
</form>
</div>
);
}
handleUsernameChange(e) {
this.setState({ username: e.target.value });
}
handlePasswordChange(e) {
this.setState({ password: e.target.value });
}
handleSubmit(e) {
e.preventDefault();
if (!this.state.username.length) {
return;
}
if (!this.state.password.length) {
return;
}
const creds = { username: this.state.username,
password: this.state.password };
axios.post('https://example.com:8443/login', creds)
.then(response => {
console.log("SUCCESSS")
window.open('https://example.com/login?t=' + response.data.token, "_blank")
}
)
.catch(error => {
if (error.response && error.response.data){
if (error.response.data === "USER_DISABLED"){
console.log("User account disabled."
)
}
if (error.response.data === "ACCOUNT_LOCKED"){
console.log("User account is locked probably due to too many failed login attempts."
)
}
else{
console.log("Login failed."
)
}
}
else{
console.log("Login failed."
)
}
console.log(error.response)
});
}
}
render(
<WP_App />,
document.getElementById('app')
);
To register a shortcode, you have to use the add_shortcode function. The function has two parameters. The first is a unique shortcode tag that represents the name of the shortcode. The second is the name of the handler function (or callback, as it is better known) that is executed after the shortcode is registered.
Q. Can you use React with WordPress? Yes, React can be used with WordPress, as in the example above, where the content on the front-end built with React is managed by WordPress CMS using the WP Rest API.
Echo the shortcode. By itself, WordPress do_shortcode just returns a value. If you want to actually display the output of the shortcode, you need to echo the do_shortcode function. If you notice in the WordPress do_shortcode example above, we make sure to always echo the do_shortcode function to display the value.
Wordpress way to load custom data for script is using wp_localize_script
function.
You could rewrite your shortcode function by the way
add_shortcode( 'my_app', 'my_app' );
/**
* Registers a shortcode that simply displays a placeholder for our React App.
*/
function my_app( $atts = array(), $content = null , $tag = 'my_app' ){
add_action( 'wp_enqueue_scripts', function() use ($atts) {
wp_enqueue_script( 'my-app', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-element' ), time(), true );
wp_localize_script(
'my-app',
'myAppWpData',
$atts
);
});
return '<div id="app">Loading...</div>';
}
Then you could use shortcode settings object via JavaScript by the way:
window.myAppWpData['form'] // if you set form as shortcode param
Then you could set this options as props param for your react WP_App component.
And then you could render your WP_APP content conditionally to its shortcode param:
Main render:
render(
<WP_App shortcodeSettings={window.myAppWpData} />,
document.getElementById('app')
);
and how can I display a content according to this attribute in react side?
You could use conditional logic according to shortcode atts values. More details about conditional React logic you could find on official documenction page
https://reactjs.org/docs/conditional-rendering.html
WP_APP render:
you could use props.shortcodeSettings
inside WP_APP render()
function to build any logic your want to display your component.
render() {
return (
// you could use props.shortcodeSettings to build any logic
// ...your code
)
}
If you want to have multiple shortcodes on the page.
You could consider to add uniqid( 'my-app' )
to script handle name
function my_app( $atts = array(), $content = null, $tag = 'my_app' ) {
$id = uniqid( 'my-app' );
add_action( 'wp_enqueue_scripts', function () use ( $atts, $id ) {
wp_enqueue_script( "my-app", plugins_url( 'build/index.js', __FILE__ ), array( 'wp-element' ), time(), true );
wp_localize_script(
"my-app",
"myAppWpData-$id",
$atts
);
} );
return sprintf( '<div id="app-%1" data-my-app="%1">Loading...</div>', $id );
}
For this way - you could implement for your index.js
file logic for multiple apps,
const shortcodesApps = document.querySelectorAll('[data-my-app]');
shortcodesApps.forEach((node) => {
const nodeID = node.getAttribute('data-my-app');
const shortcodeSettings = window[`myAppWpData-${nodeID}`];
render(
<WP_App shortcodeSettings={shortcodeSettings} />,
node
);
})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With