I think most of the web development World today knows what is Vue.js. For me it is a wonderful tool which makes life easier. It is just a super simple and elegant solution which can be very helpful in many cases.
I am not a huge fan of WordPress, but sometimes I have to deal with it and to fix some broken site or add some new stuff to some old one. But so far I have built about 15 web sites on top of WP.
On the latest project I was working on some custom functionality for picking up product options and calculating the price. I was reading around and tried to find perfect solution for this situation. And I have tried a bunch of all kind a custom form plugins and systems. Non of them was what I needed. So I decided to check out how hard it would be to use Vue.js inside of WordPress page. Well usually SEO is very important for blogs and JavaScript stuff is usually not very SEO friendly. But hey – this is dynamic form so no matter what You will use You will lose some SEO benefits.
Let’s begin
So we need a plan and this is what I came with:
- make some simple Vue.js component
- make it work on WordPress
- make the component smarter
- make it work on WordPress
- repeat 3-5…
There are many ways to use Vue. But in this case we would want to keep it simple stupid as it says in KISS principles. That means no build step should be required – make just some js file of few of them, load it in wp and done. And it is not a problem to do in Vue. But only js files are not enough – we need some connecting point on a web site. Luckily an HTML is used for that and we have access to it everywhere on the system.
Show me the code!
First we should include some js file from CDN or our own location and then write something like this:
And that is basically it for the plan #1 position.
#2 Let’s make it work in WordPress
I am sure that there are may ways to make this happen. Bu hey – I have never wrote a plugin in my life so lets do it now. I went to the YouTube and found some videos about hot it all works. And this is what I came up with:
- create a folder
- inside of it create a PHP file with the same name as a folder
- put some comments inside of that file
- make some registration hooks to work and install & activate that plugin
I must admit, that when You get used to some very well and nicely documented things Your brain starts to think that every stuff should have that kind a documentation. Unfortunately that is not the case. So this is why I was using YouTube to find out how to do it – I have no time to read information which is not so well organized… But maybe it’s just my own problem – You can write me a comment about how do You learned how to make a plugin.
So the file looks like this:
<?php
/**
* Plugin Name: WPProposal
* Plugin URI: http://www.monas.lt
* Description: This will make dynamic proposal form for Your WP site.
* Version: 1.0.0
* Author: monas_
* Author URI: http://www.monas.lt/
* Network: false
* Copyright 2019 monas_
* License: GPL-3.0
* License URI: http://www.gnu.org/licenses/gpl.txt
*/
// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( !class_exists( 'wpProposal' ) ) {
class wpProposal
{
public $plugin;
function __construct() {
$this->plugin = plugin_basename( __FILE__ );
}
function register() {
add_action( 'wp_enqueue_scripts', array( $this, 'register_scripts' ) );
}
function register_scripts(){
wp_register_style( 'cta_stylesheet', plugins_url( '/assets/mystyle.css', __FILE__ ) );
wp_enqueue_style( 'cta_stylesheet' );
wp_register_script( 'vuemin', plugins_url( '/assets/vue.min.js', __FILE__ ), [], null, true );
wp_enqueue_script( 'vuemin' );
wp_register_script( 'appmin', plugins_url( '/assets/myscript.min.js', __FILE__ ), [], null, true );
wp_enqueue_script( 'appmin' );
}
function activate() {
require_once plugin_dir_path( __FILE__ ) . 'inc/wp-proposal-activate.php';
wpProposalActivate::activate();
}
}
$wpProposal = new wpProposal();
$wpProposal->register();
// activation
register_activation_hook( __FILE__, array( $wpProposal, 'activate' ) );
// deactivation
require_once plugin_dir_path( __FILE__ ) . 'inc/wp-proposal-deactivate.php';
register_deactivation_hook( __FILE__, array( 'wpProposalDeactivate', 'deactivate' ) );
}
And in this file I refer two more files in inc folder for activation and deactivation logic, but basically those can be put in the same file also.
//inc/wp-deactivate.php
<?php
/**
* @package wpProposal
*/
class wpProposalDeactivate
{
public static function deactivate() {
flush_rewrite_rules();
}
}
//inc/wp-activate.php
<?php
/**
* @package wpProposal
*/
class wpProposalActivate
{
public static function activate() {
flush_rewrite_rules();
}
}
That is all it takes to complete #2 of our plan. We will be using some js and css files which lives in assets and now contains only that basics what is required.
Let’s make it little bit more useful
My goal was to make a dynamic form. How we can make and use that? I am working with Vue.js for more than two years now and I know that it’s very easy to do. The biggest challenge for me was to get into right thinking. All UI is data driven and that data can be passed around in one-way or two-way manier. That means to make some moving parts is a lot easier then doing the same stuff in vanilla js or jQuery. So Vue is the perfect match here.
When You use Vue all You get is a web component which may have some more web components inside and all that is mounted on top of some html div in Your website. The mounting point will be as simple as
<div id="app"></div>
Then we have our dynamic form Vue web component named wp-proposal and we will be using it like this:
<div id="app">
<wp-proposal></wp-proposal>
</div>
And then to make it more real life just add some more „moving parts”:
<div id="app">
<wp-proposal :items="{params:{}, items:[]}">
[form7 ....]
</wp-proposal>
</div>
This can be understood as:
app-home-container
component properties…
component-default-slot-content
/component
/app-home-container
What is default slot content? Well it is really nice feature introduced in HTML 5. To put it short it could be understood as a box which lives inside of Your bigger box, where box – is just a web component. I think this is one of the most important stuff out there and it opens insane amount of flexibility. It’s too big topic to talk about here, so read more about it here and on official Vue docs.
Inside of our slot I have put regular form short code which You would normally use in any place of Your site. But here it has one more role to play – it will help send out our dynamically rendered and filled form. I am using basic stuff here so the form is also very simple and it has only one additional field which will work as a connecting point of Vue form.
[hidden product-info]
Inside of our Vue component we can do some vanila js document.querySelector stuff and set some information to this hidden field every time something is changed by user. And then when user will submit the form he will post that hidden value also. Isn’t that simple? And this works perfectly!
Demo time
Here is my simple form, go ahead and send me something.
Thanks for reading!