Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

VueJS SPA for WP admin menu page not working

The VueJS project was generated by vue-cli using Webpack template. When I built for production, I get one static folder that has 2 folders and 1 index.html file. The 2 folders are css and js. There's only one css file. But there are 3 javascript files. An app.xxxxxxx.js, manifest.xxxxxxxx.js, and vendor.xxxxxxx.js.

I've wrapped the production VueJS project in a Node server and an Apache server. For the Node server, I used ExpressJS:

...
app.use('/public', express.static(__dirname + '/public'));
app.use('/static', express.static(__dirname + '/public/static'));
app.use('/js', express.static(__dirname + '/public/static/js'));
app.use('/css', express.static(__dirname + '/public/static/css'));
app.get('/', function(req, res) {
  res.sendFile(path.join(__dirname + '/public/index.html'));
});
...

The SPA works for Node.

For the Apache server, I just transferred all the HTML markup from the generated index.html to an index.php and make sure that the CSS and JS directories are read.

I'm trying to kinda do the same with WordPress. But no luck.

What I've done with WP so far is that I've loaded all the JS and CSS files using wp_enqueue_script() and wp_enqueue_style(), respectively. But I can't get the html markup to work in conjunction with the CSS and JS files. Maybe this is the problem. What am I missing?

This is what the index.html would look like after being generated from production:

<!DOCTYPE html>
<html>
<head>
  <meta charset=utf-8>
  <title>wan_admin3</title>

   <link rel=stylesheet href=https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css>

<link href=/static/css/app.49437cdf2228a91c12a30d39ae35bb58.css rel=stylesheet>
</head>

<body>

<div id=app></div>
<script type=text/javascript src=/static/js/manifest.989a96caedc89ff03309.js</script>
<script type=text/javascript src=/static/js/vendor.86018170deacaae1d066.js</script>
<script type=text/javascript src=/static/js/app.6103fd8f82bcb5c38544.js</script>
</body>
</html>

What I've done in WP functions.php

add_action( 'admin_menu', 'register_my_menu_item' );
function register_my_menu_item() {
   $my_plugins_page = add_menu_page(
     'General Page',
     'General Page',
     'manage_options',
     'mt-top-level-handle',
     'my_plugins_page_callback'
   );
   $subadmin_page = add_submenu_page(
     'mt-top-level-handle',
     'submenu-admin',
     'Sub Level Menu',
     'manage_options',
     'submenu_admin_page',
     'admin_sub_page_callback'
   );
  add_action( 'load-' . $subadmin_page, 'do_enqueue' );
}
function do_enqueue() {
  wp_enqueue_style(
    'subadmin_css_sheet',
    get_theme_file_uri( 'some-admin/subadmin/css/app.49437cdf2228a91c12a30d39ae35bb58.css'),
    array(),
    '1.0.0'
  );
  wp_enqueue_script(
    'subadmin_app_script',
    get_theme_file_uri('some-admin/subadmin/js/app.6103fd8f82bcb5c38544.js'),
    array(),
    '1.0.0',
    true
  );
  wp_enqueue_script(
    'subadmin_manifest_script',
    get_theme_file_uri( 'some-admin/subadmin/js/manifest.989a96caedc89ff03309.js'),
    array(),
    '1.0.0',
    true
  );
  wp_enqueue_script(
    'subadmin_vendor_script',
    get_theme_file_uri( 'some-admin/subadmin/js/vendor.86018170deacaae1d066.js'),
    array(),
    '1.0.0',
    true
  );
}
function my_plugins_page_callback() {
?>
   <div>Hello</div>
<?php
}
function admin_sub_page_callback() {
?>
  <div id="app">Subadmin</div>
<?php
}

The top level menu item and the sub menu are showing just how they should be. But when I click the Sub Level Menu, it only shows Subadmin text and not the VueJS SPA that works in other environments.

Subadmin text showing instead of the VueJS SPA

For sure, the JS and CSS files are loading because when you right click the the webpage and see the source code, then click the links to the JS and CSS files, the codes show up.

The CSS file link tag Screenshot

The JS file script tags Screenshot

The CSS and JS file structure inside the twentyseventeen:

The CSS and JS file structure inside the twentyseventeen

For the HTML end inside the admin_sub_page_callback(), I just took the <div id="app"></div> from the original index.html that was generated from VueJS project.

like image 807
junerockwell Avatar asked Jul 07 '17 22:07

junerockwell


1 Answers

I've gotten similar Vue.js widgets to work with WP, but only using browserify, instead of webpack.

I didn't use the browserify template of vue-cli, although it could work with that. Instead I used my own package.json. Here's the gist: https://gist.github.com/maurop123/eb0c8e884fefe3e40c110b33beff48db

That will make a single file dist/bundle.js for the whole vue app. I then dropped that file into wherever the static js files are for my wp theme.

Next, I added a wp_enqueue_script line in functions.php like this...

wp_enqueue_script( MD_THEME_NAME.'-bundle', MD_THEME_URI.'/assets/js/bundle.js', array('jquery'), NULL, true );

The particular pattern of arguments may depend on your theme. You should try to make your wp_enqueue_script look like existing one.

Finally, I added the html element needed ,like <div id="vueApp"></div> for example, anywhere in the currently rendered template.

Hope that helps!

like image 61
MauroPerez Avatar answered Oct 13 '22 10:10

MauroPerez