Phoenix 1.3 Rc0 and Bootstrap 4

Phoenix 1.3 rc0 has just been released and I want to create first versions of new apps for my home-page devekko.io and a political game and push it to a prgmr.com server using HashNukes Ansible.

This is part 1

Setup Elixir


brew install phoenix
brew install elixir

Phoenix 1.3 rc0

From the Elixir Forum the post on Phoenix 1.3 Released rc0 by Chris McCord


mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez

Trumps New Deal

I want to make a political game, Trumps New Deal, at first a super simple voting game. Thumbs up and thumbs down.

This generator is found in the install folder phoenix/installer/lib/mix/tasks/phx.new.ex


mix phx.new trumpsnewdealcom

So, in my Infra folder


➜ Infra mix phx.new trumpsnewdealcom
* creating trumpsnewdealcom/config/config.exs
* creating trumpsnewdealcom/config/dev.exs
* creating trumpsnewdealcom/config/prod.exs
* creating trumpsnewdealcom/config/prod.secret.exs
* creating trumpsnewdealcom/config/test.exs
* creating trumpsnewdealcom/lib/trumpsnewdealcom/application.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/channels/user_socket.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/views/error_helpers.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/views/error_view.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/endpoint.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/router.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/web.ex
* creating trumpsnewdealcom/mix.exs
* creating trumpsnewdealcom/README.md
* creating trumpsnewdealcom/test/support/channel_case.ex
* creating trumpsnewdealcom/test/support/conn_case.ex
* creating trumpsnewdealcom/test/test_helper.exs
* creating trumpsnewdealcom/test/web/views/error_view_test.exs
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/gettext.ex
* creating trumpsnewdealcom/priv/gettext/en/LC_MESSAGES/errors.po
* creating trumpsnewdealcom/priv/gettext/errors.pot
* creating trumpsnewdealcom/lib/trumpsnewdealcom/repo.ex
* creating trumpsnewdealcom/priv/repo/seeds.exs
* creating trumpsnewdealcom/test/support/data_case.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/controllers/page_controller.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/templates/layout/app.html.eex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/templates/page/index.html.eex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/views/layout_view.ex
* creating trumpsnewdealcom/lib/trumpsnewdealcom/web/views/page_view.ex
* creating trumpsnewdealcom/test/web/controllers/page_controller_test.exs
* creating trumpsnewdealcom/test/web/views/layout_view_test.exs
* creating trumpsnewdealcom/test/web/views/page_view_test.exs
* creating trumpsnewdealcom/.gitignore
* creating trumpsnewdealcom/assets/brunch-config.js
* creating trumpsnewdealcom/assets/css/app.css
* creating trumpsnewdealcom/assets/css/phoenix.css
* creating trumpsnewdealcom/assets/js/app.js
* creating trumpsnewdealcom/assets/js/socket.js
* creating trumpsnewdealcom/assets/package.json
* creating trumpsnewdealcom/assets/static/robots.txt
* creating trumpsnewdealcom/assets/static/images/phoenix.png
* creating trumpsnewdealcom/assets/static/favicon.ico

Fetch and install dependencies? [Yn] y
* running mix deps.get
* running mix deps.compile
* running cd assets && npm install && node node_modules/brunch/bin/brunch build

Database

we change directory


➜ Infra cd trumpsnewdealcom
➜ trumpsnewdealcom mix ecto.create
Compiling 12 files (.ex)
Generated trumpsnewdealcom app
The database for Trumpsnewdealcom.Repo has already been created
➜ trumpsnewdealcom iex -S mix phx.server
Erlang/OTP 19 [erts-8.2.2] [source] [64-bit] [smp:4:4] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]

[info] Running Trumpsnewdealcom.Web.Endpoint with Cowboy using http://0.0.0.0:4000
Interactive Elixir (1.4.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> 09:51:00 - info: compiled 6 files into 2 files, copied 3 in 1.0 sec
iex(1)>

Live Reload

By default, Phoenix runs Live Reload and we can make changes to templates, code, styles, scripts, on the fly.

Change Homepage

Now, we change the homepage index template on this on the path

trumpsnewdealcom/lib/trumpsnewdealcom/web/templates/page/index.html.eex

New Style

Strip out the Phoenix default CSS from Bootstrap 3 from trumpsnewdealcom/assets/css/phoenix.css

Now we have a clean slate

Bootswatch 4

Now, I want to strip out Bootstrap 3 and replace with Bootswatch 4 and Bootstrap 4, we will customize from these.

Node Packages

We update package.json which manages our node_modules at trumpsnewdealcom/assets/package.json to include Bootswatch 4 from a branch on Github, its not on npm registry yet.

our /Users/devekko/Infra/trumpsnewdealcom/assets/package.json is now


{
"repository": {},
"license": "MIT",
"scripts": {
"deploy": "brunch build --production",
"watch": "brunch watch --stdin"
},
"dependencies": {
"phoenix": "file:../deps/phoenix",
"bootstrap": "^4.0.0-alpha.6",
"phoenix_html": "file:../deps/phoenix_html",
"bootswatch": "[email protected]:thomaspark/bootswatch.git#v4"
},
"devDependencies": {
"babel-brunch": "6.0.6",
"sass-brunch": "2.10.4",
"brunch": "2.10.7",
"copycat-brunch": "1.1.0",
"clean-css-brunch": "2.10.0",
"css-brunch": "2.10.0",
"uglify-js-brunch": "2.1.1"
}
}

the package.json of Bootswatch 4 confirms this trumpsnewdealcom/assets/node_modules/bootswatch/package.json


{
"_args": [
[
{
"raw": "[email protected]+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"scope": null,
"escapedName": "public",
"name": "public",
"rawSpec": "git+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"spec": "git+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"type": "hosted",
"hosted": {
"type": "github",
"ssh": "[email protected]:thomaspark/bootswatch.git#v4",
"sshUrl": "git+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"httpsUrl": "git+https://github.com/thomaspark/bootswatch.git#v4",
"gitUrl": "git://github.com/thomaspark/bootswatch.git#v4",
"shortcut": "github:thomaspark/bootswatch#v4",
"directUrl": "https://raw.githubusercontent.com/thomaspark/bootswatch/v4/package.json"
}
},
"/Users/devekko/Infra/trumpsnewdealcom/assets"
]
],
"_from": "git+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"_id": "[email protected]",
"_inCache": true,
"_location": "/bootswatch",
"_phantomChildren": {},
"_requested": {
"raw": "[email protected]+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"scope": null,
"escapedName": "public",
"name": "public",
"rawSpec": "git+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"spec": "git+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"type": "hosted",
"hosted": {
"type": "github",
"ssh": "[email protected]:thomaspark/bootswatch.git#v4",
"sshUrl": "git+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"httpsUrl": "git+https://github.com/thomaspark/bootswatch.git#v4",
"gitUrl": "git://github.com/thomaspark/bootswatch.git#v4",
"shortcut": "github:thomaspark/bootswatch#v4",
"directUrl": "https://raw.githubusercontent.com/thomaspark/bootswatch/v4/package.json"
}
},
"_requiredBy": [],
"_resolved": "git+ssh:[email protected][email protected]05",
"_shasum": "cc78a14f230879f4167b7fdca031a469fe02e1f3",
"_shrinkwrap": null,
"_spec": "[email protected]+ssh:[email protected]/thomaspark/bootswatch.git#v4",
"_where": "/Users/devekko/Infra/trumpsnewdealcom/assets",
"author": {
"name": "Thomas Park"
},
"bugs": {
"url": "https://github.com/thomaspark/bootswatch/issues"
},
"dependencies": {},
"description": "Bootswatch is a collection of themes for Bootstrap.",
"devDependencies": {
"autoprefixer": "^6.5.0",
"bower": "~1.2.8",
"grunt": "^1.0.1",
"grunt-contrib-clean": "^1.0.0",
"grunt-contrib-concat": "^1.0.1",
"grunt-contrib-connect": "^1.0.2",
"grunt-contrib-sass": "^1.0.0",
"grunt-contrib-uglify": "^2.0.0",
"grunt-contrib-watch": "^1.0.0",
"grunt-exec": "^1.0.1",
"postcss-cli": "^2.6.0",
"postcss-flexbugs-fixes": "^2.0.0"
},
"engines": {
"node": ">= 0.10.0"
},
"scripts": {
"postcss": "postcss --config assets/js/postcss.js --replace */bootstrap*.css"
},
"version": "4.0.0-alpha.6"
}

Copy Asset Files

app.scss

We now need to connect compile and connect to SCSS

we rename app.css to app.scss


/* This file is for your main application css. */
@import "css/bootswatch/_variables.scss";
@import "bootstrap";
@import "css/bootswatch/_bootswatch.scss";

Brunch config

Thanks to this gist I learned how to configure Brunch for Bootstrap 4 on Phoenix


exports.config = {
// See http://brunch.io/#documentation for docs.
files: {
javascripts: {
joinTo: "js/app.js"

},
stylesheets: {
joinTo: "css/app.css"
},
templates: {
joinTo: "js/app.js"
}
},

conventions: {
assets: /^(static)/
},

// Phoenix paths configuration
paths: {
// Dependencies and current project directories to watch
watched: ["static", "css", "js", "vendor"],
// Where to compile files to
public: "../priv/static"
},

// Configure your plugins
plugins: {
babel: {
// Do not use ES6 compiler in vendor code
ignore: [/vendor/]
},
sass: {
options: {
includePaths: ["node_modules/bootstrap/scss"], // Tell sass-brunch where to look for files to @import
precision: 8 // Minimum precision required by bootstrap-sass
}
},
},

modules: {
autoRequire: {
"js/app.js": ["js/app"]
}
},

npm: {
enabled: true,
globals: { // Bootstrap's JavaScript requires both '$' and 'jQuery' in global scope
$: 'jquery',
jQuery: 'jquery',
bootstrap: 'bootstrap' // Require Bootstrap's JavaScript globally
}
}
};

Bootswatch

I manually copy the Bootswatch folders across from node_modules to the assets folders.

It is possible to use npm postinstall cp -ar type solutions, but this becomes complex as I want to strip out some files like gulp build files and dist etc etc. There is no good way to do this imho and its seems to be confirmed by Cloudless Studio.

I also want to modify the Materia Bootswatch theme and I want to keep it simple. I struggled with this for a day and realized a simple copy and paste was best.

app.scss looks like


/* This file is for your main application css. */
@import "css/bootswatch/_variables.scss";
@import "bootstrap";
@import "css/bootswatch/_bootswatch.scss";

and my css assets folder, Bootstrap is in the node_modules folder and is configured via Brunch and compiled via SASS Brunch


tree css
css
├── app.scss
├── bootswatch
│   ├── LICENSE
│   ├── _bootswatch.scss
│   └── _variables.scss
└── phoenix.css

now our site has Bootstrap 4 / Bootswatch 4 styles

Kitchen Sink

To conclude this part of the project, I add a kitchen-sink page from Bootswatch so I can compare and contrast the fidelity of my build, check for missing JS and CSS etc etc.

I add trumpsnewdealcom/lib/trumpsnewdealcom/web/templates/page/kitchen.html.eex with HTML from Bootswatch

Page Controller updated

I add a new atom :kitchen for our kitchen sink


def kitchen(conn, _params) do
render conn, "kitchen.html"
end

and in the router trumpsnewdealcom/lib/trumpsnewdealcom/web/router.ex

I add a new route


scope "/", Trumpsnewdealcom.Web do
pipe_through :browser

get "/", PageController, :index
get "/kitchen", PageController, :kitchen

end

I copy the tag contents from https://bootswatch.com/4-alpha/materia/ and paste into kitchen.index.eex and we now we have a kitchen sink at http://0.0.0.0:4000/kitchen

Change Brand Primary

And of course, to make myself feel like a talented designer I change brand-primary

GOTCHA: and for some reason, I have to stop and restart phoenix server for the css to refresh, no doubt a setting in brunch. Will try to reproduce this and publish a repo.

stay tuned as I build out the game

ALSO, PLEASE DONT FLAME ME, I didn’t vote for Trump, but I do think there is a roll-back of the FDR New Deal, hence, Trumps New Deal

WordPress Roots.io and Semantic UI Sass

After building a custom theme with Understrap and Material Design for Bootstrap 4 I wanted to quickly, i.e. within a few days, build a WordPress site using the Roots.io framework and Semantic UI.

Semantic UI has a community ownership model i.e. its not Facebook, or Google or Twitter or Microsoft and has ports into NPM, gems, Elm, Ember etc

Assign Domain OpenPlanetCulture.com

The website domain will be Open Planet Culture, openplanetculture.com. The idea for this project is a site about the planet Earth, but without the New Age baggage of Gaia Hypothesis and hopefully more accessible to the science on the subject. I want to try to use language that bridges the left-right culture-wars divide on subjects such as climate change etc. We assign the domain in Dynadot to Cloudflare and set-up DNSSEC.

Development Set-up on Mac Sierra

Install Trellis, the Ansible devops based toolchain. Locally for development it uses Vagrant and remotely on production uses Ansible.

We install Virtualbox, the Virtualbox extensions pack and Vagrant, direct from the vendor.

WordPress building on (a) Trellis

Trellis a dev-prod 12 factor app style toolchain.

We need to install Ansible which first requires PIP on Mac.


sudo easy_install pip
sudo pip install ansible

we also need Vagrant plugins


vagrant plugin install vagrant-bindfs
vagrant plugin install vagrant-hostmanager

we change the to Project directory, make our project folder


cd ~/Projects
mkdir www.openplanetculture.com
cd www.openplanetculture.com/

and now clone from Github and remove the .git folder, we dont need these .git history files

git clone --depth=1 [email protected]:roots/trellis.git && rm -rf trellis/.git

Bedrock a boilerplate base for WordPress site development

We now git clone Bedrock which contains boilerplate and modern development tools such as Facebook’s Nodejs client Yarn.


git clone --depth=1 [email protected]:roots/bedrock.git site && rm -rf site/.git

Next, we use Ansible Galaxy to install our Roots.io ecosystem roles, which are in turned sourced from the Ansible ecosystem of community roles.


cd trellis && ansible-galaxy install -r requirements.yml

install worked fine


cd trellis && ansible-galaxy install -r requirements.yml
- downloading role 'composer', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-composer/archive/1.5.0.tar.gz
- extracting composer to /Users/devekko/Projects/www.openplanetculture.com/trellis/vendor/roles/composer
- composer was installed successfully
- downloading role 'ntp', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-ntp/archive/1.3.0.tar.gz
- extracting ntp to /Users/devekko/Projects/ww.openplanetculture.com/trellis/vendor/roles/ntp
- ntp was installed successfully
- downloading role 'logrotate', owned by nickhammond
- downloading role from https://github.com/nickhammond/ansible-logrotate/archive/e7a498d.tar.gz
- extracting logrotate to /Users/devekko/Projects/www.openplanetculture.com/trellis/vendor/roles/logrotate
- logrotate was installed successfully
- downloading role 'swapfile', owned by kamaln7
- downloading role from https://github.com/kamaln7/ansible-swapfile/archive/0.4.tar.gz
- extracting swapfile to /Users/devekko/Projects/www.openplanetculture.com/trellis/vendor/roles/swapfile
- swapfile was installed successfully
- downloading role 'daemonize', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-daemonize/archive/1.1.1.tar.gz
- extracting geerlingguy.daemonize to /Users/devekko/Projects/www.openplanetculture.com/trellis/vendor/roles/geerlingguy.daemonize
- geerlingguy.daemonize was installed successfully
- downloading role 'mailhog', owned by geerlingguy
- downloading role from https://github.com/geerlingguy/ansible-role-mailhog/archive/2.1.0.tar.gz
- extracting mailhog to /Users/devekko/Projects/www.openplanetculture.com/trellis/vendor/roles/mailhog
- mailhog was installed successfully
- dependency geerlingguy.daemonize is already installed, skipping

WordPress Site development

Now we have our fundament, we have our Roots, our Trellis and our Bedrock, lets build a site.

According to the excellent Roots docs, the “site” is the basic unit of organization and a server can host 1 or more, sites.

This is excellent !

We control the sites using Ansible Group Variables and other settings, so our code is our infrastructure.

Site and Secrets organization

Sounds a bit like a spy novel, but instead we have sites defined in
www.openplanetculture.com/trellis/group_vars/development/wordpress_sites.yml

and the sites secrets in www.openplanetculture.com/trellis/group_vars/development/vault.yml

Personally, I am not convinced Ansible Vault is not a risk, but its widely used and we will go with it for now. Its certainly better than clear text passwords.

Lets generate some passwords using command line pwgen, or alternatively, my preference Password Safe.


brew install pwgen

and set them in our secrets (which I changed after publishing this blog post!)


vault_mysql_root_password: uoquiGh8Sego2hee

vault_wordpress_sites:
openplanetcuture.com:
admin_password: admin
env:
db_password: oonaNgo5eeP4eich

Notice, also that Roots.io preferences openplanetculture.com as canonical, NOT www.openplanetculture.com. This is actually not recommended by Cloudflare, but let’s go with this for now, we “should” be able to just change config and it will work, but for now, lets stay close to defaults so we don’t trip ourselves up.

There are loads of Ansible settings that we can use as we progress.

Complete Local Development Setup

We complete our local dev setup from the detailed official docs.

We check-list ourselves and looks good, so lets run vagrant up, I’ll grab a coffee and expect to do some further trouble-shooting. Vagrant rarely works the first time imho….

Dev site installed

Now I can visit the site on http://openplanetculture.dev

Open Planet Culture DEV site
Open Planet Culture DEV site

Create a new theme with Sage

Sage is the custom starter theme and its used by some interesting sites, including Data.gov.


cd /Users/devekko/Projects/openplanetculture.com/site/web/app/themes

lets install Sage master (9-dev) and we first need Composer installed globally


php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"\nphp -r "if (hash_file('SHA384', 'composer-setup.php') === '55d6ead61b29c7bdee5cccfb50076874187bd9f21f65d8991d46ec5cc90518f447387fb9f76ebae1fbbacf329e583e30') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"\nphp composer-setup.php\nphp -r "unlink('composer-setup.php');"
mv composer.phar /usr/local/bin/composer

now we install using Composer and the interactive prompts

composer create-project roots/sage openplanetculture.com dev-master
Installing roots/sage (dev-master 35edef6ae75280d060f3ef022feaf77b6d1cdb54)
- Installing roots/sage (dev-master master) Cloning master from cache
Created project in openplanetculture.com
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file
Package operations: 14 installs, 0 updates, 0 removals
- Installing composer/installers (v1.2.0) Downloading: 100%
- Installing doctrine/inflector (v1.1.0) Downloading: 100%
- Installing paragonie/random_compat (v2.0.7) Downloading: 100%
- Installing illuminate/contracts (v5.4.13) Downloading: 100%
- Installing illuminate/support (v5.4.13) Downloading: 100%
- Installing illuminate/config (v5.4.13) Downloading: 100%
- Installing psr/log (1.0.2) Downloading: 100%
- Installing symfony/debug (v3.2.4) Downloading: 100%
- Installing symfony/finder (v3.2.4) Downloading: 100%
- Installing illuminate/filesystem (v5.4.13) Downloading: 100%
- Installing illuminate/container (v5.4.13) Downloading: 100%
- Installing illuminate/events (v5.4.13) Downloading: 100%
- Installing illuminate/view (v5.4.13) Downloading: 100%
- Installing squizlabs/php_codesniffer (2.8.0) Downloading: 100%
paragonie/random_compat suggests installing ext-libsodium (Provides a modern crypto API that can be used to generate random bytes.)
illuminate/support suggests installing symfony/process (Required to use the composer class (~3.2).)
illuminate/support suggests installing symfony/var-dumper (Required to use the dd function (~3.2).)
illuminate/filesystem suggests installing league/flysystem (Required to use the Flysystem local and FTP drivers (~1.0).)
illuminate/filesystem suggests installing league/flysystem-aws-s3-v3 (Required to use the Flysystem S3 driver (~1.0).)
illuminate/filesystem suggests installing league/flysystem-rackspace (Required to use the Flysystem Rackspace driver (~1.0).)
Generating autoload files
Do you want to remove the existing VCS (.git, .svn..) history? [Y,n]? Y

Roots\Sage\PostCreateProject::updateHeaders
Define theme headers. Press enter key for default.
Theme Name [Sage Starter Theme]: Open Planet Culture
Theme URI [https://roots.io/sage/]: http://openplanetculture.com
Theme Description [Sage is a WordPress starter theme.]: Open Planet Culture Sage 9-dev theme
Theme Version [9.0.0-beta.2]:
Theme Author [Roots]: Devekko
Theme Author URI [https://roots.io/]: http://blog.devekko.com
Roots\Sage\PostCreateProject::selectFramework
Select a CSS framework (Default: Bootstrap)
[0] Bootstrap
[1] Foundation
[2] None
0
Roots\Sage\PostCreateProject::addFontAwesome
Add Font Awesome? [y,N]? y
Roots\Sage\PostCreateProject::buildOptions
Configure build settings. Press enter key for default.
Path to theme directory (eg. /wp-content/themes/sage) [/app/themes/openplanetculture.com]:
Local development URL of WP site [http://example.dev]: http://openplanetculture.dev

tree tells us we have a nice theme

tree openplanetculture.com / -L 1
openplanetculture.com
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── assets
├── composer.json
├── composer.lock
├── functions.php
├── index.php
├── package.json
├── phpcs.xml
├── screenshot.png
├── src
├── style.css
├── templates
├── vendor
└── yarn.lock

Buy the Book

There is lots more about Sage, and the best way is buy the book and support the project!

Sage 9-dev with yarn npm package manager


cd /Users/devekko/Projects/openplanetculture.com/site/web/app/themes/openplanetculture.com
brew install zsh
brew install yarn

now we use yarn as a replace npm client, no more nom install


openplanetculture.com yarn
yarn install v0.21.3
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
✨ Done in 38.09s.

now we run yarn run start


yarn run start
yarn run v0.21.3
$ webpack --hide-modules --watch --config assets/build/webpack.config.js

Webpack is watching the files…

[BS] [HTML Injector] Running...
[BS] Proxying: http://openplanetculture.dev
[BS] Access URLs:


   Local: http://localhost:3000
External: http://10.1.10.51:3000

      UI: http://localhost:3001

UI External: http://10.1.10.51:3001


[BS] Watching files...

now we have our SASS compiled into CSS and we have the basic setup for theming with Sage 9-dev and Trellis and Roots

YAY !

Adding Semantic UI

I want to try Semantic UI and use yarn


openplanetculture.com yarn add semantic-ui-sass
yarn add v0.21.3
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 📃 Building fresh packages...
success Saved lockfile.
success Saved 1 new dependency.
└─ [email protected]
✨ Done in 8.38s.

next steps will be getting Semantic UI working with Sage

Data.gov as a reference

next few days I will theme and build the Open Planet Culture site, probably referencing Data.gov

WordPress Bootstrap 4 and Material Design with Understrap Child Theme

Brand Primary

I am trying to standardize on Bootstrap 4 and Material Design and am going to test the UnderStrap theme direct from Github and will use the UnderStrap child-theme for our FolkBot WordPress theme.

We create the WordPress site, salts, database, user and gitignore

We change to the themes folder and use ZIP to download the parent and child-theme and the child-theme will have its own name folkbot-understrap.

we add the themes to GIT, create a repo on Gitlab and push the entire site repo.


git add .
git status
git commit -am "Understrap and Folkbot Understrap"
git status
git remote add gitlab_com [email protected]:folkbot/folkbot_wordpress.git
git push gitlab_com master

we activate the theme using WP cli


wp theme activate understrap
Success: Switched to 'UnderStrap' theme.

we check the browser and we see with our biological eyes in our human heads we have an Understrap theme

Folkbot Understrap default
Folkbot Understrap default

we activate the new FolkBot Understrap child theme


wp theme list
+--------------------+----------+--------+---------+
| name | status | update | version |
+--------------------+----------+--------+---------+
| folkbot_understrap | inactive | none | 0.2.2 |
| twentyfifteen | inactive | none | 1.7 |
| twentyseventeen | inactive | none | 1.1 |
| twentysixteen | inactive | none | 1.3 |
| understrap | active | none | 0.5.7 |
+--------------------+----------+--------+---------+

wp theme activate folkbot-understrap/

Success: Switched to 'UnderStrap Child' theme.

Folkbot Understrap
Folkbot Understrap

All pretty standard so far, next we are going to try to bring in the Daemonite Material Design Bootstrap 4 library.

Lets try to put it /var/www/html/wp-content/themes/folkbot_understrap/sass


git clone https://github.com/Daemonite/material.git

We add this to git by deleting the material repo’s own .git git dot folder

Material repo
Material repo

Custom CSS

Understrap wants Nodejs, Bower, Gulp and Browser Sync


sudo apt-get install git-core curl zlib1g-dev build-essential libssl-dev libreadline-dev libyaml-dev libsqlite3-dev sqlite3 libxml2-dev libxslt1-dev libcurl4-openssl-dev python-software-properties libffi-dev nodejs
cd
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
echo 'eval "$(rbenv init -)"' >> ~/.bashrc
exec $SHELL
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
echo 'export PATH="$HOME/.rbenv/plugins/ruby-build/bin:$PATH"' >> ~/.bashrc
exec $SHELL
rbenv install 2.4.0
ruby -v
gem install bundler
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo apt-get install -y build-essential
ruby -v
sudo npm install -g bower
bower --version

We change directory and install via npm install

Gulp Watch

We change the gulpfile.js so it works for our DNS and in our folder we run gulp watch

Now in folkbot-understrap/sass/theme/_child_theme_variables.scss we can change our $brand-primary: #4c4d4a; and gulp watch updates and we get a new theme color

Material Design

Next, we want to integrate Material Design


// Material Design for Bootstrap 4
@import "material/assets/sass/material";

@import "theme/child_theme_variables"; // <--------- Add your variables into this file. Also add variables to overwrite Bootstrap variables here
@import "assets/bootstrap4";// <--------- Loads Bootstrap3 or Bootstrap4. Change from /bootstrap3 to /bootstrap4 Watch out! just for testing in the moment!
@import "../src/sass/understrap/understrap/understrap";// <-------- Loads the UnderStrap defaults. Just a few classes to incorporate BS in WP
@import "../src/sass/understrap/theme/contact-form7";// <-------- Loads some basic styling for contact form 7 plugin

//Optional files - If you don´t use the corresponding scripts/fonts comment em out
@import "assets/font-awesome"; // <------- Font Awesome Icon font
@import "assets/underscores"; // <------- Underscores media styles

// Any additional imported files //
@import "theme/child_theme"; // <--------- Add your styles into this file

to modify Understrap theme settings we need to bring variables across from the theme and place them into
folkbot-understrap/sass/theme/_child_theme_variables.scss


$brand-primary: #fe9ecd;

// Basics of a navbar
$navbar-height: 60px;
$navbar-margin-bottom: 0px;
$navbar-border-radius: 0px;

we can now add the kitchen sink from Bootswatch Bootstrap 4 and we can see Material Design Bootstrap 4

we also change material design folkbot-understrap/sass/material/assets/sass/variables/_colour.scss and other variables


$brand-color: $palette-grey-500 !default;
$brand-color-dark: $palette-grey-700 !default;
$brand-color-light: $palette-grey-100 !default;
$brand-text-color: $white-primary !default;
$brand-text-color-dark: $white-primary !default;
$brand-text-color-light: $black-primary !default;

$brand-color-accent: $palette-green-a200 !default;
$brand-color-accent-dark: $palette-green-a400 !default;
$brand-color-accent-light: $palette-green-a100 !default;
$brand-text-color-accent: $white-primary !default;
$brand-text-color-accent-dark: $white-primary !default;
$brand-text-color-accent-light: $black-primary !default;

Brand Primary
Brand Primary

Obviously, this is just the start

Next, Phoenix, Elm, Angular, Sketch, Android and Swift