So I'm trying to do a headless CMS, specifically wordpress. I want all of the admin functionality for free for the backend and don't care what it looks like, but I want a proper modern front end, single page application, built with Angular, where to start...
Big thanks to Alvaro Franz, wpangular.com seems like a cracking place to start...
So on my ubuntu machine, which happens to have node, npm amd wordpress installed and working, I do the following:
cd /var/www/html/wp-content/themes
git clone https://github.com/alvarofranz/wpangular.git
cd wpangular
cp src/index.php .
cp src/functions.php .
cp src/style.css .
npm install
ng build --prod --deploy-url="/wp-content/themes/wpangular/dist/app/" --aot=false --buildOptimizer=false
You can now activate the theme, through the regular wordpress UI, and it displays, hoorah! It gets a bunch of errors, boo hoo...
The first thing I needed to do was edit, src/app/shared/constants-global.ts to remove the http://127.0.0.1, to get rid of the CORS errors (wordpress on localhost, app communicating on 127.0.0.1 browser thinks it's dealing with cross origins requests, so I edit as follows...
WP_ROOT_URL: '/', // No trailing slash
WP_API_BASE: '/wp-json' // No trailing slash
No dice... So I edit src/app/home/home.component.html and add a hello world...
<section class="hero">
<p>Hello World</p>
No dice...
Doh, I need to build, but fxck me, that ng build takes an eternity to run. Proper angular development uses "ng serve", not "ng build", I just edit the files, a watcher sees the file change, recompiles and hot swaps the code, as quick as I can "Alt Tab" from my IDE to my browser and hit refresh and there it is, if every single change requires a 60 seconds or more to build, my development time will go through the roof...
cd /var/www/html/wp-content/themes
ng serve
I can access the application @ http://localhost:4200/ but it is being server by node, not my trusty wordpress apache server... So what do I do, after some head scratching I remembered the good old days of TomCat development, we always put an apache instance in front of the Tomcat Server, served the static content from there and proxied requests from Apache to Tomcat when necessary, wonder if that would work...
First thing I need to do then is to enable MOD_PROXY on my apache server.
sudo a2enmod
will list available proxies, seems to match files in /etc/apache2/mods-available
sudo a2enmod proxy
will enable the proxy module, seems to be equivalent to copying proxy.conf and proxy.load from /etc/apache2.mods-available to /etc/apache2/mods-enabled
sudo a2enmod proxy_http
That is my apache proxy enabled, now to configure it...
Add the following to your /etc/apache2/apache2.conf (am sure it would be best practice to put it in some other file that gets included, but hey, I'm in a hurry!)
# Proxy to Node for development resources
ProxyPass /wp-content/themes/wpangular/dist/app/ http://localhost:4200/wp-content/themes/wpangular/dist/app/
ProxyPassReverse /wp-content/themes/wpangular/dist/app/ http://localhost:4200/wp-content/themes/wpangular/dist/app/
Now restart apache for that to take affect
sudo /etc/init.d/apache2 restart
Start serving wpangular theme from node:
cd /var/www/html/wp-content/themes/wpangular
ng serve --deploy-url="/wp-content/themes/wpangular/dist/app/" --base-href="/wp-content/themes/wpangular/dist/app/"
So now http://localhost:4200/ returns an error, "cannot get /", good, the app is now being served by node JS @ http://localhost:4200/wp-content/themes/wpangular/dist/app/ and that kinda works... few errors as it cannot reach wordpress, but of course it cannot reach wordpress.
Now does my proxy work?
http://localhost:4200/wp-content/themes/wpangular/dist/app/runtime.js
Returns a javascript file. Now verify that your proxy is working as expected by going to ...
http://localhost/wp-content/themes/wpangular/dist/app/runtime.js
And it returns the same Javascript file, superb! Now, if I try to access http://localhost/ I get weird errors, so I'm gonna need to fix the index.php file, which is currently expecting content to be served from the dist directory. I edit /var/www/html/wp-content/themes/wpangular/index.php as follows:
<!-- ?php require get_template_directory()."/dist/app/index.html"; ? -->
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Gregs copy of WP Angular</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap" rel="stylesheet">
</head>
<body>
<app-root></app-root>
<script src="<?php echo get_template_directory_uri()?>/dist/app/runtime.js" type="module"></script>
<script src="<?php echo get_template_directory_uri()?>/dist/app/polyfills.js" type="module"></script>
<script src="<?php echo get_template_directory_uri()?>/dist/app/styles.js" type="module"></script>
<script src="<?php echo get_template_directory_uri()?>/dist/app/vendor.js" type="module"></script>
<script src="<?php echo get_template_directory_uri()?>/dist/app/main.js" type="module"></script>
</body>
</html>
And at this point, you can serve the application from here: http://localhost/
Ok, we still get a few errors, but have now gotta a working development environment of sorts. When I build this for use on a production server, I am going to need to do:
ng build --prod --deploy-url="/wp-content/themes/wpangular/dist/app/" --base-href="/wp-content/themes/wpangular/dist/app/" --output-hashing none
That will mean the Javascript files generated will not change names constantly, and I should be able to continue using the index.php above, and not depending on incorporating the entire index.html generated from Angular. It also give me a bunch more control, as I now have the opportunity to insert post content into the HTML returned, so that I could avoid server side rendering requirements if I want search engines to see my content. Still awaiting to see if I will be forced to turn off AOT and buildoptimizer as Alvaro does above, but I gotta working development environment anyway. Big thanks to Alvaro for sharing his work, hopefully this minor contribution might be useful to someone!