diff --git a/configure-all-the-things/2018-07-24-drupal-bristol/images/1.png b/configure-all-the-things/2018-07-24-drupal-bristol/images/1.png deleted file mode 100644 index a8a2ebf..0000000 Binary files a/configure-all-the-things/2018-07-24-drupal-bristol/images/1.png and /dev/null differ diff --git a/configure-all-the-things/2018-07-24-drupal-bristol/slides.md b/configure-all-the-things/2018-07-24-drupal-bristol/slides.md deleted file mode 100644 index 384b3dc..0000000 --- a/configure-all-the-things/2018-07-24-drupal-bristol/slides.md +++ /dev/null @@ -1,55 +0,0 @@ -theme: poster, 8 -autoscale: true -build-lists: true -header-emphasis: #53B0EB -header: alignment(center) -text: alignment(left) -text-emphasis: #53B0EB -code: Monaco, line-height(1.2) - -[.hide-footer] -[.header: alignment(center)] - -# Configure all the things!! - ---- - -[.header: alignment(center)] - -# Drupal 8 -### _Configuration management_ - ---- - -[.background-color: #FFFFFF] -[.build-lists: false] -[.header: #111111] -[.text: #111111, alignment(left)] - - - -- Web Developer & System Administrator -- Senior Developer at Microserve -- Part-time freelancer -- Acquia certified Drupal 8 Grand Master -- Drupal 7 & 8 core contributor -- @opdavies -- www.oliverdavies.uk - -^ Work at Microserve. -Maintain Drupal modules, PHP CLI tools and libraries -Blog on my website - ---- - -## What is configuration? - ---- - - - -[.header: alignment(center)] - -# Thanks! -### _@opdavies_ -### _oliverdavies.uk_ diff --git a/deploying-drupal-fabric/images/fry.jpeg b/deploying-drupal-fabric/images/fry.jpeg deleted file mode 100644 index 1e9fe70..0000000 Binary files a/deploying-drupal-fabric/images/fry.jpeg and /dev/null differ diff --git a/deploying-drupal-fabric/images/grumpy.jpg b/deploying-drupal-fabric/images/grumpy.jpg deleted file mode 100644 index f44fa63..0000000 Binary files a/deploying-drupal-fabric/images/grumpy.jpg and /dev/null differ diff --git a/deploying-drupal-fabric/slides.md b/deploying-drupal-fabric/slides.md deleted file mode 100644 index ce23273..0000000 --- a/deploying-drupal-fabric/slides.md +++ /dev/null @@ -1,907 +0,0 @@ -autoscale: true -build-lists: true -theme: next, 9 - -# [fit] Deploying Drupal <br>with Fabric -### Oliver Davies -### bit.ly/deploying-drupal-fabric - ---- - -[.build-lists: false] - -- What is Fabric and what do I use it for? -- How to write and organise Fabric scripts -- Task examples - ---- - -[.build-lists: false] - - - -- Senior Developer at Microserve -- Part-time freelance Developer & System Administrator -- Drupal Bristol, PHPSW, DrupalCamp Bristol organiser -- Sticker collector, herder of elePHPants -- @opdavies -- oliverdavies.uk - - -^ Drupal, Symfony, Silex, Laravel, Sculpin -Not a Python Developer - ---- - - - -## [fit] What is <br>Fabric? - ---- - -## What is Fabric? - -Fabric is a Python (2.5-2.7) library and command-line tool for streamlining the use of SSH for application deployment or systems administration tasks. - ---- - -## What is Fabric? - -It provides a basic suite of operations for executing local or remote shell commands (normally or via sudo) and uploading/downloading files, as well as auxiliary functionality such as prompting the running user for input, or aborting execution. - ---- - -## I use Fabric to... - -- Simplify my build process -- Deploy code directly to different environments -- Act as an intermediate step - ---- - - - ---- - -[.build-lists: false] - -## Why Fabric? - -- Powerful -- Flexible -- Easier to read and write than bash - -^ - Can be used for different languages, frameworks -- Can be used for small, simple deployments or large, complicated ones -- Not very opinioned - ---- - -## Installing Fabric - -```bash -$ pip install fabric - -# macOS -$ brew install fabric - -# Debian, Ubuntu -$ apt-get install fabric -$ apt-get install python-fabric -``` - ---- - -## [fit] Writing your <br>first fabfile - ---- - -```python -# fabfile.py - -from fabric.api import env, run, cd, local - -env.hosts = ['example.com'] - -# Do stuff... -``` - -^ Callables - ---- - -```python -# fabfile.py - -from fabric.api import * - -env.hosts = ['example.com'] - -# Do stuff... -``` - ---- - -## Operations - -- cd, lcd - *change directory* -- run, sudo, local - *run a command* -- get - *download files* -- put - *upload files* - -[.footer: http://docs.fabfile.org/en/1.13/api/core/operations.html] - ---- - -## Utils - -- warn: *print warning message* -- abort: *abort execution, exit with error status* -- error: *call func with given error message* -- puts: *alias for print whose output is managed by Fabric's output controls* - -[.footer: http://docs.fabfile.org/en/1.13/api/core/utils.html] - ---- - -## File management - -```python -from fabric.contrib.files import * -``` - -- exists - *check if path exists* -- contains - *check if file contains text/matches regex* -- sed - *run search and replace on a file* -- upload_template - *render and upload a template to remote host* - -[.footer: http://docs.fabfile.org/en/1.13/api/contrib/files.html#fabric.contrib.files.append] - -^ Allows for jinja2 templates - ---- - -## Tasks - -```python - -def main(): - with cd('/var/www/html'): - run('git pull') - run('composer install') -``` - ---- - -## Task arguments - -```python, [.highlight: 1, 4-6] -def main(run_composer=True): - with cd('/var/www/html'): - run('git pull') - - if run_composer: - run('composer install') -``` - ---- - -## Task arguments - -```python, [.highlight: 1, 4-15] -def main(run_composer=True, env='prod', build_type): - with cd('/var/www/html'): - run('git pull') - - if run_composer: - if env == 'prod': - run('composer install --no-dev') - else: - run('composer install') - - if build_type == 'drupal': - ... - elif build_type == 'symfony': - ... - elif build_type == 'sculpin': - ... -``` - ---- - -## Calling other tasks - -```python, [.highlight: 4-15] -@task -def main(): - with cd('/var/www/html'): - build() - post_install() - -def build(): - run('git pull') - run('composer install') - -def post_install(): - with prefix('drush'): - run('updatedb -y') - run('entity-updates -y') - run('cache-rebuild') -``` - -^ Better organised code -Not everything in one long -Easier to read and comprehend -Single responsibilty principle - ---- - -## Running Tasks - -```bash -fab --list - -fab <task> - -fab <task>:build_number=$BUILD_ID,build_type=drupal -``` - -^ fabfile.py in the current directory is found automatically. - ---- - -``` -[production] Executing task 'main' -[production] run: git pull -[production] out: Already up-to-date. -[production] out: - -[production] run: composer install -... -[production] out: Generating autoload files -[production] out: - -Done. -Disconnecting from production... done. -``` - ---- - -## Downsides - -- Running build tasks on production - ---- - -[.build-lists: false] - -## Not Building on Prod - -1. Build locally and deploy. - ---- - -## Local tasks - -```python -# Runs remotely. - -from fabric.api import run - -run('git pull') -run('composer install') - -# Runs locally. - -from fabric.api import local - -local('git pull') -local('composer install') -``` - ---- - -## Local tasks - -```python -# Remote. - -from fabric.api import cd - -with cd('themes/custom/drupalbristol'): - ... - -# Runs locally. - -from fabric.api import lcd - -with lcd('themes/custom/drupalbristol'): - ... -``` - ---- - -## rsync - -```python, [.highlight: 1, 5-11] -from fabric.contrib.project import rsync_project - -... - -def deploy(): - rsync_project( - local_dir='./', - remote_dir='/var/www/html' - default_opts='-vzcrSLh', - exclude=('.git', 'node_modules/', '.sass-cache/') - ) -``` - ---- - -``` -[production] Executing task 'main' -[localhost] local: git pull -Current branch master is up to date. -[localhost] local: composer install -Loading composer repositories with package information -Installing dependencies (including require-dev) from lock file -Nothing to install or update -Generating autoload files - -Done. -``` - -^ - The risky steps have been run separate to the live code. -- Any issues will not affect the live site. - ---- - -[.build-lists: false] - -## Not Building on Prod - -1. ~~Build locally and deploy.~~ -1. Build in a separate directory and switch after build. - -^ Capistrano - ---- - -## Deploying into a different directory - -```python -from fabric.api import * -from time import time - -project_dir = '/var/www/html' -next_release = "%(time).0f" % { 'time': time() } # Current timestamp - -def init(): - if not exists(project_dir): - run('mkdir -p %s/backups' % project_dir) - run('mkdir -p %s/shared' % project_dir) - run('mkdir -p %s/releases' % project_dir) -``` - ---- - -## Deploying into a different directory - -```python -current_release = '%s/%s' % (releases_dir, next_release) - -run('git clone %s %s' % (git_repo, current_release)) - -def build(): - with cd(current_release): - pre_tasks() - build_site() - post_tasks() -``` - -^ - Clone the repository into a different directory -- Run any "risky" tasks away from the production code - ---- - -## Deploying into a different directory - -```python -def pre_build(build_number): - with cd('current'): - print '==> Dumping the DB (just in case)...' - backup_database() - -def backup_database(): - cd('drush sql-dump --gzip > ../backups/%s.sql.gz' % build_number) -``` - ---- - -## Deploying into a different directory - -```python -def update_symlinks(): - run('ln -nfs %s/releases/%s %s/current' - % (project_dir, next_release, project_dir)) - -# /var/www/html/current -``` - ---- - -``` -[production] Executing task 'main' -[production] run: git clone https://github.com/opdavies/oliverdavies.uk.git - /var/www/html/releases/1505865600 -Installing Composer dependencies... -[production] run: composer install --no-dev -Update the symlink to the new release... -[production] run: ln -nfs /var/www/html/releases/1505865600 - /var/www/html/current - -Done. -``` - ---- - -```bash -# /var/www/html - -shared # settings.local.php, sites.php, files etc. -releases/1502323200 -releases/1505692800 -releases/1505696400 -releases/1505865600 -current -> releases/1505865600 # symlink -``` - ---- - -[.build-lists: false] - -## Positives - -- Errors happen away from production - -## Downsides - -- Lots of release directories - -^ If the build fails, then your live site is not affected. - ---- - -## Removing old builds - -```python -def main(builds_to_keep=3): - with cd('%s/releases' % project_dir): - run("ls -1tr | head -n -%d | xargs -d '\\n' rm -fr" - % builds_to_keep) -``` - -^ - Find directory names -- 1tr not ltr -- Remove the directories -- Additional tasks, removing DB etc - ---- - - - -## [fit] Is the site <br>still running? - ---- - -## Checking for failures - -```python -run(command).return_code == 0: - # Pass - -run(command).return_code == 1: - # Fail - -run(command).failed: - # Fail -``` - -^ Works for local and remote. - ---- - -```python -print 'Checking the site is alive...' -if run('drush status | egrep "Connected|Successful"').failed: - # Revert back to previous build. -``` - -^ egrep is an acronym for "Extended Global Regular Expressions Print". It is a program which scans a specified file line by line, returning lines that contain a pattern matching a given regular expression. - ---- - -```bash, [.highlight 3] -$ drush status - -Drupal version : 8.3.7 -Site URI : http://default -Database driver : mysql -Database hostname : db -Database username : user -Database name : default -Database : Connected -Drupal bootstrap : Successful -Drupal user : -Default theme : bartik -Administration theme : seven -PHP configuration : /etc/php5/cli/php.ini -... -``` - -^ Successful - ---- - -```bash, [.highlight 3] -$ drush status - -Drupal version : 8.3.7 -Site URI : http://default -Database driver : mysql -Database hostname : db -Database username : user -Database name : default -PHP configuration : /etc/php5/cli/php.ini -... -``` - -^ Failed. -"Database" to "PHP configuration" missing if cannot connect or DB is empty. - ---- - -## [fit] Does the code still <br>merge cleanly? - -^ Pre-task - ---- - -```python -def check_for_merge_conflicts(target_branch): - with settings(warn_only=True): - print('Ensuring that this can be merged into the main branch.') - - if local('git fetch && git merge --no-ff origin/%s' - % target_branch).failed: - abort('Cannot merge into target branch.') -``` - -^ Define target branch in Jenkins/when Fabric is run. - ---- - - - -## [fit] Do our tests <br>still pass? - -[.footer: http://nashvillephp.org/images/testing-workshop-banner-1600x800.jpg] - ---- - -```python -with settings(warn_only=True): - with lcd('%s/docroot/core' % project_dir): - if local('../../vendor/bin/phpunit ../modules/custom').failed: - abort('Tests failed!') -``` - ---- - -``` -[localhost] run: ../../vendor/bin/phpunit ../modules/custom -[localhost] out: PHPUnit 4.8.35 by Sebastian Bergmann and contributors. -[localhost] out: -[localhost] out: ....... -[localhost] out: -[localhost] out: Time: 1.59 minutes, Memory: 6.00MB -[localhost] out: -[localhost] out: OK (7 tests, 42 assertions) -[localhost] out: - - -Done. -``` - ---- - -``` -[localhost] run: ../../vendor/bin/phpunit ../modules/custom -[localhost] out: PHPUnit 4.8.35 by Sebastian Bergmann and contributors. -[localhost] out: -[localhost] out: E -[localhost] out: -[localhost] out: Time: 18.67 seconds, Memory: 6.00MB -[localhost] out: -[localhost] out: There was 1 error: -[localhost] out: -[localhost] out: 1) Drupal\Tests\broadbean\Functional\AddJobTest::testNodesAreCreated -[localhost] out: Behat\Mink\Exception\ExpectationException: Current response status code is 200, but 201 expected. -[localhost] out: -[localhost] out: /var/www/html/vendor/behat/mink/src/WebAssert.php:770 -[localhost] out: /var/www/html/vendor/behat/mink/src/WebAssert.php:130 -[localhost] out: /var/www/html/docroot/modules/custom/broadbean/tests/src/Functional/AddJobTest.php:66 -[localhost] out: -[localhost] out: FAILURES! -[localhost] out: Tests: 1, Assertions: 6, Errors: 1. -[localhost] out: - -Warning: run() received nonzero return code 2 while executing '../../vendor/bin/phpunit ../modules/custom/broadbean'! - -Fatal error: Tests failed! - -Aborting. -``` - ---- - - - -## [fit] Making Fabric <br>Smarter - ---- - -## Conditional variables - -```python -drupal_version = None - -if exists('composer.json') and exists('core'): - drupal_version = 8 -else: - drupal_version = 7 -``` - ---- - -## Conditional tasks - -```python -if exists('composer.json'): - run('composer install') - -with cd('themes/custom/example'): - if exists('package.json') and not exists('node_modules'): - run('yarn --pure-lockfile') - - if exists('gulpfile.js'): - run('node_modules/.bin/gulp --production') - elif exists('gruntfile.js'): - run('node_modules/.bin/grunt build') -``` - ---- - -## Project settings file - -```yml -# app.yml - -drupal: - version: 8 - root: web - config: - import: yes - name: sync - cmi_tools: no - tests: - simpletest: false - phpunit: true - theme: - path: 'themes/custom/drupalbristol' - build: - type: gulp - npm: no - yarn: yes - -composer: - install: true -``` - ---- - -## Project settings file - -```python, [.highlight 3] -# fabfile.py - -from fabric.api import * -import yaml - -config = [] - -if exists('app.yml'): - with open('app.yml', 'r') as file: - config = yaml.load(file.read()) -``` - ---- - -## Project settings file - -```python -# fabfile.py - -if config['composer']['install'] == True: - local('composer install') -``` - ---- - -## Project settings file - -```python -# fabfile.py - -if build_type == 'drupal': - drupal = config['drupal'] -``` - ---- - -## Project settings file - -```python, [.highlight: 6-9] -# fabfile.py - -if build_type == 'drupal': - drupal = config['drupal'] - - with cd(drupal['root']): - if drupal['version'] == 8: - - if drupal['version'] == 7: -``` - ---- - -## Project settings file - -```python, [.highlight: 8-10] -# fabfile.py - -if build_type == 'drupal': - drupal = config['drupal'] - - with cd(drupal['root']): - if drupal['version'] == 8: - if drupal['config']['import'] == True: - # Import the staged configuration. - run('drush cim -y %s' % drupal['config']['name']) -``` - ---- - -## Project settings file - -```python, [.highlight: 9-15] -# fabfile.py - -if build_type == 'drupal': - drupal = config['drupal'] - - with cd(drupal['root']): - if drupal['version'] == 8: - if drupal['config']['import'] == True: - if drupal['config']['cmi_tools'] == True: - # Use Drush CMI Tools. - run('drush cimy -y %s' % drupal['config']['name']) - else: - # Use core. - run('drush cim -y %s' % drupal['config']['name']) -``` - -^ - Less hard-coded values -- More flexible -- No need to use different files for different versions or frameworks -- No forked fabfiles per project or lots of conditionals based on the project - ---- - -## Project settings file - -```python -# fabfile.py - -theme = config['theme'] - -with cd(theme['path']): - if theme['build']['gulp'] == True: - if env == 'prod': - run('node_modules/.bin/gulp --production') - else: - run('node_modules/.bin/gulp') -``` - ---- - -## Project settings file v2 - -```yml -# app.yml - -commands: - build: | - cd web/themes/custom/drupalbristol - yarn --pure-lockfile - npm run prod - - deploy: | - cd web - drush updatedb -y - drush cache-rebuild -y -``` - -^ How do we know when to run Composer or npm? -How do we know what commands to run? -Can't tell this just by the presence of files. - ---- - -## Project settings file v2 - -```python -# fabfile.py - -# Run build commands locally. -for hook in config['commands'].get('build', '').split("\n"): - run(hook) - -... - -# Run deploy commands remotely. -for hook in config['commands'].get('deploy', '').split("\n"): - run(hook) -``` - -^ "run" won't work locally - ---- - -## Other things - -- Run Drush commands -- Run automated tests -- Verify file permissions -- Restart services -- Anything you can do on the command line... - ---- - -[.build-lists: false] - -## Fabric has... - -- Simplified my build process -- Made my build process more flexible -- Made my build process more robust - ---- - -[.build-lists: false] - -- https://www.oliverdavies.uk/talks/deploying-drupal-fabric -- http://fabfile.org -- https://github.com/opdavies/fabric-example-drupal -- https://github.com/opdavies/fabric-example-sculpin -- https://deploy.serversforhackers.com (~~$129~~ $79) - ---- - -## Thanks! - -# Questions? - -### @opdavies -### oliverdavies.uk diff --git a/deploying-php-fabric/slides.md b/deploying-php-fabric/slides.md deleted file mode 100644 index 6cef1b0..0000000 --- a/deploying-php-fabric/slides.md +++ /dev/null @@ -1,748 +0,0 @@ -autoscale: true -build-lists: true -theme: poster, 7 - -# [fit] *Deploying* PHP<br>applications<br>*with* Fabric - ---- - -[.build-lists: false] - -- What is Fabric and what do I use it for? -- How to write and organise Fabric scripts -- Task examples - ---- - -[.build-lists: false] - -- Senior Developer at Microserve -- Part-time freelance Developer & Sysadmin -- Drupal Bristol, PHPSW, DrupalCamp Bristol -- @opdavies -- oliverdavies.uk - - - -^ Drupal (7 & 8), Symfony, Silex, Laravel, Sculpin -Not a Python Developer - ---- - -## *What is* Fabric*?* - ---- - -## What is Fabric? - -*Fabric is a* Python (2.5-2.7) library and command-line tool for streamlining the use of SSH *for application deployment or systems administration tasks.* - ---- - -## What is Fabric? - -It provides a basic suite of operations for executing local or remote shell commands (normally or via sudo) and uploading/downloading files, as well as auxiliary functionality such as prompting the running user for input, or aborting execution. - ---- - -## I use Fabric to... - -- Simplify my build process -- Deploy code directly to different environments -- Act as an intermediate step - ---- - - - ---- - -[.build-lists: false] - -## Why Fabric? - -- Powerful -- Flexible -- Easier to write than bash - -^ - Can be used for different languages, frameworks -- Can be used for small, simple deployments or large, complicated ones -- Not very opinioned - ---- - -## Installing Fabric - -```bash -$ pip install fabric - -# macOS -$ brew install fabric - -# Debian, Ubuntu -$ apt-get install fabric -$ apt-get install python-fabric -``` - ---- - -## Writing your <br>first *fabfile* - ---- - -```python -# fabfile.py - -from fabric.api import env, run, cd, local - -env.hosts = ['example.com'] - -# Do stuff... -``` - -^ Callables - ---- - -```python -# fabfile.py - -from fabric.api import * - -env.hosts = ['example.com'] - -# Do stuff... -``` - ---- - -## Operations - -- cd, lcd - *change directory* -- run, sudo, local - *run a command* -- get - *download files* -- put - *upload files* - -[.footer: http://docs.fabfile.org/en/1.13/api/core/operations.html] - ---- - -## Utils - -- warn: *print warning message* -- abort: *abort execution, exit with error status* -- error: *call func with given error message* -- puts: *alias for print whose output is managed by Fabric's output controls* - -[.footer: http://docs.fabfile.org/en/1.13/api/core/utils.html] - ---- - -## File management - -```python -from fabric.contrib.files import * -``` - -- exists - *check if path exists* -- contains - *check if file contains text/matches regex* -- sed - *run search and replace on a file* -- upload_template - *render and upload a template to remote host* - -[.footer: http://docs.fabfile.org/en/1.13/api/contrib/files.html#fabric.contrib.files.append] - -^ Allows for jinja2 templates - ---- - -## Tasks - -```python - -def build(): - with cd('/var/www/html'): - run('git pull') - run('composer install') -``` - ---- - -## Task arguments - -```python, [.highlight: 1, 4-6] -def build(run_composer=True): - with cd('/var/www/html'): - run('git pull') - - if run_composer: - run('composer install') -``` - ---- - -## Task arguments - -```python, [.highlight: 1, 4-15] -def build(run_composer=True, env='prod', build_type): - with cd('/var/www/html'): - run('git pull') - - if run_composer: - if env == 'prod': - run('composer install --no-dev') - else: - run('composer install') - - if build_type == 'drupal': - ... - elif build_type == 'symfony': - ... - elif build_type == 'sculpin': - ... -``` - ---- - -## Calling other tasks - -```python, [.highlight: 4-15] -@task -def build(): - with cd('/var/www/html'): - build() - post_install() - -def build(): - run('git pull') - run('composer install') - -def post_install(): - with prefix('drush'): - run('updatedb -y') - run('entity-updates -y') - run('cache-rebuild') -``` - -^ Better organised code -Not everything in one long -Easier to read and comprehend -Single responsibilty principle - ---- - -## Running Tasks - -```bash -fab --list - -fab <task> - -fab <task>:build_number=$BUILD_ID,build_type=drupal -``` - -^ fabfile.py in the current directory is found automatically. - ---- - -``` -[production] Executing task 'main' -[production] run: git pull -[production] out: Already up-to-date. -[production] out: - -[production] run: composer install -... -[production] out: Generating autoload files -[production] out: - -Done. -Disconnecting from production... done. -``` - ---- - -## Downsides - -- Running build tasks on production - ---- - -[.build-lists: false] - -## *Not* Building on Prod - -1. Build locally and deploy. - ---- - -## Local tasks - -```python -# Runs remotely. - -from fabric.api import run - -run('git pull') -run('composer install') - -# Runs locally. - -from fabric.api import local - -local('git pull') -local('composer install') -``` - ---- - -## Local tasks - -```python -# Remote. - -from fabric.api import cd - -with cd('themes/custom/drupalbristol'): - ... - -# Runs locally. - -from fabric.api import lcd - -with lcd('themes/custom/drupalbristol'): - ... -``` - ---- - -## rsync - -```python, [.highlight: 1, 5-11] -from fabric.contrib.project import rsync_project - -... - -def deploy(): - rsync_project( - local_dir='./', - remote_dir='/var/www/html' - default_opts='-vzcrSLh', - exclude=('.git', 'node_modules/', '.sass-cache/') - ) -``` - ---- - -``` -[production] Executing task 'main' -[localhost] local: git pull -Current branch master is up to date. -[localhost] local: composer install -Loading composer repositories with package information -Installing dependencies (including require-dev) from lock file -Nothing to install or update -Generating autoload files - -Done. -``` - -^ - The risky steps have been run separate to the live code. -- Any issues will not affect the live site. - ---- - -[.build-lists: false] - -## *Not* Building on Prod - -1. ~~Build locally and deploy.~~ -1. Build in a separate directory and switch after build. - -^ Capistrano - ---- - -## Deploying into a *different directory* - -```python -from fabric.api import * -from time import time - -project_dir = '/var/www/html' -next_release = "%(time).0f" % { 'time': time() } # timestamp - -def init(): - if not exists(project_dir): - run('mkdir -p %s/backups' % project_dir) - run('mkdir -p %s/shared' % project_dir) - run('mkdir -p %s/releases' % project_dir) -``` - ---- - -## Deploying into a *different directory* - -```python -current_release = '%s/%s' % (releases_dir, next_release) - -run('git clone %s %s' % (git_repo, current_release)) - -def build(): - with cd(current_release): - pre_tasks() - build() - post_tasks() -``` - -^ - Clone the repository into a different directory -- Run any "risky" tasks away from the production code - ---- - -## Deploying into a *different directory* - -```python -def pre_build(build_number): - with cd('current'): - print '==> Dumping the DB (just in case)...' - backup_database() - -def backup_database(): - cd('drush sql-dump --gzip > ../backups/%s.sql.gz' % build_number) -``` - ---- - -## Deploying into a *different directory* - -```python -def update_symlinks(): - run('ln -nfs %s/releases/%s %s/current' - % (project_dir, next_release, project_dir)) - -# /var/www/html/current -``` - ---- - -``` -[production] Executing task 'main' -[production] run: git clone https://github.com/opdavies/oliverdavies.uk.git - /var/www/html/releases/1505865600 -===> Installing Composer dependencies... -[production] run: composer install --no-dev -===> Update the symlink to the new release... -[production] run: ln -nfs /var/www/html/releases/1505865600 - /var/www/html/current - -Done. -``` - ---- - -```bash -# /var/www/html - -shared -releases/1502323200 -releases/1505692800 -releases/1505696400 -releases/1505865600 -current -> releases/1505865600 # symlink -``` - ---- - -## Positives - -- Errors happen away from production - -## Downsides - -- Lots of release directories - ---- - -## Removing old builds - -```python -def main(builds_to_keep=3): - with cd('%s/releases' % project_dir): - run("ls -1tr | head -n -%d | xargs -d '\\n' rm -fr" - % builds_to_keep) -``` - -^ - Find directory names -- 1tr not ltr -- Remove the directories -- Additional tasks, removing DB etc - ---- - -## Is the site still running? - ---- - -## Checking for failures - -```python -run(command).failed: - # Fail - -run(command).return_code == 0: - # Pass - -run(command).return_code == 1: - # Fail -``` - -^ Works for local and remote. - ---- - -```python -def post_tasks(): - print '===> Checking the site is alive.' - if run('drush status | egrep "Connected|Successful"').failed: - # Revert back to previous build. -``` - ---- - -```bash, [.highlight 3] -$ drush status - -Drupal version : 8.3.7 -Site URI : http://default -Database driver : mysql -Database hostname : db -Database username : user -Database name : default -Database : Connected -Drupal bootstrap : Successful -Drupal user : -Default theme : bartik -Administration theme : seven -PHP configuration : /etc/php5/cli/php.ini -... -``` - -^ "Database" to "PHP configuration" missing if cannot connect. - ---- - -## Does the code still merge cleanly? - -^ Pre-task - ---- - -```python -def check_for_merge_conflicts(target_branch): - with settings(warn_only=True): - print('===> Ensuring that this can be merged into the main branch.') - - if local('git fetch && git merge --no-ff origin/%s' % target_branch).failed: - abort('Cannot merge into target branch.') -``` - ---- - - - -## Making fabric smarter - ---- - -## Conditional variables - -```python -drupal_version = None - -if exists('composer.json') and exists('core'): - drupal_version = 8 -else: - drupal_version = 7 -``` - ---- - -## Conditional tasks - -```python -if exists('composer.json'): - run('composer install') - -with cd('themes/custom/example'): - if exists('package.json') and not exists('node_modules'): - run('yarn --pure-lockfile') - - if exists('gulpfile.js'): - run('node_modules/.bin/gulp --production') - elif exists('gruntfile.js'): - run('node_modules/.bin/grunt build') -``` - ---- - -## Project settings file - -```yml -# app.yml - -drupal: - version: 8 - root: web - config: - import: yes - name: sync - cmi_tools: no - theme: - path: 'themes/custom/drupalbristol' - build: - npm: no - type: gulp - yarn: yes - -composer: - install: true -``` - ---- - -## Project settings file - -```python, [.highlight 3] -# fabfile.py - -from fabric.api import * -import yaml - -with open('app.yml', 'r') as file: - config = yaml.load(file.read()) -``` - ---- - -## Project settings file - -```python -# fabfile.py - -if config['composer']['install'] == True: - local('composer install') -``` - ---- - -## Project settings file - -```python -# fabfile.py - -if build_type == 'drupal': - drupal = config['drupal'] - - with cd(drupal['root']): - if drupal['version'] == 8: - if drupal['config']['import'] == True: - if drupal['config']['cmi_tools']: - run('drush cim -y %s' % drupal['config']['import']['name']) - else: - run('drush cimy -y %s' % drupal['config']['import']['name']) - - if drupal['version'] == 7: - ... -``` - -^ - Less hard-coded values -- More flexible -- No need to use different files for different versions or frameworks -- No forked fabfiles per project or lots of conditionals based on the project - ---- - -## Project settings file - -```python -theme = config['theme'] - -with cd(theme['path']): - if theme['build']['gulp'] == True: - if env == 'prod': - run('node_modules/.bin/gulp --production') - else: - run('node_modules/.bin/gulp') -``` - ---- - -## Project settings file v2 - -```yml -# app.yml - -commands: - build: | - cd web/themes/custom/drupalbristol - yarn --pure-lockfile - node_modules/.bin/gulp --production - - deploy: | - cd web - drush cache-rebuild -y -``` - ---- - -## Project settings file v2 - -```python -# fabfile.py - -for hook in config['commands'].get('build', '').split("\n"): - run(hook) - -... - -for hook in config['commands'].get('deploy', '').split("\n"): - run(hook) -``` - ---- - -## Other things - -- Run Drush/console/artisan commands -- Verify file permissions -- Restart services -- Anything you can do on the command line... - ---- - -[.build-lists: false] - -## Fabric has... - -- Simplified my build process -- Made my build process more flexible -- Made my build process more robust - ---- - -[.build-lists: false] - -- https://www.oliverdavies.uk/talks/deploying-php-fabric -- http://fabfile.org -- https://github.com/opdavies/fabric-example-sculpin -- https://github.com/opdavies/fabric-example-drupal -- https://deploy.serversforhackers.com (~~$129~~ $79) - ---- - -## *joind.in/talk/*4e35d - ---- - -## @opdavies -## *oliverdavies.uk* diff --git a/drupal-dev-days-recap/images/IMG_5278.jpg b/drupal-dev-days-recap/images/IMG_5278.jpg deleted file mode 100644 index b30c532..0000000 Binary files a/drupal-dev-days-recap/images/IMG_5278.jpg and /dev/null differ diff --git a/drupal-dev-days-recap/images/autowiring-tweet.png b/drupal-dev-days-recap/images/autowiring-tweet.png deleted file mode 100644 index a35d2d5..0000000 Binary files a/drupal-dev-days-recap/images/autowiring-tweet.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/block-aria-roles-2.png b/drupal-dev-days-recap/images/block-aria-roles-2.png deleted file mode 100644 index 6840d1f..0000000 Binary files a/drupal-dev-days-recap/images/block-aria-roles-2.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/block-aria-roles.png b/drupal-dev-days-recap/images/block-aria-roles.png deleted file mode 100644 index 54046b5..0000000 Binary files a/drupal-dev-days-recap/images/block-aria-roles.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/dev-days-website.png b/drupal-dev-days-recap/images/dev-days-website.png deleted file mode 100644 index 2180213..0000000 Binary files a/drupal-dev-days-recap/images/dev-days-website.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/dev-days-youtube.png b/drupal-dev-days-recap/images/dev-days-youtube.png deleted file mode 100644 index e108eb5..0000000 Binary files a/drupal-dev-days-recap/images/dev-days-youtube.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/gabor-keynote.png b/drupal-dev-days-recap/images/gabor-keynote.png deleted file mode 100644 index db9890f..0000000 Binary files a/drupal-dev-days-recap/images/gabor-keynote.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/lisbon-map.png b/drupal-dev-days-recap/images/lisbon-map.png deleted file mode 100644 index ef4582a..0000000 Binary files a/drupal-dev-days-recap/images/lisbon-map.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/membership-renewal.png b/drupal-dev-days-recap/images/membership-renewal.png deleted file mode 100644 index 3659d05..0000000 Binary files a/drupal-dev-days-recap/images/membership-renewal.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/membership-tweet.png b/drupal-dev-days-recap/images/membership-tweet.png deleted file mode 100644 index b66d25f..0000000 Binary files a/drupal-dev-days-recap/images/membership-tweet.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/rachel-keynote-2.png b/drupal-dev-days-recap/images/rachel-keynote-2.png deleted file mode 100644 index 451e58d..0000000 Binary files a/drupal-dev-days-recap/images/rachel-keynote-2.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/rachel-keynote.png b/drupal-dev-days-recap/images/rachel-keynote.png deleted file mode 100644 index b5f4d50..0000000 Binary files a/drupal-dev-days-recap/images/rachel-keynote.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/rslootjes-slide.png b/drupal-dev-days-recap/images/rslootjes-slide.png deleted file mode 100644 index 2fb03f3..0000000 Binary files a/drupal-dev-days-recap/images/rslootjes-slide.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/security-slide.png b/drupal-dev-days-recap/images/security-slide.png deleted file mode 100644 index 8e8bb0a..0000000 Binary files a/drupal-dev-days-recap/images/security-slide.png and /dev/null differ diff --git a/drupal-dev-days-recap/images/talk-feedback.png b/drupal-dev-days-recap/images/talk-feedback.png deleted file mode 100644 index 1a94d6b..0000000 Binary files a/drupal-dev-days-recap/images/talk-feedback.png and /dev/null differ diff --git a/drupal-dev-days-recap/slides.md b/drupal-dev-days-recap/slides.md deleted file mode 100644 index d8106c5..0000000 --- a/drupal-dev-days-recap/slides.md +++ /dev/null @@ -1,101 +0,0 @@ -theme: plain jane - -# **Drupal Developer Days <br>2018 Recap** - - - ---- - - - ---- - - - ---- - - - -^ 400 people - ---- - - - -^ sprints - ---- - - - ---- - - - -^ Yay, commit credits! - ---- - - - -^ Composer, JS in core, admin UI, API first -Signs on tables, online meetings and Slack channels -Find the right people -Get involved with something that interests you rather than searching for random issues - ---- - - - -^ Symfony Framework style API building in Drupal -symfony guy -things i've done in symfony that I didn't know you could do in D8 -great to see cross-community knowledge sharing - ---- - - - ---- - - - -^ Jess (xjm) - D8 release manager -Responsible disclosure, cross-project collaboration, and Drupal 8 security -Don't include dev dependencies in prod code! -ODL was doing this! -immediate ROI - ---- - - - ---- - - - ---- - - - ---- - - - -^ Great to chat about the DA with Rachel - ---- - - - -^ Membership drive - ---- - - - ---- - - - -^ Videos are now online diff --git a/drupal-testing-workshop/2018-06-28-drupal-bristol/slides.md b/drupal-testing-workshop/2018-06-28-drupal-bristol/slides.md deleted file mode 100644 index ffb2ec8..0000000 --- a/drupal-testing-workshop/2018-06-28-drupal-bristol/slides.md +++ /dev/null @@ -1,1844 +0,0 @@ -autoscale: true -build-lists: true -header-emphasis: #53B0EB -header: alignment(left) -text: alignment(left) -text-emphasis: #53B0EB -theme: poster, 8 - -[.header: alignment(center)] - - - -# [fit] Drupal Testing Workshop -### _Drupal Bristol, June 2018_ - ---- - -[.build-lists: false] - -- Module and theme developers -- Want to know more about automated testing -- Looking to start writing your first tests - ---- - -[.background-color: #FFFFFF] -[.build-lists: false] -[.header: #111111] -[.text: #111111, alignment(left)] - - - -- Full stack Web Developer & System Administrator -- Senior Developer at Microserve -- Part-time freelancer -- Acquia certified Drupal 8 Grand Master -- Drupal 7 & 8 core contributor -- opdavies (Drupal.org, GitHub, Twitter) -- www.oliverdavies.uk - -^ Work at Microserve. -Maintain Drupal modules, PHP CLI tools and libraries -Blog on my website - ---- - -[.header: alignment(center)] - -## Test_Driven_Drupal_.com_ - ---- - -[.header: alignment(center)] - -## _Why_ write tests? - ---- - -## _Why write tests?_ - -- Catch bugs earlier -- Piece of mind -- Prevent regressions -- Write less code -- Documentation -- Drupal core requirement - _<https://www.drupal.org/core/gates#testing>_ -- More important with regular D8 releases - -^ Dave Liddament talk - better and cheaper to catch bugs earlier (e.g. whilst developing rather than after it's been released) -Refer to tests when writing implementation code -ONO merge conflict - ---- - -[.header: alignment(center)] - -## [fit] _Having tests does not mean_ -## [fit] there will be no bugs - ---- - -[.header: alignment(center)] - -## [fit] _Testing may add time now_ -## [fit] but save more time in the future - ---- - -## _Testing in Drupal_ - -- _Drupal 7_ - Simpletest (testing) module provided as part of core -- _Drupal 8_ - PHPUnit added as a core dependency -- _PHPUnit Initiative_ - Simpletest to be deprecated and removed in Drupal 9 - -^ Focussing on PHPUnit today - ---- - -### _Exercise 1_ -## Local site setup - ---- - -[.header: #53B0EB] - -## Docksal - -- Docker based local development environment -- Microserve standard -- Open source -- Per site configuration and customisation -- fin CLI, Apache, MySQL, Solr, Varnish, Mailhog, PHPMyAdmin etc -- Virtualbox or native Docker -- Can slow down tests -- Provides consistency - ---- - -- https://github.com/opdavies/drupal-testing-workshop -- https://docksal.io/installation -- git clone -- fin init -- http://drupaltest.docksal - -^ Contains Drupal 8 with Composer, examples module - ---- - -### _Exercise 2_ -## Running Tests - ---- - -### _Option 1_ -## Simpletest module (UI) - ---- - - - ---- - - - ---- - - - ---- - - - ---- - - - ---- - - - ---- - - - ---- - -### _Option 2_ -## Command line - ---- - -## Prerequisite _(creating a phpunit.xml file)_ - -- Configures PHPUnit -- Needed to run some types of tests -- Ignored by Git by default -- Copy _core/phpunit.xml.dist_ to _core/phpunit.xml_ -- Add and change as needed - - `SIMPLETEST_BASE_URL`, `SIMPLETEST_DB`, `BROWSERTEST_OUTPUT_DIRECTORY` - - `stopOnFailure="true"` - ---- - -``` -cd web - -../vendor/bin/phpunit -c core \ -modules/contrib/examples/phpunit_example -``` - ---- - -``` -cd web/core - -../../vendor/bin/phpunit \ -../modules/contrib/examples/phpunit_example -``` - ---- - -## Pro-tip: Add paths to _$PATH_ - -```bash -# ~/.zshrc - -export PATH=$HOME/bin:/usr/local/bin:$PATH - -export PATH=vendor/bin:$PATH -export PATH=../vendor/bin:$PATH -export PATH=node_modules/.bin:$PATH -``` - ---- - -### _Option 2_ -## CLI with Docksal - ---- - -``` -fin bash - -cd web - -../vendor/bin/phpunit -c core \ -modules/contrib/examples/phpunit_example -``` - ---- - -``` -fin bash - -cd web/core - -../../vendor/bin/phpunit \ -../modules/contrib/examples/phpunit_example -``` - ---- - -### _Option 3_ -## Docksal PHPUnit addon - ---- - -- Custom Docksal command -- Submitted to the Docksal addons repo -- _fin addon install phpunit_ -- Wrapper around phpunit command -- Copies a stub phpunit.xml file if exists, or duplicates phpunit.xml.dist -- Shorter command, combines two actions - -^ Checks for core/phpunit.xml on each test run -Will create one if is not present - ---- - -``` -fin phpunit web/modules/contrib/examples/phpunit_example -``` - ---- - -``` -fin phpunit web/modules/contrib/examples/phpunit_example - - -Copying /var/www/.docksal/drupal/core/phpunit.xml to /var/www/web/core/phpunit.xml -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/contrib/examples/phpunit_example -.................................. 34 / 34 (100%) - -Time: 46.8 seconds, Memory: 6.00MB - -OK (34 tests, 41 assertions) -``` - ---- - -``` -fin phpunit web/modules/contrib/examples/phpunit_example - - -Copying /var/www/web/core/phpunit.xml.dist to /var/www/web/core/phpunit.xml. -Please edit it's values as needed and re-run 'fin phpunit'. -``` ---- - -``` -fin phpunit web/modules/contrib/examples/phpunit_example - - -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/contrib/examples/phpunit_example -.................................. 34 / 34 (100%) - -Time: 48.62 seconds, Memory: 6.00MB - -OK (34 tests, 41 assertions) -``` - ---- - -### _Option 4_ -## IDE/text editor integration - ---- - - - ---- - -[.header: alignment(center)] - -## Types of tests - ---- - -[.header: alignment(center)] - -## _1._ Arrange -## _2._ Act -## _3._ Assert - ---- - -[.header: #53B0EB] - -## Functional tests - -- Tests functionality -- Interacts with database -- Full Drupal installation -- Slower to run -- With/without JavaScript - -^ testing profile - ---- - -### _Exercise_ -## Let's write a <br>functional test - ---- - -- Create a _web/modules/custom/drupalbristol_ directory -- Create a `drupalbristol.info.yml` file - ---- - -``` -# drupalbristol.info.yml - -name: Drupal Bristol -core: 8.x -type: module -``` - ---- - -- Create a _tests/src/Functional_ directory -- Create an _ExampleFunctionalTest.php_ file - ---- - - -```php -// ExampleFunctionalTest.php - -namespace Drupal\Tests\drupalbristol\Functional; - -use Drupal\Tests\BrowserTestBase; - -class ExampleFunctionalTest extends BrowserTestBase { - -} - -``` - ---- - -```php - -// ExampleFunctionalTest.php - -public function testExamplePage() { - $this->drupalGet('/example-one'); - - $this->assertSession()->statusCodeEquals(200); -} -``` - ---- - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing Drupal\Tests\drupalbristol\Functional\ExampleFunctionalTest - -Behat\Mink\Exception\ExpectationException : Current response status code is 404, but 200 expected. - /var/www/vendor/behat/mink/src/WebAssert.php:768 - /var/www/vendor/behat/mink/src/WebAssert.php:130 - /var/www/web/modules/custom/drupalbristol/tests/src/Functional/ExampleFunctionalTest.php:14 - -Time: 18.2 seconds, Memory: 6.00MB - -ERRORS! -Tests: 1, Assertions: 2, Errors: 1. -``` - ---- - -- Create a _drupalbristol.routing.yml_ file -- Create a Controller - ---- - -```yaml -# drupalbristol.routing.yml - -drupalbristol.example: - path: '/example-one' - defaults: - _controller: 'Drupal\drupalbristol\Controllers\ExampleController::index' - requirements: - _access: 'TRUE' -``` - ---- - -```php -// src/Controllers/ExampleController.php - -namespace Drupal\drupalbristol\Controllers; - -use Drupal\Core\Controller\ControllerBase; - -class ExampleController extends ControllerBase { - - public function index() { - return ['#markup' => $this->t('Drupal Testing Workshop')]; - } - -} -``` - ---- - -```php -class ExampleFunctionalTest extends BrowserTestBase { - - protected static $modules = ['drupalbristol']; - - ... -} -``` - ---- - -[.header: #53B0EB] - -## Kernel tests - -- Integration tests -- Can install modules, interact with services, container, database -- Minimal Drupal bootstrap -- Faster than functional tests -- More setup required - ---- - -### _Exercise_ -## Let's write a <br>kernel test - ---- - -- Create a _tests/src/Kernel directory -- Create an _ExampleKernelTest.php_ file -- Create a Service -- Use the service within the test to perform an action - ---- - -```php -// tests/src/Kernel/ExampleKernelTest.php - -namespace Drupal\Tests\drupalbristol\Kernel; - -use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; -use Drupal\user\Entity\User; - -class ExampleKernelTest extends EntityKernelTestBase { - - public static $modules = ['drupalbristol']; - - public function testUserDeleter() { - } - -} - -``` - ---- - -```php -// tests/src/Kernel/ExampleKernelTest.php - -public function testUserDeleter { - $user = $this->createUser(); - - $this->assertInstanceOf(User::class, $user); - - /** @var \Drupal\drupalbristol\Services\UserDeleter $user_deleter */ - $user_deleter = \Drupal::service('drupalbristol.user_deleter'); - $user_deleter->delete($user); - - $user = $this->reloadEntity($user); - - $this->assertNull($user); -} -``` - ---- - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing Drupal\Tests\drupalbristol\Kernel\ExampleKernelTest - -Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException : You have requested a non-existent service "drupalbristol.user_deleter". - /var/www/vendor/symfony/dependency-injection/ContainerBuilder.php:1043 - /var/www/vendor/symfony/dependency-injection/ContainerBuilder.php:610 - /var/www/vendor/symfony/dependency-injection/ContainerBuilder.php:588 - /var/www/web/core/lib/Drupal.php:159 - /var/www/web/modules/custom/drupalbristol/tests/src/Kernel/ExampleKernelTest.php:24 - -Time: 7.06 seconds, Memory: 6.00MB - - -ERRORS! -Tests: 1, Assertions: 3, Errors: 1. - -Process finished with exit code 2 -``` - ---- - -```yaml -# drupalbristol.services.yml - -services: - drupalbristol.user_deleter: - class: 'Drupal\drupalbristol\Services\UserDeleter' - arguments: [] -``` - ---- - -```php -// src/Services/UserDeleter.php - -namespace Drupal\drupalbristol\Services; - -use Drupal\Core\Session\AccountInterface; - -class UserDeleter { - - public function delete(AccountInterface $user) { - user_delete($user->id()); - } - -} -``` - ---- - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing Drupal\Tests\drupalbristol\Kernel\ExampleKernelTest - -Drupal\Core\Entity\EntityStorageException : SQLSTATE[HY000]: General error: 1 no such table: test89378988.users_data: DELETE FROM {users_data} -WHERE uid IN (:db_condition_placeholder_0); Array -( - [:db_condition_placeholder_0] => 1 -) - - /var/www/web/core/lib/Drupal/Core/Entity/Sql/SqlContentEntityStorage.php:777 - /var/www/web/core/includes/entity.inc:281 - /var/www/web/core/modules/user/user.module:878 - /var/www/web/core/modules/user/user.module:865 - /var/www/web/modules/custom/drupalbristol/src/Services/UserDeleter.php:10 - /var/www/web/modules/custom/drupalbristol/tests/src/Kernel/ExampleKernelTest.php:25 - - Caused by - Drupal\Core\Database\DatabaseExceptionWrapper: SQLSTATE[HY000]: General error: 1 no such table: test89378988.users_data: DELETE FROM {users_data} - WHERE uid IN (:db_condition_placeholder_0); Array - ( - [:db_condition_placeholder_0] => 1 - ) - -Time: 6.55 seconds, Memory: 6.00MB - -ERRORS! -Tests: 1, Assertions: 3, Errors: 1. - -Process finished with exit code 2 -``` - ---- - -```php -// tests/src/Kernel/ExampleKernelTest.php - -protected function setUp() { - parent::setUp(); - - $this->installSchema('user', ['users_data']); -} -``` - ---- - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing Drupal\Tests\drupalbristol\Kernel\ExampleKernelTest - - -Time: 7.38 seconds, Memory: 6.00MB - -OK (1 test, 5 assertions) - -Process finished with exit code 0 - -``` - ---- - -[.header: #53B0EB] - -## Unit tests - -- Tests PHP logic -- No database interaction -- Fast to run -- Tightly coupled -- Mocking dependencies -- Hard to refactor - ---- - -### _Exercise_ -## Let's write a <br>unit test - ---- - -```php -// tests/src/Unit/Services/ExampleUnitTest.php - -namespace Drupal\Tests\drupalbristol\Unit; - -use Drupal\Tests\UnitTestCase; - -class ExampleUnitTest extends UnitTestCase { - - public function testAdd() { - $this->assertEquals(5, (new Calculator(3))->add(2)->calculate()); - } -} -``` - ---- - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing Drupal\Tests\drupalbristol\Unit\ExampleUnitTest - -Error : Class 'Drupal\Tests\drupalbristol\Unit\Calculator' not found - /var/www/web/modules/custom/drupalbristol/tests/src/Unit/Services/ExampleUnitTest.php:10 - -Time: 5.13 seconds, Memory: 6.00MB - - -ERRORS! -Tests: 1, Assertions: 0, Errors: 1. -``` - ---- - -```php -// src/Services/Calculator.php - -namespace Drupal\drupalbristol\Services; - -class Calculator { - - private $total; - - public function __construct($value) { - $this->total = $value; - } - - public function add($value) { - $this->total += $value; - - return $this; - } - - public function calculate() { - return $this->total; - } - -} -``` - ---- - -```php -// tests/src/Unit/Services/ExampleUnitTest.php - -namespace Drupal\Tests\drupalbristol\Unit; - -use Drupal\drupalbristol\Services\Calculator; -use Drupal\Tests\UnitTestCase; - -class ExampleUnitTest extends UnitTestCase { - - public function testAdd() { - $this->assertEquals(5, (new Calculator(3))->add(2)->calculate()); - } - -} -``` - ---- - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing Drupal\Tests\drupalbristol\Unit\ExampleUnitTest - - -Time: 4.55 seconds, Memory: 4.00MB - -OK (1 test, 1 assertion) -``` - ---- - -[.header: alignment(center)] - -## Test driven <br>development _(TDD)_ - ---- - - -## _Test Driven Development_ - -- Write a test -- Test fails -- Write code -- Test passes -- Refactor -- Repeat - ---- - -[.background-color: #FFFFFF] -[.footer: https://github.com/foundersandcoders/testing-tdd-intro] -[.footer-style: #2F2F2F] - - - ---- - -## _How I Write Tests - "Outside In"_ - -- Start with functional tests -- Drop down to kernel or unit tests where needed -- Programming by wishful thinking -- Write comments first, then fill in the code -- Sometimes write assertions first - ---- - -### _Exercise_ -## Let's build a blog using test driven development - - ---- - -## _Acceptance criteria_ - -- As a site visitor -- I want to see a list of published articles at /blog -- Ordered by post date - ---- - -## _Tasks_ - -- Ensure the blog page exists -- Ensure only published articles are shown -- Ensure the articles are shown in the correct order - ---- - -## _Implementation_ - -- Use views module -- Do the mininum amount at each step, make no assumptions, let the tests guide us -- Start with functional test - ---- - -### _Step 1_ -## Create the module - ---- - -```yml -# tdd_blog.info.yml - -name: 'TDD Blog' -core: '8.x' -type: 'module' -``` - ---- - -### _Step 2_ -## Ensure the blog page exists - ---- - - -```php -<?php - -// tests/src/Functional/BlogPageTest.php - -namespace Drupal\Tests\tdd_blog\Functional; - -use Drupal\Tests\BrowserTestBase; - -class BlogPageTest extends BrowserTestBase { - - protected static $modules = ['tdd_blog']; - - public function testBlogPageExists() { - $this->drupalGet('/blog'); - - $this->assertSession()->statusCodeEquals(200); - } - -} -``` - ---- - - -```php, [.highlight: 5] -<?php - -// tests/src/Functional/BlogPageTest.php - -namespace Drupal\Tests\tdd_blog\Functional; - -use Drupal\Tests\BrowserTestBase; - -class BlogPageTest extends BrowserTestBase { - - protected static $modules = ['tdd_blog']; - - public function testBlogPageExists() { - $this->drupalGet('/blog'); - - $this->assertSession()->statusCodeEquals(200); - } - -} -``` - ---- - - -```php, [.highlight: 7-9] -<?php - -// tests/src/Functional/BlogPageTest.php - -namespace Drupal\Tests\tdd_blog\Functional; - -use Drupal\Tests\BrowserTestBase; - -class BlogPageTest extends BrowserTestBase { - - protected static $modules = ['tdd_blog']; - - public function testBlogPageExists() { - $this->drupalGet('/blog'); - - $this->assertSession()->statusCodeEquals(200); - } - -} -``` - ---- - - -```php, [.highlight: 11] -<?php - -// tests/src/Functional/BlogPageTest.php - -namespace Drupal\Tests\tdd_blog\Functional; - -use Drupal\Tests\BrowserTestBase; - -class BlogPageTest extends BrowserTestBase { - - protected static $modules = ['tdd_blog']; - - public function testBlogPageExists() { - $this->drupalGet('/blog'); - - $this->assertSession()->statusCodeEquals(200); - } - -} -``` - ---- - - -```php, [.highlight: 13-17] -<?php - -// tests/src/Functional/BlogPageTest.php - -namespace Drupal\Tests\tdd_blog\Functional; - -use Drupal\Tests\BrowserTestBase; - -class BlogPageTest extends BrowserTestBase { - - protected static $modules = ['tdd_blog']; - - public function testBlogPageExists() { - $this->drupalGet('/blog'); - - $this->assertSession()->statusCodeEquals(200); - } - -} -``` - ---- - - -```bash, [.highlight: 1] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -E 1 / 1 (100%) - -Time: 19.31 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. - -/var/www/vendor/behat/mink/src/WebAssert.php:768 -/var/www/vendor/behat/mink/src/WebAssert.php:130 -/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13 - -ERRORS! -Tests: 1, Assertions: 3, Errors: 1. -``` - ---- - - -```bash, [.highlight: 4] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -E 1 / 1 (100%) - -Time: 19.31 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. - -/var/www/vendor/behat/mink/src/WebAssert.php:768 -/var/www/vendor/behat/mink/src/WebAssert.php:130 -/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13 - -ERRORS! -Tests: 1, Assertions: 3, Errors: 1. -``` - ---- - - -```bash, [.highlight: 5-13] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -E 1 / 1 (100%) - -Time: 19.31 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. - -/var/www/vendor/behat/mink/src/WebAssert.php:768 -/var/www/vendor/behat/mink/src/WebAssert.php:130 -/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13 - -ERRORS! -Tests: 1, Assertions: 3, Errors: 1. -``` - ---- - - -```bash, [.highlight: 14-16] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -E 1 / 1 (100%) - -Time: 19.31 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. - -/var/www/vendor/behat/mink/src/WebAssert.php:768 -/var/www/vendor/behat/mink/src/WebAssert.php:130 -/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13 - -ERRORS! -Tests: 1, Assertions: 3, Errors: 1. -``` - ---- - - -```bash, [.highlight: 18-19] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -E 1 / 1 (100%) - -Time: 19.31 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Behat\Mink\Exception\ExpectationException: Current response status code is 404, but 200 expected. - -/var/www/vendor/behat/mink/src/WebAssert.php:768 -/var/www/vendor/behat/mink/src/WebAssert.php:130 -/var/www/web/modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php:13 - -ERRORS! -Tests: 1, Assertions: 3, Errors: 1. -``` - ---- - -- _The view has not been created_ -- Create a new view -- Set the path -- Export the config -- Copy it into the module's `config/install` directory - ---- - - -```[.highlight: 11-13] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -E 1 / 1 (100%) - -Time: 16.02 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by <em class="placeholder">tdd_blog</em> -have unmet dependencies: <em class="placeholder">views.view.blog (node.type.article, node, views)</em> - -/var/www/web/core/lib/Drupal/Core/Config/UnmetDependenciesException.php:98 -/var/www/web/core/lib/Drupal/Core/Config/ConfigInstaller.php:469 -/var/www/web/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php:132 -/var/www/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:145 -/var/www/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83 -/var/www/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:437 -/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:1055 -/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:490 - -ERRORS! -Tests: 1, Assertions: 0, Errors: 1. -``` - ---- - - -```yml,[.highlight: 1, 7-10] -# tdd_blog.info.yml - -name: 'TDD Dublin' -description: 'A demo module to show test driven module development.' -core: 8.x -type: module - -dependencies: - - 'drupal:node' - - 'drupal:views' -``` - ---- - - -```[.highlight: 10-13] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -E 1 / 1 (100%) - -Time: 20 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Functional\BlogPageTest::testBlogPageExists -Drupal\Core\Config\UnmetDependenciesException: Configuration objects provided by <em class="placeholder">tdd_blog</em> -have unmet dependencies: <em class="placeholder">views.view.blog (node.type.article)</em> - -/var/www/web/core/lib/Drupal/Core/Config/UnmetDependenciesException.php:98 -/var/www/web/core/lib/Drupal/Core/Config/ConfigInstaller.php:469 -/var/www/web/core/lib/Drupal/Core/ProxyClass/Config/ConfigInstaller.php:132 -/var/www/web/core/lib/Drupal/Core/Extension/ModuleInstaller.php:145 -/var/www/web/core/lib/Drupal/Core/ProxyClass/Extension/ModuleInstaller.php:83 -/var/www/web/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php:437 -/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:1055 -/var/www/web/core/tests/Drupal/Tests/BrowserTestBase.php:490 - -ERRORS! -Tests: 1, Assertions: 0, Errors: 1. -``` - ---- - -- Add the article content type - ---- - - -```[.highlight: 5, 9] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog -. 1 / 1 (100%) - -Time: 23.36 seconds, Memory: 6.00MB - -OK (1 test, 3 assertions) -``` - ---- - -[.build-lists: false] - -## _Tasks_ - -- ~~Ensure the blog page exists~~ -- Ensure only published articles are shown -- Ensure the articles are shown in the correct order - ---- - -### _Step 3_ -## Ensure only published articles are shown - ---- - - -```php -public function testOnlyPublishedArticlesAreShown() { - // Given I have a mixture of published and unpublished articles, - // as well as other types of content. - - // When I view the blog page. - - // I should only see the published articles. -} -``` - ---- - -### _Option 1_ -## Functional tests - ---- - - -```php,[.highlight: 1, 4-8] -// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php - -public function testOnlyPublishedArticlesAreShown() { - // Given I have a mixture of published and unpublished articles, - // as well as other types of content. - $node1 = $this->drupalCreateNode(['type' => 'page', 'status' => 1]); - $node2 = $this->drupalCreateNode(['type' => 'article', 'status' => 1]); - $node3 = $this->drupalCreateNode(['type' => 'article', 'status' => 0]); - - // When I view the blog page. - $this->drupalGet('/blog'); - - // I should only see the published articles. - $assert = $this->assertSession(); - $assert->pageTextContains($node2->label()); - $assert->pageTextNotContains($node1->label()); - $assert->pageTextNotContains($node3->label()); -} -``` - -^ Different ways to achieve this. This is taking the functional test approach. - ---- - - -```php,[.highlight: 10-12] -// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php - -public function testOnlyPublishedArticlesAreShown() { - // Given I have a mixture of published and unpublished articles, - // as well as other types of content. - $node1 = $this->drupalCreateNode(['type' => 'page', 'status' => 1]); - $node2 = $this->drupalCreateNode(['type' => 'article', 'status' => 1]); - $node3 = $this->drupalCreateNode(['type' => 'article', 'status' => 0]); - - // When I view the blog page. - $this->drupalGet('/blog'); - - // I should only see the published articles. - $assert = $this->assertSession(); - $assert->pageTextContains($node2->label()); - $assert->pageTextNotContains($node1->label()); - $assert->pageTextNotContains($node3->label()); -} -``` - ---- - - -```php, [.highlight: 13-17] -// modules/custom/tdd_blog/tests/src/Functional/BlogPageTest.php - -public function testOnlyPublishedArticlesAreShown() { - // Given I have a mixture of published and unpublished articles, - // as well as other types of content. - $node1 = $this->drupalCreateNode(['type' => 'page', 'status' => 1]); - $node2 = $this->drupalCreateNode(['type' => 'article', 'status' => 1]); - $node3 = $this->drupalCreateNode(['type' => 'article', 'status' => 0]); - - // When I view the blog page. - $this->drupalGet('/blog'); - - // I should only see the published articles. - $assert = $this->assertSession(); - $assert->pageTextContains($node2->label()); - $assert->pageTextNotContains($node1->label()); - $assert->pageTextNotContains($node3->label()); -} -``` - ---- - -### _Option 2_ -## Kernel tests - ---- - - -```php -<?php - -namespace Drupal\Tests\tdd_blog\Kernel; - -use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; -use Drupal\Tests\node\Traits\NodeCreationTrait; - -class BlogPageTest extends EntityKernelTestBase { - - use NodeCreationTrait; - - public static $modules = ['node']; - - public function testOnlyPublishedArticlesAreShown() { - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - } - -} -``` - -^ Kernel test approach -Dropping down a level -No need for the brower, not asserting against HTML -Faster to run - ---- - - -```php, [.highlight: 3-8] -<?php - -namespace Drupal\Tests\tdd_blog\Kernel; - -use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; -use Drupal\Tests\node\Traits\NodeCreationTrait; - -class BlogPageTest extends EntityKernelTestBase { - - use NodeCreationTrait; - - public static $modules = ['node']; - - public function testOnlyPublishedArticlesAreShown() { - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - } - -} -``` - ---- - - -```php, [.highlight: 10] -<?php - -namespace Drupal\Tests\tdd_blog\Kernel; - -use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; -use Drupal\Tests\node\Traits\NodeCreationTrait; - -class BlogPageTest extends EntityKernelTestBase { - - use NodeCreationTrait; - - public static $modules = ['node']; - - public function testOnlyPublishedArticlesAreShown() { - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - } - -} -``` - ---- - - -```php, [.highlight: 14-18] -<?php - -namespace Drupal\Tests\tdd_blog\Kernel; - -use Drupal\KernelTests\Core\Entity\EntityKernelTestBase; -use Drupal\Tests\node\Traits\NodeCreationTrait; - -class BlogPageTest extends EntityKernelTestBase { - - use NodeCreationTrait; - - public static $modules = ['node']; - - public function testOnlyPublishedArticlesAreShown() { - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - } - -} -``` - ---- - - -```[.highlight: 9-16] -docker@cli:/var/www/web$ ../vendor/bin/phpunit -c core modules/custom/tdd_blog/tests/src/Kernel/ -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing modules/custom/tdd_blog/tests/src/Kernel/ -E 1 / 1 (100%) - -Time: 6.22 seconds, Memory: 6.00MB - -There was 1 error: - -1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testOnlyPublishedArticlesAreShown -Error: Call to a member function id() on boolean - -/var/www/web/core/modules/filter/filter.module:212 -/var/www/web/core/modules/node/tests/src/Traits/NodeCreationTrait.php:73 -/var/www/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:13 - -ERRORS! -Tests: 1, Assertions: 2, Errors: 1. -``` - ---- - - -```php, [.highlight: 2] -public function testOnlyPublishedArticlesAreShown() { - $this->installConfig(['filter']); - - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); -} -``` - ---- - - -```php, [.highlight: 8] -public function testOnlyPublishedArticlesAreShown() { - $this->installConfig(['filter']); - - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - - $results = views_get_view_result('blog'); -} -``` - ---- - - -```php, [.highlight: 3] -... - -public static $modules = ['node', 'tdd_blog', 'views']; - -public function testOnlyPublishedArticlesAreShown() { - $this->installConfig(['filter', 'tdd_blog']); - - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - - $results = views_get_view_result('blog'); - - $this->assertCount(1, $results); - $this->assertEquals(2, $results[0]->_entity->id()); -} -``` - ---- - - -```php, [.highlight: 6] -... - -public static $modules = ['node', 'tdd_blog', 'views']; - -public function testOnlyPublishedArticlesAreShown() { - $this->installConfig(['filter', 'tdd_blog']); - - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - - $results = views_get_view_result('blog'); - - $this->assertCount(1, $results); - $this->assertEquals(2, $results[0]->_entity->id()); -} -``` - ---- - - -```php, [.highlight: 8-15] -... - -public static $modules = ['node', 'tdd_blog', 'views']; - -public function testOnlyPublishedArticlesAreShown() { - $this->installConfig(['filter', 'tdd_blog']); - - $this->createNode(['type' => 'page', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 1]); - $this->createNode(['type' => 'article', 'status' => 0]); - - $results = views_get_view_result('blog'); - - $this->assertCount(1, $results); - $this->assertEquals(2, $results[0]->_entity->id()); -} -``` - -^ Assert -Should only be one result, should be node 2 -Node IDs are reset on each test method - ---- - - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/custom/tdd_blog/tests/src/Kernel -F 1 / 1 (100%) - -Time: 2.16 seconds, Memory: 6.00MB - -There was 1 failure: - -1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testOnlyPublishedArticlesAreShown -Failed asserting that actual size 3 matches expected size 1. - -/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:23 - -FAILURES! -Tests: 1, Assertions: 4, Failures: 1. -``` - ---- - - -```[.highlight: 8-13] -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/custom/tdd_blog/tests/src/Kernel -F 1 / 1 (100%) - -Time: 2.16 seconds, Memory: 6.00MB - -There was 1 failure: - -1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testOnlyPublishedArticlesAreShown -Failed asserting that actual size 3 matches expected size 1. - -/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:23 - -FAILURES! -Tests: 1, Assertions: 4, Failures: 1. -``` - ---- - ->- _There are no filters on the view_ -- Add the filters -- Export and save the view - ---- - -```[.highlight: 3-8] -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/custom/tdd_blog/tests/src/Kernel -. 1 / 1 (100%) - -Time: 2.02 seconds, Memory: 6.00MB - -OK (1 test, 6 assertions) -``` - ---- - -[.build-lists: false] - -## _Tasks_ - -- ~~Ensure the blog page exists~~ -- ~~Ensure only published articles are shown~~ -- Ensure the articles are shown in the correct order - ---- - -### _Step 4_ -## Ensure the articles are ordered by date - ---- - - -```php -// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php - -public function testArticlesAreOrderedByDate() { - // Given that I have numerous articles with different post dates. - - // When I go to the blog page. - - // The articles are ordered by post date. -} -``` - ---- - - -```php, [.highlight: 4-9] -// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php - -public function testArticlesAreOrderedByDate() { - // Given that I have numerous articles with different post dates. - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]); - - // When I go to the blog page. - - // The articles are ordered by post date. -} -``` - ---- - -```php -$this->createNode([ - 'type' => 'article', - 'created' => (new \DateTime())->modify('+1 day')->getTimestamp(), -]); -``` - -^ Array of default values - ---- - - -```php, [.highlight: 10-11] -// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php - -public function testArticlesAreOrderedByDate() { - // Given that I have numerous articles with different post dates. - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]); - - // When I go to the blog page. - $results = views_get_view_result('blog'); - - // The articles are ordered by post date. -} -``` - ---- - - -```php, [.highlight:10-15] -// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php - -public function testArticlesAreOrderedByDate() { - // Given that I have numerous articles with different post dates. - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]); - - // When I go to the blog page. - $results = views_get_view_result('blog'); - - $nids = array_map(function(ResultRow $result) { - return $result->_entity->id(); - }, $results); - - // The articles are ordered by post date. -} -``` - ---- - - -```php, [.highlight: 5-9, 17-18] -// modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php - -public function testArticlesAreOrderedByDate() { - // Given that I have numerous articles with different post dates. - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 day')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 month')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+3 days')->getTimestamp()]); - $this->createNode(['type' => 'article', 'created' => (new \DateTime())->modify('+1 hour')->getTimestamp()]); - - // When I go to the blog page. - $results = views_get_view_result('blog'); - - $nids = array_map(function(ResultRow $result) { - return $result->_entity->id(); - }, $results); - - // The articles are ordered by post date. - $this->assertEquals([4, 1, 3, 2], $nids); -} -``` - ---- - - -``` -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/custom/tdd_blog/tests/src/Kernel -F 1 / 1 (100%) - -Time: 1.42 seconds, Memory: 6.00MB - -There was 1 failure: - -1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testArticlesAreOrderedByDate -Failed asserting that two arrays are equal. ---- Expected -+++ Actual -@@ @@ - Array ( -- 0 => 4 -- 1 => 1 -- 2 => 3 -- 3 => 2 -+ 0 => '3' -+ 1 => '2' -+ 2 => '4' -+ 3 => '1' - -/Users/opdavies/Code/drupal-testing-workshop/web/core/tests/Drupal/KernelTests/KernelTestBase.php:1114 -/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:43 - -FAILURES! -Tests: 1, Assertions: 4, Failures: 1. -``` - ---- - -[.text: comic sans] - -```[.highlight: 8-26] -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/custom/tdd_blog/tests/src/Kernel -F 1 / 1 (100%) - -Time: 1.42 seconds, Memory: 6.00MB - -There was 1 failure: - -1) Drupal\Tests\tdd_blog\Kernel\BlogPageTest::testArticlesAreOrderedByDate -Failed asserting that two arrays are equal. ---- Expected -+++ Actual -@@ @@ - Array ( -- 0 => 4 -- 1 => 1 -- 2 => 3 -- 3 => 2 -+ 0 => '3' -+ 1 => '2' -+ 2 => '4' -+ 3 => '1' - -/Users/opdavies/Code/drupal-testing-workshop/web/core/tests/Drupal/KernelTests/KernelTestBase.php:1114 -/Users/opdavies/Code/drupal-testing-workshop/web/modules/custom/tdd_blog/tests/src/Kernel/BlogPageTest.php:43 - -FAILURES! -Tests: 1, Assertions: 4, Failures: 1. -``` - ---- - -- _There is no sort order defined on the view_ -- Add the sort order -- Re-export the view - ---- - -```[.highlight:3-8] -PHPUnit 6.5.8 by Sebastian Bergmann and contributors. - -Testing web/modules/custom/tdd_blog/tests/src/Kernel -. 1 / 1 (100%) - -Time: 1.74 seconds, Memory: 6.00MB - -OK (1 test, 5 assertions) -``` - ---- - -[.build-lists: false] - -## _Tasks_ - -- ~~Ensure the blog page exists~~ -- ~~Ensure only published articles are shown~~ -- ~~Ensure the articles are shown in the correct order~~ - ---- - -[.header: alignment(center)] - -# Questions? - ---- - -[.header: alignment(center)] - -# Thanks -### _@opdavies_ -### _oliverdavies.uk_ diff --git a/drupal-testing-workshop/2018-09-19-microserve/drupal-testing-workshop-microserve2.pdf b/drupal-testing-workshop/2018-09-19-microserve/drupal-testing-workshop-microserve2.pdf deleted file mode 100644 index 6675d9f..0000000 Binary files a/drupal-testing-workshop/2018-09-19-microserve/drupal-testing-workshop-microserve2.pdf and /dev/null differ diff --git a/drupal-testing-workshop/images/files.png b/drupal-testing-workshop/images/files.png deleted file mode 100644 index a23b62a..0000000 Binary files a/drupal-testing-workshop/images/files.png and /dev/null differ diff --git a/drupal-testing-workshop/images/homer-smart.png b/drupal-testing-workshop/images/homer-smart.png deleted file mode 100644 index 50c5705..0000000 Binary files a/drupal-testing-workshop/images/homer-smart.png and /dev/null differ diff --git a/deploying-drupal-ansible-ansistrano/2019-01-22-drupal-bristol/slides.pdf b/instances/deploying-drupal-ansible-ansistrano/2019-01-22-drupal-bristol/slides.pdf similarity index 100% rename from deploying-drupal-ansible-ansistrano/2019-01-22-drupal-bristol/slides.pdf rename to instances/deploying-drupal-ansible-ansistrano/2019-01-22-drupal-bristol/slides.pdf diff --git a/deploying-drupal-fabric/2017-10-20-drupalcamp-dublin/slides.pdf b/instances/deploying-drupal-fabric/2017-10-20-drupalcamp-dublin/slides.pdf similarity index 100% rename from deploying-drupal-fabric/2017-10-20-drupalcamp-dublin/slides.pdf rename to instances/deploying-drupal-fabric/2017-10-20-drupalcamp-dublin/slides.pdf diff --git a/deploying-drupal-fabric/2017-10-26-drupal-somerset/slides.pdf b/instances/deploying-drupal-fabric/2017-10-26-drupal-somerset/slides.pdf similarity index 100% rename from deploying-drupal-fabric/2017-10-26-drupal-somerset/slides.pdf rename to instances/deploying-drupal-fabric/2017-10-26-drupal-somerset/slides.pdf diff --git a/deploying-php-fabric/2017-04-20-nomad-php/slides.pdf b/instances/deploying-php-fabric/2017-04-20-nomad-php/slides.pdf similarity index 100% rename from deploying-php-fabric/2017-04-20-nomad-php/slides.pdf rename to instances/deploying-php-fabric/2017-04-20-nomad-php/slides.pdf diff --git a/deploying-php-fabric/2017-09-13-phpsw/slides.pdf b/instances/deploying-php-fabric/2017-09-13-phpsw/slides.pdf similarity index 100% rename from deploying-php-fabric/2017-09-13-phpsw/slides.pdf rename to instances/deploying-php-fabric/2017-09-13-phpsw/slides.pdf diff --git a/deploying-php-fabric/2017-10-01-phpnw/slides.pdf b/instances/deploying-php-fabric/2017-10-01-phpnw/slides.pdf similarity index 100% rename from deploying-php-fabric/2017-10-01-phpnw/slides.pdf rename to instances/deploying-php-fabric/2017-10-01-phpnw/slides.pdf diff --git a/drupal-8/2015-04-08-phpsw/slides.pdf b/instances/drupal-8/2015-04-08-phpsw/slides.pdf similarity index 100% rename from drupal-8/2015-04-08-phpsw/slides.pdf rename to instances/drupal-8/2015-04-08-phpsw/slides.pdf diff --git a/drupal-rejoining-php-herd/2016-06-11-php-south-coast/slides.pdf b/instances/drupal-rejoining-php-herd/2016-06-11-php-south-coast/slides.pdf similarity index 100% rename from drupal-rejoining-php-herd/2016-06-11-php-south-coast/slides.pdf rename to instances/drupal-rejoining-php-herd/2016-06-11-php-south-coast/slides.pdf diff --git a/drupal-testing-workshop/2018-06-28-drupal-bristol/slides.pdf b/instances/drupal-testing-workshop/2018-06-28-drupal-bristol/slides.pdf similarity index 100% rename from drupal-testing-workshop/2018-06-28-drupal-bristol/slides.pdf rename to instances/drupal-testing-workshop/2018-06-28-drupal-bristol/slides.pdf diff --git a/drupal-testing-workshop/2018-09-19-microserve/drupal-testing-workshop-microserve.pdf b/instances/drupal-testing-workshop/2018-09-19-microserve/slides.pdf similarity index 100% rename from drupal-testing-workshop/2018-09-19-microserve/drupal-testing-workshop-microserve.pdf rename to instances/drupal-testing-workshop/2018-09-19-microserve/slides.pdf diff --git a/drupal-vm-generator/2016-04-02-drupal-bristol/slides.pdf b/instances/drupal-vm-generator/2016-04-02-drupal-bristol/slides.pdf similarity index 100% rename from drupal-vm-generator/2016-04-02-drupal-bristol/slides.pdf rename to instances/drupal-vm-generator/2016-04-02-drupal-bristol/slides.pdf diff --git a/drupal-vm-symfony-console/2016-07-23-drupalcamp-bristol/slides.pdf b/instances/drupal-vm-symfony-console/2016-07-23-drupalcamp-bristol/slides.pdf similarity index 100% rename from drupal-vm-symfony-console/2016-07-23-drupalcamp-bristol/slides.pdf rename to instances/drupal-vm-symfony-console/2016-07-23-drupalcamp-bristol/slides.pdf diff --git a/drush-make-drupal-bristol/2014-07-02-drupal-bristol/slides.pdf b/instances/drush-make-drupal-bristol/2014-07-02-drupal-bristol/slides.pdf similarity index 100% rename from drush-make-drupal-bristol/2014-07-02-drupal-bristol/slides.pdf rename to instances/drush-make-drupal-bristol/2014-07-02-drupal-bristol/slides.pdf diff --git a/getting-started-drupal-8-module-development/2016-03-05-drupalcamp-london/slides.pdf b/instances/getting-started-drupal-8-module-development/2016-03-05-drupalcamp-london/slides.pdf similarity index 100% rename from getting-started-drupal-8-module-development/2016-03-05-drupalcamp-london/slides.pdf rename to instances/getting-started-drupal-8-module-development/2016-03-05-drupalcamp-london/slides.pdf diff --git a/getting-your-data-into-drupal-8/2017-03-04-drupalcamp-london/slides.pdf b/instances/getting-your-data-into-drupal-8/2017-03-04-drupalcamp-london/slides.pdf similarity index 100% rename from getting-your-data-into-drupal-8/2017-03-04-drupalcamp-london/slides.pdf rename to instances/getting-your-data-into-drupal-8/2017-03-04-drupalcamp-london/slides.pdf diff --git a/getting-your-data-into-drupal-8/todo.md b/instances/getting-your-data-into-drupal-8/todo.md similarity index 100% rename from getting-your-data-into-drupal-8/todo.md rename to instances/getting-your-data-into-drupal-8/todo.md diff --git a/git-flow/2014-03-01-drupalcamp-london/slides.pdf b/instances/git-flow/2014-03-01-drupalcamp-london/slides.pdf similarity index 100% rename from git-flow/2014-03-01-drupalcamp-london/slides.pdf rename to instances/git-flow/2014-03-01-drupalcamp-london/slides.pdf diff --git a/goodbye-drush-make-hello-composer/2017-11-17-drupal-bristol/slides.pdf b/instances/goodbye-drush-make-hello-composer/2017-11-17-drupal-bristol/slides.pdf similarity index 100% rename from goodbye-drush-make-hello-composer/2017-11-17-drupal-bristol/slides.pdf rename to instances/goodbye-drush-make-hello-composer/2017-11-17-drupal-bristol/slides.pdf diff --git a/goodbye-drush-make-hello-composer/2018-02-16-php-uk/slides3.pdf b/instances/goodbye-drush-make-hello-composer/2018-02-16-php-uk/slides.pdf similarity index 100% rename from goodbye-drush-make-hello-composer/2018-02-16-php-uk/slides3.pdf rename to instances/goodbye-drush-make-hello-composer/2018-02-16-php-uk/slides.pdf diff --git a/having-fun-drupal-8-drupalorg-api/2018-04-18-drupal-bristol/slides.pdf b/instances/having-fun-drupal-8-drupalorg-api/2018-04-18-drupal-bristol/slides.pdf similarity index 100% rename from having-fun-drupal-8-drupalorg-api/2018-04-18-drupal-bristol/slides.pdf rename to instances/having-fun-drupal-8-drupalorg-api/2018-04-18-drupal-bristol/slides.pdf diff --git a/having-fun-drupal-8-drupalorg-api/2019-03-03-drupalcamp-london/slides.pdf b/instances/having-fun-drupal-8-drupalorg-api/2019-03-03-drupalcamp-london/slides.pdf similarity index 100% rename from having-fun-drupal-8-drupalorg-api/2019-03-03-drupalcamp-london/slides.pdf rename to instances/having-fun-drupal-8-drupalorg-api/2019-03-03-drupalcamp-london/slides.pdf diff --git a/it-all-started-with-a-patch/2017-02-08-phpsw/slides.pdf b/instances/it-all-started-with-a-patch/2017-02-08-phpsw/slides.pdf similarity index 100% rename from it-all-started-with-a-patch/2017-02-08-phpsw/slides.pdf rename to instances/it-all-started-with-a-patch/2017-02-08-phpsw/slides.pdf diff --git a/modern-drupal-development-composer/2016-11-09-phpsw/slides.pdf b/instances/modern-drupal-development-composer/2016-11-09-phpsw/slides.pdf similarity index 100% rename from modern-drupal-development-composer/2016-11-09-phpsw/slides.pdf rename to instances/modern-drupal-development-composer/2016-11-09-phpsw/slides.pdf diff --git a/static-websites-sculpin/2015-10-14-phpsw/slides.pdf b/instances/static-websites-sculpin/2015-10-14-phpsw/slides.pdf similarity index 100% rename from static-websites-sculpin/2015-10-14-phpsw/slides.pdf rename to instances/static-websites-sculpin/2015-10-14-phpsw/slides.pdf diff --git a/taking-flight-with-tailwind-css/2018-01-17-drupal-bristol/slides.pdf b/instances/taking-flight-with-tailwind-css/2018-01-17-drupal-bristol/slides.pdf similarity index 100% rename from taking-flight-with-tailwind-css/2018-01-17-drupal-bristol/slides.pdf rename to instances/taking-flight-with-tailwind-css/2018-01-17-drupal-bristol/slides.pdf diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.pdf b/instances/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.pdf similarity index 100% rename from taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.pdf rename to instances/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.pdf diff --git a/taking-flight-with-tailwind-css/2019-05-18-wordcamp-bristol/slides.pdf b/instances/taking-flight-with-tailwind-css/2019-05-18-wordcamp-bristol/slides.pdf similarity index 100% rename from taking-flight-with-tailwind-css/2019-05-18-wordcamp-bristol/slides.pdf rename to instances/taking-flight-with-tailwind-css/2019-05-18-wordcamp-bristol/slides.pdf diff --git a/test-drive-twig-sculpin/2015-07-25-drupalcamp-north/slides.pdf b/instances/test-drive-twig-sculpin/2015-07-25-drupalcamp-north/slides.pdf similarity index 100% rename from test-drive-twig-sculpin/2015-07-25-drupalcamp-north/slides.pdf rename to instances/test-drive-twig-sculpin/2015-07-25-drupalcamp-north/slides.pdf diff --git a/tdd-test-driven-drupal/2017-03-04-drupalcamp-london/slides.pdf b/instances/test-driven-drupal/2017-03-04-drupalcamp-london/slides.pdf similarity index 100% rename from tdd-test-driven-drupal/2017-03-04-drupalcamp-london/slides.pdf rename to instances/test-driven-drupal/2017-03-04-drupalcamp-london/slides.pdf diff --git a/tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.pdf b/instances/test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.pdf similarity index 100% rename from tdd-test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.pdf rename to instances/test-driven-drupal/2017-10-21-drupalcamp-dublin/slides.pdf diff --git a/tdd-test-driven-drupal/2017-11-22-drupal-bristol/slides.pdf b/instances/test-driven-drupal/2017-11-22-drupal-bristol/slides.pdf similarity index 100% rename from tdd-test-driven-drupal/2017-11-22-drupal-bristol/slides.pdf rename to instances/test-driven-drupal/2017-11-22-drupal-bristol/slides.pdf diff --git a/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides.pdf b/instances/test-driven-drupal/2018-06-14-drupal-somerset/slides.pdf similarity index 100% rename from tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides.pdf rename to instances/test-driven-drupal/2018-06-14-drupal-somerset/slides.pdf diff --git a/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/slides.pdf b/instances/test-driven-drupal/2018-07-05-drupal-dev-days/slides.pdf similarity index 100% rename from tdd-test-driven-drupal/2018-07-05-drupal-dev-days/slides.pdf rename to instances/test-driven-drupal/2018-07-05-drupal-dev-days/slides.pdf diff --git a/tdd-test-driven-drupal/2019-03-02-drupalcamp-london/slides.pdf b/instances/test-driven-drupal/2019-03-02-drupalcamp-london/slides.pdf similarity index 100% rename from tdd-test-driven-drupal/2019-03-02-drupalcamp-london/slides.pdf rename to instances/test-driven-drupal/2019-03-02-drupalcamp-london/slides.pdf diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.pdf b/instances/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.pdf similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.pdf rename to instances/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.pdf diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides2.pdf b/instances/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides.pdf similarity index 100% rename from using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides2.pdf rename to instances/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides.pdf diff --git a/deploying-drupal-ansible-ansistrano/images/ansible.png b/source/deploying-drupal-ansible-ansistrano/images/ansible.png similarity index 100% rename from deploying-drupal-ansible-ansistrano/images/ansible.png rename to source/deploying-drupal-ansible-ansistrano/images/ansible.png diff --git a/deploying-drupal-ansible-ansistrano/images/ansistrano-flow.png b/source/deploying-drupal-ansible-ansistrano/images/ansistrano-flow.png similarity index 100% rename from deploying-drupal-ansible-ansistrano/images/ansistrano-flow.png rename to source/deploying-drupal-ansible-ansistrano/images/ansistrano-flow.png diff --git a/deploying-drupal-ansible-ansistrano/images/ansistrano.png b/source/deploying-drupal-ansible-ansistrano/images/ansistrano.png similarity index 100% rename from deploying-drupal-ansible-ansistrano/images/ansistrano.png rename to source/deploying-drupal-ansible-ansistrano/images/ansistrano.png diff --git a/deploying-drupal-ansible-ansistrano/images/composer.png b/source/deploying-drupal-ansible-ansistrano/images/composer.png similarity index 100% rename from deploying-drupal-ansible-ansistrano/images/composer.png rename to source/deploying-drupal-ansible-ansistrano/images/composer.png diff --git a/deploying-drupal-ansible-ansistrano/images/druplicon.png b/source/deploying-drupal-ansible-ansistrano/images/druplicon.png similarity index 100% rename from deploying-drupal-ansible-ansistrano/images/druplicon.png rename to source/deploying-drupal-ansible-ansistrano/images/druplicon.png diff --git a/deploying-drupal-ansible-ansistrano/images/vagrant.png b/source/deploying-drupal-ansible-ansistrano/images/vagrant.png similarity index 100% rename from deploying-drupal-ansible-ansistrano/images/vagrant.png rename to source/deploying-drupal-ansible-ansistrano/images/vagrant.png diff --git a/deploying-drupal-ansible-ansistrano/slides.md b/source/deploying-drupal-ansible-ansistrano/slides.md similarity index 100% rename from deploying-drupal-ansible-ansistrano/slides.md rename to source/deploying-drupal-ansible-ansistrano/slides.md diff --git a/drupal-testing-workshop/images/2c6qi8.jpg b/source/drupal-testing-workshop/images/2c6qi8.jpg similarity index 100% rename from drupal-testing-workshop/images/2c6qi8.jpg rename to source/drupal-testing-workshop/images/2c6qi8.jpg diff --git a/drupal-testing-workshop/images/appnovation.png b/source/drupal-testing-workshop/images/appnovation.png similarity index 100% rename from drupal-testing-workshop/images/appnovation.png rename to source/drupal-testing-workshop/images/appnovation.png diff --git a/drupal-testing-workshop/images/broadbean.png b/source/drupal-testing-workshop/images/broadbean.png similarity index 100% rename from drupal-testing-workshop/images/broadbean.png rename to source/drupal-testing-workshop/images/broadbean.png diff --git a/drupal-testing-workshop/images/collection-class-1.png b/source/drupal-testing-workshop/images/collection-class-1.png similarity index 100% rename from drupal-testing-workshop/images/collection-class-1.png rename to source/drupal-testing-workshop/images/collection-class-1.png diff --git a/drupal-testing-workshop/images/collection-class-2.png b/source/drupal-testing-workshop/images/collection-class-2.png similarity index 100% rename from drupal-testing-workshop/images/collection-class-2.png rename to source/drupal-testing-workshop/images/collection-class-2.png diff --git a/drupal-testing-workshop/images/d8-simpletest-1.png b/source/drupal-testing-workshop/images/d8-simpletest-1.png similarity index 100% rename from drupal-testing-workshop/images/d8-simpletest-1.png rename to source/drupal-testing-workshop/images/d8-simpletest-1.png diff --git a/drupal-testing-workshop/images/d8-simpletest-2.png b/source/drupal-testing-workshop/images/d8-simpletest-2.png similarity index 100% rename from drupal-testing-workshop/images/d8-simpletest-2.png rename to source/drupal-testing-workshop/images/d8-simpletest-2.png diff --git a/drupal-testing-workshop/images/d8-simpletest-3.png b/source/drupal-testing-workshop/images/d8-simpletest-3.png similarity index 100% rename from drupal-testing-workshop/images/d8-simpletest-3.png rename to source/drupal-testing-workshop/images/d8-simpletest-3.png diff --git a/drupal-testing-workshop/images/d8-simpletest-4.png b/source/drupal-testing-workshop/images/d8-simpletest-4.png similarity index 100% rename from drupal-testing-workshop/images/d8-simpletest-4.png rename to source/drupal-testing-workshop/images/d8-simpletest-4.png diff --git a/drupal-testing-workshop/images/d8-simpletest-5.png b/source/drupal-testing-workshop/images/d8-simpletest-5.png similarity index 100% rename from drupal-testing-workshop/images/d8-simpletest-5.png rename to source/drupal-testing-workshop/images/d8-simpletest-5.png diff --git a/drupal-testing-workshop/images/d8-simpletest-6.png b/source/drupal-testing-workshop/images/d8-simpletest-6.png similarity index 100% rename from drupal-testing-workshop/images/d8-simpletest-6.png rename to source/drupal-testing-workshop/images/d8-simpletest-6.png diff --git a/drupal-testing-workshop/images/d8-simpletest-7.png b/source/drupal-testing-workshop/images/d8-simpletest-7.png similarity index 100% rename from drupal-testing-workshop/images/d8-simpletest-7.png rename to source/drupal-testing-workshop/images/d8-simpletest-7.png diff --git a/drupal-testing-workshop/images/dcbristol.png b/source/drupal-testing-workshop/images/dcbristol.png similarity index 100% rename from drupal-testing-workshop/images/dcbristol.png rename to source/drupal-testing-workshop/images/dcbristol.png diff --git a/deploying-php-fabric/images/deploy-all-the-things.jpg b/source/drupal-testing-workshop/images/deploy-all-the-things.jpg similarity index 100% rename from deploying-php-fabric/images/deploy-all-the-things.jpg rename to source/drupal-testing-workshop/images/deploy-all-the-things.jpg diff --git a/deploying-drupal-fabric/images/files.png b/source/drupal-testing-workshop/images/files.png similarity index 100% rename from deploying-drupal-fabric/images/files.png rename to source/drupal-testing-workshop/images/files.png diff --git a/deploying-drupal-fabric/images/homer-smart.png b/source/drupal-testing-workshop/images/homer-smart.png similarity index 100% rename from deploying-drupal-fabric/images/homer-smart.png rename to source/drupal-testing-workshop/images/homer-smart.png diff --git a/drupal-testing-workshop/images/kernel-tests.png b/source/drupal-testing-workshop/images/kernel-tests.png similarity index 100% rename from drupal-testing-workshop/images/kernel-tests.png rename to source/drupal-testing-workshop/images/kernel-tests.png diff --git a/drupal-testing-workshop/images/matt-stauffer-tweet.png b/source/drupal-testing-workshop/images/matt-stauffer-tweet.png similarity index 100% rename from drupal-testing-workshop/images/matt-stauffer-tweet.png rename to source/drupal-testing-workshop/images/matt-stauffer-tweet.png diff --git a/drupal-testing-workshop/images/me.jpg b/source/drupal-testing-workshop/images/me.jpg similarity index 100% rename from drupal-testing-workshop/images/me.jpg rename to source/drupal-testing-workshop/images/me.jpg diff --git a/drupal-testing-workshop/images/phpstorm-integration.png b/source/drupal-testing-workshop/images/phpstorm-integration.png similarity index 100% rename from drupal-testing-workshop/images/phpstorm-integration.png rename to source/drupal-testing-workshop/images/phpstorm-integration.png diff --git a/drupal-testing-workshop/images/phpunit.png b/source/drupal-testing-workshop/images/phpunit.png similarity index 100% rename from drupal-testing-workshop/images/phpunit.png rename to source/drupal-testing-workshop/images/phpunit.png diff --git a/drupal-testing-workshop/images/simpletest-1.png b/source/drupal-testing-workshop/images/simpletest-1.png similarity index 100% rename from drupal-testing-workshop/images/simpletest-1.png rename to source/drupal-testing-workshop/images/simpletest-1.png diff --git a/drupal-testing-workshop/images/simpletest-2.png b/source/drupal-testing-workshop/images/simpletest-2.png similarity index 100% rename from drupal-testing-workshop/images/simpletest-2.png rename to source/drupal-testing-workshop/images/simpletest-2.png diff --git a/drupal-testing-workshop/images/simpletest-3.png b/source/drupal-testing-workshop/images/simpletest-3.png similarity index 100% rename from drupal-testing-workshop/images/simpletest-3.png rename to source/drupal-testing-workshop/images/simpletest-3.png diff --git a/drupal-testing-workshop/images/simpletest-4.png b/source/drupal-testing-workshop/images/simpletest-4.png similarity index 100% rename from drupal-testing-workshop/images/simpletest-4.png rename to source/drupal-testing-workshop/images/simpletest-4.png diff --git a/drupal-testing-workshop/images/simpletest.png b/source/drupal-testing-workshop/images/simpletest.png similarity index 100% rename from drupal-testing-workshop/images/simpletest.png rename to source/drupal-testing-workshop/images/simpletest.png diff --git a/drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-1.png b/source/drupal-testing-workshop/images/tdd-blog-1.png similarity index 100% rename from drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-1.png rename to source/drupal-testing-workshop/images/tdd-blog-1.png diff --git a/drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-2.png b/source/drupal-testing-workshop/images/tdd-blog-2.png similarity index 100% rename from drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-2.png rename to source/drupal-testing-workshop/images/tdd-blog-2.png diff --git a/drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-3.png b/source/drupal-testing-workshop/images/tdd-blog-3.png similarity index 100% rename from drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-3.png rename to source/drupal-testing-workshop/images/tdd-blog-3.png diff --git a/drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-4.png b/source/drupal-testing-workshop/images/tdd-blog-4.png similarity index 100% rename from drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-4.png rename to source/drupal-testing-workshop/images/tdd-blog-4.png diff --git a/drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-5.png b/source/drupal-testing-workshop/images/tdd-blog-5.png similarity index 100% rename from drupal-testing-workshop/2018-09-19-microserve/images/tdd-blog-5.png rename to source/drupal-testing-workshop/images/tdd-blog-5.png diff --git a/drupal-testing-workshop/images/tdd-circle-of-life.png b/source/drupal-testing-workshop/images/tdd-circle-of-life.png similarity index 100% rename from drupal-testing-workshop/images/tdd-circle-of-life.png rename to source/drupal-testing-workshop/images/tdd-circle-of-life.png diff --git a/drupal-testing-workshop/images/tdd-loop.png b/source/drupal-testing-workshop/images/tdd-loop.png similarity index 100% rename from drupal-testing-workshop/images/tdd-loop.png rename to source/drupal-testing-workshop/images/tdd-loop.png diff --git a/drupal-testing-workshop/images/timmillwood-ono.png b/source/drupal-testing-workshop/images/timmillwood-ono.png similarity index 100% rename from drupal-testing-workshop/images/timmillwood-ono.png rename to source/drupal-testing-workshop/images/timmillwood-ono.png diff --git a/drupal-testing-workshop/images/title.png b/source/drupal-testing-workshop/images/title.png similarity index 100% rename from drupal-testing-workshop/images/title.png rename to source/drupal-testing-workshop/images/title.png diff --git a/drupal-testing-workshop/images/toggle-optional-fields-1.png b/source/drupal-testing-workshop/images/toggle-optional-fields-1.png similarity index 100% rename from drupal-testing-workshop/images/toggle-optional-fields-1.png rename to source/drupal-testing-workshop/images/toggle-optional-fields-1.png diff --git a/drupal-testing-workshop/images/toggle-optional-fields-2.png b/source/drupal-testing-workshop/images/toggle-optional-fields-2.png similarity index 100% rename from drupal-testing-workshop/images/toggle-optional-fields-2.png rename to source/drupal-testing-workshop/images/toggle-optional-fields-2.png diff --git a/drupal-testing-workshop/images/toggle-optional-fields-3.png b/source/drupal-testing-workshop/images/toggle-optional-fields-3.png similarity index 100% rename from drupal-testing-workshop/images/toggle-optional-fields-3.png rename to source/drupal-testing-workshop/images/toggle-optional-fields-3.png diff --git a/drupal-testing-workshop/images/toggle-optional-fields-button.png b/source/drupal-testing-workshop/images/toggle-optional-fields-button.png similarity index 100% rename from drupal-testing-workshop/images/toggle-optional-fields-button.png rename to source/drupal-testing-workshop/images/toggle-optional-fields-button.png diff --git a/drupal-testing-workshop/images/when-you-do-things-right.jpg b/source/drupal-testing-workshop/images/when-you-do-things-right.jpg similarity index 100% rename from drupal-testing-workshop/images/when-you-do-things-right.jpg rename to source/drupal-testing-workshop/images/when-you-do-things-right.jpg diff --git a/drupal-testing-workshop/2018-09-19-microserve/slides.md b/source/drupal-testing-workshop/slides.md similarity index 100% rename from drupal-testing-workshop/2018-09-19-microserve/slides.md rename to source/drupal-testing-workshop/slides.md diff --git a/having-fun-drupal-8-drupalorg-api/images/api-page.png b/source/having-fun-drupal-8-drupalorg-api/images/api-page.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/api-page.png rename to source/having-fun-drupal-8-drupalorg-api/images/api-page.png diff --git a/having-fun-drupal-8-drupalorg-api/images/api-result.png b/source/having-fun-drupal-8-drupalorg-api/images/api-result.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/api-result.png rename to source/having-fun-drupal-8-drupalorg-api/images/api-result.png diff --git a/having-fun-drupal-8-drupalorg-api/images/do-projects-page.png b/source/having-fun-drupal-8-drupalorg-api/images/do-projects-page.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/do-projects-page.png rename to source/having-fun-drupal-8-drupalorg-api/images/do-projects-page.png diff --git a/having-fun-drupal-8-drupalorg-api/images/do-projects-settings.png b/source/having-fun-drupal-8-drupalorg-api/images/do-projects-settings.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/do-projects-settings.png rename to source/having-fun-drupal-8-drupalorg-api/images/do-projects-settings.png diff --git a/having-fun-drupal-8-drupalorg-api/images/drupalversary.png b/source/having-fun-drupal-8-drupalorg-api/images/drupalversary.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/drupalversary.png rename to source/having-fun-drupal-8-drupalorg-api/images/drupalversary.png diff --git a/having-fun-drupal-8-drupalorg-api/images/library-github.png b/source/having-fun-drupal-8-drupalorg-api/images/library-github.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/library-github.png rename to source/having-fun-drupal-8-drupalorg-api/images/library-github.png diff --git a/having-fun-drupal-8-drupalorg-api/images/library-packagist.png b/source/having-fun-drupal-8-drupalorg-api/images/library-packagist.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/library-packagist.png rename to source/having-fun-drupal-8-drupalorg-api/images/library-packagist.png diff --git a/having-fun-drupal-8-drupalorg-api/images/library-travis.png b/source/having-fun-drupal-8-drupalorg-api/images/library-travis.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/library-travis.png rename to source/having-fun-drupal-8-drupalorg-api/images/library-travis.png diff --git a/having-fun-drupal-8-drupalorg-api/images/microserve-website.png b/source/having-fun-drupal-8-drupalorg-api/images/microserve-website.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/microserve-website.png rename to source/having-fun-drupal-8-drupalorg-api/images/microserve-website.png diff --git a/having-fun-drupal-8-drupalorg-api/images/spatie-website.png b/source/having-fun-drupal-8-drupalorg-api/images/spatie-website.png similarity index 100% rename from having-fun-drupal-8-drupalorg-api/images/spatie-website.png rename to source/having-fun-drupal-8-drupalorg-api/images/spatie-website.png diff --git a/having-fun-drupal-8-drupalorg-api/notes.md b/source/having-fun-drupal-8-drupalorg-api/notes.md similarity index 100% rename from having-fun-drupal-8-drupalorg-api/notes.md rename to source/having-fun-drupal-8-drupalorg-api/notes.md diff --git a/having-fun-drupal-8-drupalorg-api/slides.txt b/source/having-fun-drupal-8-drupalorg-api/slides.txt similarity index 100% rename from having-fun-drupal-8-drupalorg-api/slides.txt rename to source/having-fun-drupal-8-drupalorg-api/slides.txt diff --git a/images/me-microserve.jpg b/source/images/me-microserve.jpg similarity index 100% rename from images/me-microserve.jpg rename to source/images/me-microserve.jpg diff --git a/images/me-phpnw.png b/source/images/me-phpnw.png similarity index 100% rename from images/me-phpnw.png rename to source/images/me-phpnw.png diff --git a/images/me-precedent.jpg b/source/images/me-precedent.jpg similarity index 100% rename from images/me-precedent.jpg rename to source/images/me-precedent.jpg diff --git a/images/microserve-light.png b/source/images/microserve-light.png similarity index 100% rename from images/microserve-light.png rename to source/images/microserve-light.png diff --git a/taking-flight-with-tailwind-css/images/example/0.png b/source/taking-flight-with-tailwind-css/images/example/0.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/0.png rename to source/taking-flight-with-tailwind-css/images/example/0.png diff --git a/taking-flight-with-tailwind-css/images/example/1.png b/source/taking-flight-with-tailwind-css/images/example/1.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/1.png rename to source/taking-flight-with-tailwind-css/images/example/1.png diff --git a/taking-flight-with-tailwind-css/images/example/10.png b/source/taking-flight-with-tailwind-css/images/example/10.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/10.png rename to source/taking-flight-with-tailwind-css/images/example/10.png diff --git a/taking-flight-with-tailwind-css/images/example/11.png b/source/taking-flight-with-tailwind-css/images/example/11.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/11.png rename to source/taking-flight-with-tailwind-css/images/example/11.png diff --git a/taking-flight-with-tailwind-css/images/example/12.png b/source/taking-flight-with-tailwind-css/images/example/12.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/12.png rename to source/taking-flight-with-tailwind-css/images/example/12.png diff --git a/taking-flight-with-tailwind-css/images/example/13.png b/source/taking-flight-with-tailwind-css/images/example/13.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/13.png rename to source/taking-flight-with-tailwind-css/images/example/13.png diff --git a/taking-flight-with-tailwind-css/images/example/14.png b/source/taking-flight-with-tailwind-css/images/example/14.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/14.png rename to source/taking-flight-with-tailwind-css/images/example/14.png diff --git a/taking-flight-with-tailwind-css/images/example/2.png b/source/taking-flight-with-tailwind-css/images/example/2.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/2.png rename to source/taking-flight-with-tailwind-css/images/example/2.png diff --git a/taking-flight-with-tailwind-css/images/example/3.png b/source/taking-flight-with-tailwind-css/images/example/3.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/3.png rename to source/taking-flight-with-tailwind-css/images/example/3.png diff --git a/taking-flight-with-tailwind-css/images/example/4.png b/source/taking-flight-with-tailwind-css/images/example/4.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/4.png rename to source/taking-flight-with-tailwind-css/images/example/4.png diff --git a/taking-flight-with-tailwind-css/images/example/5.png b/source/taking-flight-with-tailwind-css/images/example/5.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/5.png rename to source/taking-flight-with-tailwind-css/images/example/5.png diff --git a/taking-flight-with-tailwind-css/images/example/6.png b/source/taking-flight-with-tailwind-css/images/example/6.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/6.png rename to source/taking-flight-with-tailwind-css/images/example/6.png diff --git a/taking-flight-with-tailwind-css/images/example/7.png b/source/taking-flight-with-tailwind-css/images/example/7.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/7.png rename to source/taking-flight-with-tailwind-css/images/example/7.png diff --git a/taking-flight-with-tailwind-css/images/example/8.png b/source/taking-flight-with-tailwind-css/images/example/8.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/8.png rename to source/taking-flight-with-tailwind-css/images/example/8.png diff --git a/taking-flight-with-tailwind-css/images/example/9.png b/source/taking-flight-with-tailwind-css/images/example/9.png similarity index 100% rename from taking-flight-with-tailwind-css/images/example/9.png rename to source/taking-flight-with-tailwind-css/images/example/9.png diff --git a/taking-flight-with-tailwind-css/images/screenshot-laravel-nova.png b/source/taking-flight-with-tailwind-css/images/screenshot-laravel-nova.png similarity index 100% rename from taking-flight-with-tailwind-css/images/screenshot-laravel-nova.png rename to source/taking-flight-with-tailwind-css/images/screenshot-laravel-nova.png diff --git a/taking-flight-with-tailwind-css/images/screenshot-rebuilding-bartik.png b/source/taking-flight-with-tailwind-css/images/screenshot-rebuilding-bartik.png similarity index 100% rename from taking-flight-with-tailwind-css/images/screenshot-rebuilding-bartik.png rename to source/taking-flight-with-tailwind-css/images/screenshot-rebuilding-bartik.png diff --git a/taking-flight-with-tailwind-css/images/screenshot-send-firefox.png b/source/taking-flight-with-tailwind-css/images/screenshot-send-firefox.png similarity index 100% rename from taking-flight-with-tailwind-css/images/screenshot-send-firefox.png rename to source/taking-flight-with-tailwind-css/images/screenshot-send-firefox.png diff --git a/taking-flight-with-tailwind-css/images/tailwind.svg b/source/taking-flight-with-tailwind-css/images/tailwind.svg similarity index 100% rename from taking-flight-with-tailwind-css/images/tailwind.svg rename to source/taking-flight-with-tailwind-css/images/tailwind.svg diff --git a/taking-flight-with-tailwind-css/images/techs.png b/source/taking-flight-with-tailwind-css/images/techs.png similarity index 100% rename from taking-flight-with-tailwind-css/images/techs.png rename to source/taking-flight-with-tailwind-css/images/techs.png diff --git a/taking-flight-with-tailwind-css/taking-flight-tailwind-css.md b/source/taking-flight-with-tailwind-css/taking-flight-tailwind-css.md similarity index 100% rename from taking-flight-with-tailwind-css/taking-flight-tailwind-css.md rename to source/taking-flight-with-tailwind-css/taking-flight-tailwind-css.md diff --git a/tdd-test-driven-drupal/images/2c6qi8.jpg b/source/test-driven-drupal/images/2c6qi8.jpg similarity index 100% rename from tdd-test-driven-drupal/images/2c6qi8.jpg rename to source/test-driven-drupal/images/2c6qi8.jpg diff --git a/tdd-test-driven-drupal/images/afilina-tweet.png b/source/test-driven-drupal/images/afilina-tweet.png similarity index 100% rename from tdd-test-driven-drupal/images/afilina-tweet.png rename to source/test-driven-drupal/images/afilina-tweet.png diff --git a/tdd-test-driven-drupal/images/appnovation.png b/source/test-driven-drupal/images/appnovation.png similarity index 100% rename from tdd-test-driven-drupal/images/appnovation.png rename to source/test-driven-drupal/images/appnovation.png diff --git a/tdd-test-driven-drupal/images/broadbean-drupal-flow-1.png b/source/test-driven-drupal/images/broadbean-drupal-flow-1.png similarity index 100% rename from tdd-test-driven-drupal/images/broadbean-drupal-flow-1.png rename to source/test-driven-drupal/images/broadbean-drupal-flow-1.png diff --git a/tdd-test-driven-drupal/images/broadbean-drupal-flow-2.png b/source/test-driven-drupal/images/broadbean-drupal-flow-2.png similarity index 100% rename from tdd-test-driven-drupal/images/broadbean-drupal-flow-2.png rename to source/test-driven-drupal/images/broadbean-drupal-flow-2.png diff --git a/tdd-test-driven-drupal/images/broadbean.png b/source/test-driven-drupal/images/broadbean.png similarity index 100% rename from tdd-test-driven-drupal/images/broadbean.png rename to source/test-driven-drupal/images/broadbean.png diff --git a/tdd-test-driven-drupal/images/collection-class-1.png b/source/test-driven-drupal/images/collection-class-1.png similarity index 100% rename from tdd-test-driven-drupal/images/collection-class-1.png rename to source/test-driven-drupal/images/collection-class-1.png diff --git a/tdd-test-driven-drupal/images/collection-class-2.png b/source/test-driven-drupal/images/collection-class-2.png similarity index 100% rename from tdd-test-driven-drupal/images/collection-class-2.png rename to source/test-driven-drupal/images/collection-class-2.png diff --git a/tdd-test-driven-drupal/images/d8-simpletest-1.png b/source/test-driven-drupal/images/d8-simpletest-1.png similarity index 100% rename from tdd-test-driven-drupal/images/d8-simpletest-1.png rename to source/test-driven-drupal/images/d8-simpletest-1.png diff --git a/tdd-test-driven-drupal/images/d8-simpletest-2.png b/source/test-driven-drupal/images/d8-simpletest-2.png similarity index 100% rename from tdd-test-driven-drupal/images/d8-simpletest-2.png rename to source/test-driven-drupal/images/d8-simpletest-2.png diff --git a/tdd-test-driven-drupal/images/d8-simpletest-3.png b/source/test-driven-drupal/images/d8-simpletest-3.png similarity index 100% rename from tdd-test-driven-drupal/images/d8-simpletest-3.png rename to source/test-driven-drupal/images/d8-simpletest-3.png diff --git a/tdd-test-driven-drupal/images/d8-simpletest-4.png b/source/test-driven-drupal/images/d8-simpletest-4.png similarity index 100% rename from tdd-test-driven-drupal/images/d8-simpletest-4.png rename to source/test-driven-drupal/images/d8-simpletest-4.png diff --git a/tdd-test-driven-drupal/images/d8-simpletest-5.png b/source/test-driven-drupal/images/d8-simpletest-5.png similarity index 100% rename from tdd-test-driven-drupal/images/d8-simpletest-5.png rename to source/test-driven-drupal/images/d8-simpletest-5.png diff --git a/tdd-test-driven-drupal/images/d8-simpletest-6.png b/source/test-driven-drupal/images/d8-simpletest-6.png similarity index 100% rename from tdd-test-driven-drupal/images/d8-simpletest-6.png rename to source/test-driven-drupal/images/d8-simpletest-6.png diff --git a/tdd-test-driven-drupal/images/d8-simpletest-7.png b/source/test-driven-drupal/images/d8-simpletest-7.png similarity index 100% rename from tdd-test-driven-drupal/images/d8-simpletest-7.png rename to source/test-driven-drupal/images/d8-simpletest-7.png diff --git a/tdd-test-driven-drupal/images/dcbristol.png b/source/test-driven-drupal/images/dcbristol.png similarity index 100% rename from tdd-test-driven-drupal/images/dcbristol.png rename to source/test-driven-drupal/images/dcbristol.png diff --git a/tdd-test-driven-drupal/images/ddd-1.jpeg b/source/test-driven-drupal/images/ddd-1.jpeg similarity index 100% rename from tdd-test-driven-drupal/images/ddd-1.jpeg rename to source/test-driven-drupal/images/ddd-1.jpeg diff --git a/tdd-test-driven-drupal/images/ddd-2.jpeg b/source/test-driven-drupal/images/ddd-2.jpeg similarity index 100% rename from tdd-test-driven-drupal/images/ddd-2.jpeg rename to source/test-driven-drupal/images/ddd-2.jpeg diff --git a/tdd-test-driven-drupal/images/ddd-3.jpeg b/source/test-driven-drupal/images/ddd-3.jpeg similarity index 100% rename from tdd-test-driven-drupal/images/ddd-3.jpeg rename to source/test-driven-drupal/images/ddd-3.jpeg diff --git a/tdd-test-driven-drupal/images/ddd-4.jpeg b/source/test-driven-drupal/images/ddd-4.jpeg similarity index 100% rename from tdd-test-driven-drupal/images/ddd-4.jpeg rename to source/test-driven-drupal/images/ddd-4.jpeg diff --git a/tdd-test-driven-drupal/images/ddd-5.jpg b/source/test-driven-drupal/images/ddd-5.jpg similarity index 100% rename from tdd-test-driven-drupal/images/ddd-5.jpg rename to source/test-driven-drupal/images/ddd-5.jpg diff --git a/tdd-test-driven-drupal/images/ddd-5.png b/source/test-driven-drupal/images/ddd-5.png similarity index 100% rename from tdd-test-driven-drupal/images/ddd-5.png rename to source/test-driven-drupal/images/ddd-5.png diff --git a/drupal-testing-workshop/images/deploy-all-the-things.jpg b/source/test-driven-drupal/images/deploy-all-the-things.jpg similarity index 100% rename from drupal-testing-workshop/images/deploy-all-the-things.jpg rename to source/test-driven-drupal/images/deploy-all-the-things.jpg diff --git a/deploying-php-fabric/images/files.png b/source/test-driven-drupal/images/files.png similarity index 100% rename from deploying-php-fabric/images/files.png rename to source/test-driven-drupal/images/files.png diff --git a/deploying-php-fabric/images/homer-smart.png b/source/test-driven-drupal/images/homer-smart.png similarity index 100% rename from deploying-php-fabric/images/homer-smart.png rename to source/test-driven-drupal/images/homer-smart.png diff --git a/tdd-test-driven-drupal/images/kernel-tests.png b/source/test-driven-drupal/images/kernel-tests.png similarity index 100% rename from tdd-test-driven-drupal/images/kernel-tests.png rename to source/test-driven-drupal/images/kernel-tests.png diff --git a/tdd-test-driven-drupal/images/matt-stauffer-tweet.png b/source/test-driven-drupal/images/matt-stauffer-tweet.png similarity index 100% rename from tdd-test-driven-drupal/images/matt-stauffer-tweet.png rename to source/test-driven-drupal/images/matt-stauffer-tweet.png diff --git a/tdd-test-driven-drupal/images/me.jpg b/source/test-driven-drupal/images/me.jpg similarity index 100% rename from tdd-test-driven-drupal/images/me.jpg rename to source/test-driven-drupal/images/me.jpg diff --git a/tdd-test-driven-drupal/images/phpstorm-integration.png b/source/test-driven-drupal/images/phpstorm-integration.png similarity index 100% rename from tdd-test-driven-drupal/images/phpstorm-integration.png rename to source/test-driven-drupal/images/phpstorm-integration.png diff --git a/tdd-test-driven-drupal/images/phpunit.png b/source/test-driven-drupal/images/phpunit.png similarity index 100% rename from tdd-test-driven-drupal/images/phpunit.png rename to source/test-driven-drupal/images/phpunit.png diff --git a/tdd-test-driven-drupal/images/simpletest-1.png b/source/test-driven-drupal/images/simpletest-1.png similarity index 100% rename from tdd-test-driven-drupal/images/simpletest-1.png rename to source/test-driven-drupal/images/simpletest-1.png diff --git a/tdd-test-driven-drupal/images/simpletest-2.png b/source/test-driven-drupal/images/simpletest-2.png similarity index 100% rename from tdd-test-driven-drupal/images/simpletest-2.png rename to source/test-driven-drupal/images/simpletest-2.png diff --git a/tdd-test-driven-drupal/images/simpletest-3.png b/source/test-driven-drupal/images/simpletest-3.png similarity index 100% rename from tdd-test-driven-drupal/images/simpletest-3.png rename to source/test-driven-drupal/images/simpletest-3.png diff --git a/tdd-test-driven-drupal/images/simpletest-4.png b/source/test-driven-drupal/images/simpletest-4.png similarity index 100% rename from tdd-test-driven-drupal/images/simpletest-4.png rename to source/test-driven-drupal/images/simpletest-4.png diff --git a/tdd-test-driven-drupal/images/simpletest-countdown.png b/source/test-driven-drupal/images/simpletest-countdown.png similarity index 100% rename from tdd-test-driven-drupal/images/simpletest-countdown.png rename to source/test-driven-drupal/images/simpletest-countdown.png diff --git a/tdd-test-driven-drupal/images/simpletest.png b/source/test-driven-drupal/images/simpletest.png similarity index 100% rename from tdd-test-driven-drupal/images/simpletest.png rename to source/test-driven-drupal/images/simpletest.png diff --git a/tdd-test-driven-drupal/images/tada.png b/source/test-driven-drupal/images/tada.png similarity index 100% rename from tdd-test-driven-drupal/images/tada.png rename to source/test-driven-drupal/images/tada.png diff --git a/tdd-test-driven-drupal/images/tawny-tweet-1.png b/source/test-driven-drupal/images/tawny-tweet-1.png similarity index 100% rename from tdd-test-driven-drupal/images/tawny-tweet-1.png rename to source/test-driven-drupal/images/tawny-tweet-1.png diff --git a/tdd-test-driven-drupal/images/tawny-tweet-2.png b/source/test-driven-drupal/images/tawny-tweet-2.png similarity index 100% rename from tdd-test-driven-drupal/images/tawny-tweet-2.png rename to source/test-driven-drupal/images/tawny-tweet-2.png diff --git a/tdd-test-driven-drupal/images/tdd-blog-1.png b/source/test-driven-drupal/images/tdd-blog-1.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-blog-1.png rename to source/test-driven-drupal/images/tdd-blog-1.png diff --git a/tdd-test-driven-drupal/images/tdd-blog-2.png b/source/test-driven-drupal/images/tdd-blog-2.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-blog-2.png rename to source/test-driven-drupal/images/tdd-blog-2.png diff --git a/tdd-test-driven-drupal/images/tdd-blog-3.png b/source/test-driven-drupal/images/tdd-blog-3.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-blog-3.png rename to source/test-driven-drupal/images/tdd-blog-3.png diff --git a/tdd-test-driven-drupal/images/tdd-blog-4.png b/source/test-driven-drupal/images/tdd-blog-4.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-blog-4.png rename to source/test-driven-drupal/images/tdd-blog-4.png diff --git a/tdd-test-driven-drupal/images/tdd-blog-5.png b/source/test-driven-drupal/images/tdd-blog-5.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-blog-5.png rename to source/test-driven-drupal/images/tdd-blog-5.png diff --git a/tdd-test-driven-drupal/images/tdd-blog-directories.png b/source/test-driven-drupal/images/tdd-blog-directories.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-blog-directories.png rename to source/test-driven-drupal/images/tdd-blog-directories.png diff --git a/tdd-test-driven-drupal/images/tdd-blog-installed.png b/source/test-driven-drupal/images/tdd-blog-installed.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-blog-installed.png rename to source/test-driven-drupal/images/tdd-blog-installed.png diff --git a/tdd-test-driven-drupal/images/tdd-circle-of-life.png b/source/test-driven-drupal/images/tdd-circle-of-life.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-circle-of-life.png rename to source/test-driven-drupal/images/tdd-circle-of-life.png diff --git a/tdd-test-driven-drupal/images/tdd-drupal-tasks.png b/source/test-driven-drupal/images/tdd-drupal-tasks.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-drupal-tasks.png rename to source/test-driven-drupal/images/tdd-drupal-tasks.png diff --git a/tdd-test-driven-drupal/images/tdd-loop.png b/source/test-driven-drupal/images/tdd-loop.png similarity index 100% rename from tdd-test-driven-drupal/images/tdd-loop.png rename to source/test-driven-drupal/images/tdd-loop.png diff --git a/tdd-test-driven-drupal/images/timmillwood-ono.png b/source/test-driven-drupal/images/timmillwood-ono.png similarity index 100% rename from tdd-test-driven-drupal/images/timmillwood-ono.png rename to source/test-driven-drupal/images/timmillwood-ono.png diff --git a/tdd-test-driven-drupal/images/title.png b/source/test-driven-drupal/images/title.png similarity index 100% rename from tdd-test-driven-drupal/images/title.png rename to source/test-driven-drupal/images/title.png diff --git a/tdd-test-driven-drupal/images/toggle-optional-fields-1.png b/source/test-driven-drupal/images/toggle-optional-fields-1.png similarity index 100% rename from tdd-test-driven-drupal/images/toggle-optional-fields-1.png rename to source/test-driven-drupal/images/toggle-optional-fields-1.png diff --git a/tdd-test-driven-drupal/images/toggle-optional-fields-2.png b/source/test-driven-drupal/images/toggle-optional-fields-2.png similarity index 100% rename from tdd-test-driven-drupal/images/toggle-optional-fields-2.png rename to source/test-driven-drupal/images/toggle-optional-fields-2.png diff --git a/tdd-test-driven-drupal/images/toggle-optional-fields-3.png b/source/test-driven-drupal/images/toggle-optional-fields-3.png similarity index 100% rename from tdd-test-driven-drupal/images/toggle-optional-fields-3.png rename to source/test-driven-drupal/images/toggle-optional-fields-3.png diff --git a/tdd-test-driven-drupal/images/toggle-optional-fields-button.png b/source/test-driven-drupal/images/toggle-optional-fields-button.png similarity index 100% rename from tdd-test-driven-drupal/images/toggle-optional-fields-button.png rename to source/test-driven-drupal/images/toggle-optional-fields-button.png diff --git a/tdd-test-driven-drupal/images/when-you-do-things-right.jpg b/source/test-driven-drupal/images/when-you-do-things-right.jpg similarity index 100% rename from tdd-test-driven-drupal/images/when-you-do-things-right.jpg rename to source/test-driven-drupal/images/when-you-do-things-right.jpg diff --git a/tdd-test-driven-drupal/slides.md b/source/test-driven-drupal/slides.md similarity index 100% rename from tdd-test-driven-drupal/slides.md rename to source/test-driven-drupal/slides.md diff --git a/tdd-test-driven-drupal/todo.md b/source/test-driven-drupal/todo.md similarity index 100% rename from tdd-test-driven-drupal/todo.md rename to source/test-driven-drupal/todo.md diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/all-the-things.jpg b/source/using-laravel-collections-outside-laravel/images/all-the-things.jpg similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/all-the-things.jpg rename to source/using-laravel-collections-outside-laravel/images/all-the-things.jpg diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/blog-post.png b/source/using-laravel-collections-outside-laravel/images/blog-post.png similarity index 100% rename from using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/blog-post.png rename to source/using-laravel-collections-outside-laravel/images/blog-post.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/collection-class-module-project-page-1.png b/source/using-laravel-collections-outside-laravel/images/collection-class-module-project-page-1.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/collection-class-module-project-page-1.png rename to source/using-laravel-collections-outside-laravel/images/collection-class-module-project-page-1.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/collection-class-module-project-page-2.png b/source/using-laravel-collections-outside-laravel/images/collection-class-module-project-page-2.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/collection-class-module-project-page-2.png rename to source/using-laravel-collections-outside-laravel/images/collection-class-module-project-page-2.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/composer.png b/source/using-laravel-collections-outside-laravel/images/composer.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/composer.png rename to source/using-laravel-collections-outside-laravel/images/composer.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/drupal-8.png b/source/using-laravel-collections-outside-laravel/images/drupal-8.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/drupal-8.png rename to source/using-laravel-collections-outside-laravel/images/drupal-8.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/drupal-issue-1.png b/source/using-laravel-collections-outside-laravel/images/drupal-issue-1.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/drupal-issue-1.png rename to source/using-laravel-collections-outside-laravel/images/drupal-issue-1.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/drupal-issue-2.png b/source/using-laravel-collections-outside-laravel/images/drupal-issue-2.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/drupal-issue-2.png rename to source/using-laravel-collections-outside-laravel/images/drupal-issue-2.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/druplicon.png b/source/using-laravel-collections-outside-laravel/images/druplicon.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/druplicon.png rename to source/using-laravel-collections-outside-laravel/images/druplicon.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/laravel.png b/source/using-laravel-collections-outside-laravel/images/laravel.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/laravel.png rename to source/using-laravel-collections-outside-laravel/images/laravel.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/packagist.png b/source/using-laravel-collections-outside-laravel/images/packagist.png similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/packagist.png rename to source/using-laravel-collections-outside-laravel/images/packagist.png diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/tweet-1.png b/source/using-laravel-collections-outside-laravel/images/tweet-1.png similarity index 100% rename from using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/tweet-1.png rename to source/using-laravel-collections-outside-laravel/images/tweet-1.png diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/yay-open-source.jpg b/source/using-laravel-collections-outside-laravel/images/yay-open-source.jpg similarity index 100% rename from using-laravel-collections-outside-laravel/2017-12-21-nomad-php/images/yay-open-source.jpg rename to source/using-laravel-collections-outside-laravel/images/yay-open-source.jpg diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides.md b/source/using-laravel-collections-outside-laravel/slides.md similarity index 100% rename from using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/slides.md rename to source/using-laravel-collections-outside-laravel/slides.md diff --git a/taking-flight-with-tailwind-css/2018-01-17-drupal-bristol/images/1.png b/taking-flight-with-tailwind-css/2018-01-17-drupal-bristol/images/1.png deleted file mode 100644 index afbb8ca..0000000 Binary files a/taking-flight-with-tailwind-css/2018-01-17-drupal-bristol/images/1.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/1.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/1.png deleted file mode 100644 index a8a2ebf..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/1.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/laravel-nova.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/laravel-nova.png deleted file mode 100644 index f5ba37e..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/laravel-nova.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/php-south-wales.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/php-south-wales.png deleted file mode 100644 index d4279a7..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/php-south-wales.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/refactoring-ui.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/refactoring-ui.png deleted file mode 100644 index bf6e1a9..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/refactoring-ui.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/spatie.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/spatie.png deleted file mode 100644 index 1739a07..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/images/spatie.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.md b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.md deleted file mode 100644 index bbb3adc..0000000 --- a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides.md +++ /dev/null @@ -1,667 +0,0 @@ -theme: poster, 8 -autoscale: true -build-lists: true -header-emphasis: #53B0EB -header: alignment(left) -text: alignment(left) -text-emphasis: #53B0EB -code: line-height(1.2) - -[.hide-footer] -[.header: alignment(center)] - -## [fit] _Taking Flight with_ -## [fit] Tailwind CSS - -With Oliver Davies - ---- - -[.background-color: #FFFFFF] -[.build-lists: false] -[.header: #111111] -[.text: #111111, alignment(left)] - - - -- Full Stack Web Developer & System Administrator -- Senior Developer at Microserve -- Part-time freelancer -- Acquia certified Drupal 8 Grand Master -- Drupal 7 & 8 core contributor -- Symfony, Laravel, ~~Silex,~~ Sculpin -- @opdavies -- www.oliverdavies.uk - -^ Work at Microserve. -Maintain Drupal modules, PHP CLI tools and libraries -Blog on my website - ---- - -[.background-color: #FFFFFF] -[.build-lists: false] -[.text: #111111, alignment(left)] - - - -- https://microserve.io -- https://www.drupal.org/microserve -- https://github.com/microserve-io -- https://twitter.com/microserveltd -- https://www.linkedin.com/company/microserve-ltd - ---- - -[.header: alignment(center)] - -## A _Utility-First CSS Framework_ for Rapid UI Development - -^ What is Tailwind? - ---- - -[.header: alignment(center)] - - -## A CSS framework <br>_with no CSS_ - ---- - - - -[.header: alignment(center)] - - -## _A different way_ <br>to write CSS - ---- - -[.build-lists: false] - -- Developed by Adam Wathan and others -- Utility CSS class generator -- PostCSS -- Configured with JavaScript -- Some preprocessor features -- Can be used in addition to preprocessors -- Open source - -^ Works with plain CSS or any preprocessor -Can be configured to enable/disable modules, configure colours etc. -Can use features like variables if using plain CSS. - ---- - -```css -.title { - background-color: #3490DC; - color: #FFF; - display: block; - font-size: 1.5rem; - padding: 2rem; -} -``` - ---- - -```css -.text-2xl { - font-size: 1.5rem; -} - -.bg-red { - background-color: #93140B; -} - -.text-white { - color: #FFF; -} -``` - ---- - -```html -<div class="text-2xl bg-red text-white p-8"> - <p>Hello, PHP South Wales!</p> -</div> -``` - ---- - - - ---- - -[.header: alignment(center)] - -# Installation - ---- - -[.header: #53B0EB] - -# Option 1 - -``` -https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css -``` - ---- - -[.header: #53B0EB] - -# Option 2 - -```bash -npm install tailwindcss --save-dev - -yarn add tailwindcss --dev - -./node_modules/.bin/tailwind init [filename] -``` - -^ Install with npm or Yarn -Run "tailwind init" to generate a default tailwind.js file - ---- - -```js -// tailwind.js - -var colors = { - 'transparent': 'transparent', - - 'black': '#222b2f', - 'grey-darkest': '#364349', - 'grey-darker': '#596a73', - 'grey-dark': '#70818a', - 'grey': '#9babb4', - 'grey-light': '#dae4e9', - 'grey-lighter': '#f2f2f2', - 'grey-lightest': '#fafcfc', - 'white': '#ffffff', - ... -``` - ---- - -```less -// app.css - -@tailwind preflight; - -@tailwind components; - -@tailwind utilities; -``` - ---- - -```js -// webpack.mix.js - -let mix = require('laravel-mix'); - - -mix.postCss('build', 'assets/css/app.css', [ - require('laravel-mix-tailwind')() -]) -``` - ---- - -```js -// webpack.mix.js - -let mix = require('laravel-mix'); - - -mix.postCss('build', 'assets/css/app.css', [ - require('laravel-mix-tailwind')('./tailwind.config.js') -]) -``` - ---- - -```js -// webpack.config.js - -Encore - .setOutputPath('public/build/') - .setPublicPath('/build') - .addStyleEntry('app', './assets/css/app.css') - .enablePostCssLoader() -; -``` - -^ Using Webpack Encore - ---- - -```js -// postcss.config.js - -module.exports = { - plugins: [ - require('tailwindcss')('./tailwind.js'), - ] -} -``` - ---- - -```html -<head> - <title>Hello, World!</title> - <link rel="stylesheet" href="/build/app.css"> -... -``` - ---- - -```css -.text-left { - text-align: left; -} - -.text-center { - text-align: center; -} - -.text-right { - text-align: right; -} - -.text-justify { - text-align: justify; -} - -... -``` - ---- - -```html -<div class="text-2xl bg-red text-white p-8"> - <p>Hello, PHP South Wales!</p> -</div> -``` - ---- - - - ---- - -[.header: alignment(center)] - -# Configuration - ---- - -```javascript -// tailwind.js - -var colors = { - ... - - 'blue-darkest': '#05233b', - 'blue-darker': '#103d60', - 'blue-dark': '#2779bd', - 'blue': '#0678be', - 'blue-light': '#6cb2eb', - 'blue-lighter': '#bcdefa', - 'blue-lightest': '#eff8ff', - - ... -} -``` - -^ Add, change, remove values as needed - ---- - -```js -screens: { - 'sm': '576px', - 'md': '768px', - 'lg': '992px', - 'xl': '1200px', -} -``` - ---- - -```js -textSizes: { - 'xs': '.75rem', // 12px - 'sm': '.875rem', // 14px - 'base': '1rem', // 16px - 'lg': '1.125rem', // 18px - 'xl': '1.25rem', // 20px - '2xl': '1.5rem', // 24px - '3xl': '1.875rem', // 30px - '4xl': '2.25rem', // 36px - '5xl': '3rem', // 48px -} -``` - ---- - -```js -width: { - 'auto': 'auto', - 'px': '1px', - '1': '0.25rem', - '2': '0.5rem', - '3': '0.75rem', - '4': '1rem', - '6': '1.5rem', - '8': '2rem', - '10': '2.5rem', - '12': '3rem', - '16': '4rem', - '24': '6rem', - ... -} -``` - ---- - -```js -padding: { - 'px': '1px', - '0': '0', - '1': '0.25rem', - '2': '0.5rem', - '3': '0.75rem', - '4': '1rem', - '5': '1.25rem', - '6': '1.5rem', - '8': '2rem', - '16': '4rem', -} -``` - ---- - -```javascript -options: { - prefix: '', - important: false, - separator: ':', -} -``` - -^ - Drupal important config -- By adding a prefix, we don't clash with Drupal's core styles - e.g. ".block" - ---- - -[.build-lists: false] - -- Colours (text and background) -- Font family, size, weight -- Leading (line height), tracking (letter spacing) -- Border widths, colours, radius -- Width, height, min/max width/height - ---- - -[.build-lists: false] - -- Padding, margin (positive and negative) -- Shadows -- Z-index -- Opacity -- SVG fill, stroke -- Screen sizes (breakpoints) - ---- - -[.header: alignment(center)] - -# States -### _Hover, Focus, Active, Group hover_ - ---- - -```css -.{state}{separator}{class} -``` - ---- - -```twig -<a class="bg-grey hover:bg-grey-dark focus:bg-grey-dark" href="/"> - Home -</a> -``` - -^ Hover, focus - ---- - -```twig -<a class="group"> - <img - class="border-white group-hover:border-grey" - src="{{ speaker.photoUrl }}" - > - - <div class="no-underline group-hover:underline"> - {{ speaker.name }} - </div> -</a> -``` - -^ Group hover - ---- - -[.header: alignment(center)] - -# Responsive - ---- - -```less -.{screen}{separator}{class} -``` - ---- - -```html -<div class="w-full md:w-1/2 lg:w-1/4"> - <p>Hello, World!</p> -</div> -``` - ---- - -[.header: alignment(center)] - -# Extracting <br>Components - ---- - -[.header: alignment(center)] - - -## _Do you need to_ extract <br>a component? - ---- - -```twig -{% for item in items %} - <a class="block py-3 px-4 text-sm text-grey" href="{{ item.url }}"> - {{ item.title }} - </a> -{% endfor %} -``` - -^ Use a loop - ---- - -```twig -<h2>Adults</h2> - -{% include 'class-list' with { - classes: page.classes, - type: 'adults', -} %} - -<h2>Kids</h2> - -{% include 'class-list' with { - classes: page.classes, - type: 'kids', -} %} -``` - -^ Move the duplicate markup into a partial, so there's only one version -Pass data in. - ---- - -```html -<a href="inline-block rounded text-sm py-2 px-3 text-white bg-red"> - Click me! -</a> - -<a href="inline-block rounded text-sm py-2 px-3 text-white bg-green"> - Click me too! -</a> -``` - ---- - -```css -# main.css - -.button { - @apply .inline-block; - @apply .rounded; - @apply .text-sm; - @apply .py-2; - @apply .px-3; - @apply .text-white; -} -``` - ---- - -```html -<a href="button bg-red"> - Click me! -</a> - -<a href="button bg-green"> - Click me too! -</a> -``` - ---- - -```less -// table.less - -.table-responsive { - @apply .mb-4 .border .w-full; - overflow-x: auto; - overflow-y: hidden; -} - -.table-responsive table { - @apply .mb-0 .border-0 .whitespace-no-wrap; -} - -.table { - @apply .w-full .table-collapse; -} - -.table tr:nth-child(odd) { - @apply .bg-grey-lightest; -} - -.table tr th { - @apply .text-left .p-3 .bg-white; -} - -.table td { - @apply .px-3 .py-3 .border-t; -} -``` - ---- - -[.header: #53B0EB] - -# Advantages - -- Quick to prototype and make changes -- Write less CSS -- More consistency -- Easy to customise, promote to components -- Mix and match with normal CSS -- Easy to write reusable plugins -- Use PurgeCSS to remove unused classes - -^ Do more with browser dev tools -Only picking from pre-defined colours, widths. No magic numbers. -Less ramp-up time as using the same framework on different sites. -Same classes, but no visual similarities like with other frameworks like Bootstrap - ---- - -[.header: #53B0EB] - -# Disadvantages - -- Extra build tools and steps -- Lots of classes in markup -- Large file size by default - -^ - Need a build tool (Gulp, Grunt, Webpack) to build CSS - ---- - - - ---- - - - ---- - - - - ---- - - - ---- - -[.build-lists: false] -[.header: #53B0EB] - -# Resources - -- tailwindcss.com -- tailwindcomponents.com -- github.com/merchedhq/awesome-tailwindcss -- youtube.com/adamwathan -- github.com/opdavies/oliverdavies.uk -- github.com/phpsw/phpsw-ng - ---- - -[.header: alignment(center)] - -# Thanks! -### _@opdavies_ -### _oliverdavies.uk_ - diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/1.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/1.png deleted file mode 100644 index 27ac156..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/1.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/10.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/10.png deleted file mode 100644 index c1f0364..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/10.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/11.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/11.png deleted file mode 100644 index b941238..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/11.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/12.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/12.png deleted file mode 100644 index a91d7c8..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/12.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/13.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/13.png deleted file mode 100644 index a9c33d4..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/13.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/14.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/14.png deleted file mode 100644 index 768084c..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/14.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/15.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/15.png deleted file mode 100644 index bac10ec..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/15.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/16.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/16.png deleted file mode 100644 index 982d550..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/16.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/17.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/17.png deleted file mode 100644 index 06459bc..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/17.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/18.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/18.png deleted file mode 100644 index bf14ffd..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/18.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/19.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/19.png deleted file mode 100644 index 52bb006..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/19.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/2.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/2.png deleted file mode 100644 index 8f85564..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/2.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/20.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/20.png deleted file mode 100644 index 94737da..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/20.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/21.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/21.png deleted file mode 100644 index 4dcf719..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/21.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/22.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/22.png deleted file mode 100644 index c1f0364..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/22.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/23.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/23.png deleted file mode 100644 index c59007f..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/23.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/24.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/24.png deleted file mode 100644 index a0aa06c..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/24.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/25.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/25.png deleted file mode 100644 index e8c2d77..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/25.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/26.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/26.png deleted file mode 100644 index c31712e..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/26.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/27.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/27.png deleted file mode 100644 index 50ee2c7..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/27.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/28.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/28.png deleted file mode 100644 index 27103c6..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/28.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/29.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/29.png deleted file mode 100644 index 59d954c..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/29.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/3.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/3.png deleted file mode 100644 index ecc669c..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/3.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/30.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/30.png deleted file mode 100644 index 6fdf3a0..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/30.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/31.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/31.png deleted file mode 100644 index e651792..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/31.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/32.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/32.png deleted file mode 100644 index 4c15a6f..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/32.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/33.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/33.png deleted file mode 100644 index 760b2e2..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/33.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/34.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/34.png deleted file mode 100644 index 7565860..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/34.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/35.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/35.png deleted file mode 100644 index 7be12f6..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/35.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/36.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/36.png deleted file mode 100644 index b63b523..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/36.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/37.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/37.png deleted file mode 100644 index a71070c..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/37.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/38.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/38.png deleted file mode 100644 index 1f6ccc0..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/38.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/39.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/39.png deleted file mode 100644 index 693ebec..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/39.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/4.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/4.png deleted file mode 100644 index 52d6197..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/4.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/40.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/40.png deleted file mode 100644 index f4674f2..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/40.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/41.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/41.png deleted file mode 100644 index 46f1b58..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/41.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/42.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/42.png deleted file mode 100644 index 8377f42..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/42.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/43.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/43.png deleted file mode 100644 index c20bacb..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/43.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/44.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/44.png deleted file mode 100644 index 431f2e2..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/44.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/45.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/45.png deleted file mode 100644 index 66b8728..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/45.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/46.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/46.png deleted file mode 100644 index c3a1c33..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/46.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/47.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/47.png deleted file mode 100644 index 9792224..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/47.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/48.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/48.png deleted file mode 100644 index eb26ef0..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/48.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/49.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/49.png deleted file mode 100644 index c4b19da..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/49.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/5.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/5.png deleted file mode 100644 index 612b630..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/5.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/50.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/50.png deleted file mode 100644 index 1052a89..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/50.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/51.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/51.png deleted file mode 100644 index f35568a..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/51.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/52.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/52.png deleted file mode 100644 index 201d344..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/52.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/53.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/53.png deleted file mode 100644 index f362d4c..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/53.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/54.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/54.png deleted file mode 100644 index f71d5ac..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/54.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/6.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/6.png deleted file mode 100644 index 57fa577..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/6.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/7.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/7.png deleted file mode 100644 index 8c30ba6..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/7.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/8.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/8.png deleted file mode 100644 index 781840a..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/8.png and /dev/null differ diff --git a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/9.png b/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/9.png deleted file mode 100644 index c0ef4bb..0000000 Binary files a/taking-flight-with-tailwind-css/2018-07-31-php-south-wales/slides/9.png and /dev/null differ diff --git a/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides2.pdf b/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides2.pdf deleted file mode 100644 index c6c4eaf..0000000 Binary files a/tdd-test-driven-drupal/2018-06-14-drupal-somerset/slides2.pdf and /dev/null differ diff --git a/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/tdd-test-driven-drupal.pdf b/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/tdd-test-driven-drupal.pdf deleted file mode 100644 index 77964ee..0000000 Binary files a/tdd-test-driven-drupal/2018-07-05-drupal-dev-days/tdd-test-driven-drupal.pdf and /dev/null differ diff --git a/tdd-test-driven-drupal/images/deploy-all-the-things.jpg b/tdd-test-driven-drupal/images/deploy-all-the-things.jpg deleted file mode 100644 index f90028e..0000000 Binary files a/tdd-test-driven-drupal/images/deploy-all-the-things.jpg and /dev/null differ diff --git a/tdd-test-driven-drupal/images/files.png b/tdd-test-driven-drupal/images/files.png deleted file mode 100644 index a23b62a..0000000 Binary files a/tdd-test-driven-drupal/images/files.png and /dev/null differ diff --git a/tdd-test-driven-drupal/images/homer-smart.png b/tdd-test-driven-drupal/images/homer-smart.png deleted file mode 100644 index 50c5705..0000000 Binary files a/tdd-test-driven-drupal/images/homer-smart.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.md b/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.md deleted file mode 100644 index 4b69727..0000000 --- a/using-laravel-collections-outside-laravel/2017-12-21-nomad-php/slides.md +++ /dev/null @@ -1,236 +0,0 @@ -theme: poster, 8 -autoscale: true -build-lists: true -header-emphasis: #53B0EB -header: alignment(left) -text: alignment(left) -text-emphasis: #53B0EB -code: Operator Mono, line-height(1.5) - -[.background-color: #FFFFFF] -[.hide-footer] -[.header: #111111, alignment(center)] - -## Using Laravel Collections... <br>Outside Laravel - - - ---- - -[.header: alignment(center)] - -## Collections :thumbsup: - -^ Became a fan of Collections whilst learning Laravel -Powerful object orientated way to interact with arrays -Store items within the collection, run methods, chainable -More readable, less temporary variables -Video on Laracasts, Adam Wathan's refactoring to Collections -Wanted to use them with different PHP projects e.g. Drupal - ---- - -```php -collect(['foo', 'bar']); // ['foo', 'bar'] - -collect('foobar'); // ['foobar'] - -$object = new stdClass(); -$object->foo = 'bar'; -collect($object); // ['foo' => 'bar'] -collect($object)->get('foo'); // bar -``` - -^ How do you make a collection? -collect function is provided -String, array or object -Stored as items within the Collection object - ---- - -```php -$collection = collect(['a', 'b', 1, 'c', 2, 'd', 'e', 3, 4]); - -$collection->count(); // 9 - -$collection->first(); // a - -$collection->first(function ($item) { - return is_numeric($item); -}); // 1 - -$collection->contains(2); // true - -$collection->contains([2, 10]); // false - -$collection->filter(function ($item) { - return $item > 2; -}); // [3, 4] -``` - -^ Once you have a collection, what can you do with it? -"contains" - no more needle/haystack, haystack/needle -"filter" - filters false, null values -Can pass callbacks to `first` and `filter`, return true or false as needed. - ---- - -```php -$collection = collect([ - ['name' => 'John', 'email' => 'john@example.com', 'age' => 31], - ['name' => 'Jane', 'email' => 'jane@example.com', 'age' => 27], -]); - -$collection->pluck('name'); // ['John', 'Jane'] - -$collection->pluck('name')->sort(); // ['Jane', 'John'] - -$collection->filter(function ($person) { - return $person['age'] >= 30; -})->pluck('name'); // ['John'] -``` - ---- - -[.background-color: #FFFFFF] - - - -^ This is great, but how can I do that in my Drupal code? -How can I do that? - ---- - -## There’s a module for that! -### _- Drupalers_ - ---- - -[.text: alignment(center)] - -## [fit] There's not a module for that. :disappointed: -### _- Me_ - ---- - - - -^ Drupal 7 - ---- - - -### _Version 1.0_ -## Write my own Collection class - -^ Wrote my own Collection class -Wrote my own tests - ---- - - - -^ Maybe 70% of what Laravel's could do. - ---- - - - -^ Can't remember how, but then I found this. - ---- - - -### Collect - Illuminate Collections as a separate package. -#### _https://packagist.org/packages/tightenco/collect_ - ---- - -### Import Laravel's Collections into non-Laravel packages easily, without needing to require the entire Illuminate\Support package. -#### _https://packagist.org/packages/tightenco/collect_ - ---- - -[.background-color: #FFFFFF] - - - -^ Can install via Composer - ---- - -## _composer require_<br>tightenco/collect - ---- - - ---- - - - ---- - -### _Version 2.0_ -## Use someone else’s Collection class - -^ More fully featured, less code to maintain - ---- - -[.background-color: #FFFFFF] - - - ---- - -[.build-lists: false] - -- Install Composer -- Require `tightenco/collect` -- Include `autoload.php` -- `collect()` away! - ---- - -[.build-lists: false] - -- Install Composer -- Require `tightenco/collect` -- Include `autoload.php` -- `collect()` away! - - - ---- - -```php -// index.php - -require __DIR__ . '/vendor/autoload.php'; - -$collection = collect(['foo', 'bar']); - -$collection->each(function ($item) { - // Do something. -}); -``` - -^ Require/include autoload.php -Start using Collections! -`collect` function is autoloaded - ---- - -[.background-color: #FFFFFF] - - - -^ Drupal 8, Sculpin site, PHP libraries - ---- - -[.header: alignment(center)] - -# Thanks! -### _@opdavies_ -### _oliverdavies.uk_ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/all-the-things.jpg b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/all-the-things.jpg deleted file mode 100644 index 4817029..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/all-the-things.jpg and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-1.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-1.png deleted file mode 100644 index 5faddee..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-1.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-2.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-2.png deleted file mode 100644 index a5bd958..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/collection-class-module-project-page-2.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/composer.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/composer.png deleted file mode 100644 index bb95a49..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/composer.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-8.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-8.png deleted file mode 100644 index a0d7bb9..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-8.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-1.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-1.png deleted file mode 100644 index 1d79637..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-1.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-2.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-2.png deleted file mode 100644 index aabd686..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/drupal-issue-2.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/druplicon.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/druplicon.png deleted file mode 100644 index f8ced55..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/druplicon.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/laravel.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/laravel.png deleted file mode 100644 index 3c83acc..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/laravel.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/packagist.png b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/packagist.png deleted file mode 100644 index c129ae3..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/packagist.png and /dev/null differ diff --git a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/yay-open-source.jpg b/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/yay-open-source.jpg deleted file mode 100644 index ab224d2..0000000 Binary files a/using-laravel-collections-outside-laravel/2018-08-28-php-south-wales/images/yay-open-source.jpg and /dev/null differ