diff --git a/source/_posts/10-years-working-full-time-drupal-php.md b/source/_posts/10-years-working-full-time-drupal-php.md new file mode 100644 index 00000000..5d292dc5 --- /dev/null +++ b/source/_posts/10-years-working-full-time-drupal-php.md @@ -0,0 +1,26 @@ +--- +title: 10 years working full time with Drupal and PHP +description: 10 years ago today, I started working for Horse & Country TV in what was my full-time Drupal development role. +tags: [] +date: 2020-07-19 +--- + +
+ +10 years ago today, I started working for [Horse & Country TV](https://horseandcountry.tv) in what was my full-time Drupal development role. + +I'd been learning and working with Drupal for a couple of years prior to this, working on some personal and freelance projects, but when I was looking to move back to this area of Wales, this job on my doorstep was ideal. + +Initially starting as the sole Developer before another started a few months later, I remember being very excited to see and learn how this site has been built. Some of the main things that I remember working on was re-developing the Events section and adding paid events with [Ubercart](https://www.drupal.org/project/ubercart), and expanding my module development knowledge by adding a custom block that programmatically showed the current and next programme on the channel. + +As well as working with Drupal itself, it was a great opportunity to get more hands-on experience with Linux servers and to learn new tools such as [Git](https://git-scm.com) for version control. + +I also remember being asked to contribute to a public issue on Drupal.org as part of the interview process to demonstrate my debugging abilities. I decided to look at [this Drupal 6 issue](https://www.drupal.org/node/753898), and posted a comment with some updated code that I then forwarded on, and then uploaded a patch to the issue queue. This is still one of my favourite approaches for interviews, and one that I've used myself since when interviewing people for roles that use open source technologies. I much prefer this to working on internal, company specific coding tests, as it gives the interviewee some real world experience and exposure to the project itself and its community, rather than just how to _use_ it. + +Posting on a Drupal core issue and submitting patches was a bit scary at the time, but I think paved the way for me later contributing to core and other Drupal and open source projects. In fact, I was a Contribution Day mentor at DrupalCon Los Angeles in 2015 and helped someone get _their_ first commit to core when [a fix was committed to Drupal 8](https://git.drupalcode.org/project/drupal/commit/9cdd22c). + +After this role, I've worked for various agencies working primarily with Drupal and PHP, as well as for the [Drupal Association](https://www.drupal.org/assocation) itself. Whilst in recent years I've also started working with other frameworks like Symfony and Vue.js, Drupal and PHP has always been my core specialism. + +I've been very excited by the developments in both PHP and Drupal in recent versions, and I'm looking forward to the next 10 years working with them. + +Thank you Horse & Country for giving me the chance to start on my full-time Drupal journey! diff --git a/source/_posts/cleanly-retrieving-user-profile-data-using-entity-metadata-wrapper.md b/source/_posts/cleanly-retrieving-user-profile-data-using-entity-metadata-wrapper.md new file mode 100644 index 00000000..44b274ee --- /dev/null +++ b/source/_posts/cleanly-retrieving-user-profile-data-using-entity-metadata-wrapper.md @@ -0,0 +1,34 @@ +--- +title: Cleanly retrieving user profile data using an Entity Metadata Wrapper +description: How to use Drupal 7's EntityMetadataWrapper to cleanly retrieve user profile field data. +tags: [Drupal, Drupal 7, Drupal Planet, PHP] +date: 2021-02-23 +--- + +Today I needed to load some Drupal user data via a [profile2](https://www.drupal.org/project/profile2) profile. When looking into this, most resources that I found suggest using this approach and calling the `profile2_load_by_user()` function directly and passing in the user object: + + +```php +$account = user_load(...); + +$accountWrapper = new EntityDrupalWrapper('user', $account); +// or `$accountWrapper = entity_metadata_wrapper('user', $account); + +$profile = profile2_load_by_user($account->value()); +// or `$profile = profile2_load_by_user($account);` + +$profileWrapper = new EntityDrupalWrapper('profile2', $profile); + +$firstName = $profileWrapper->get('field_first_name')->value(); +``` + +This though requires a few steps, and as I'm a fan of object-orientated code and Entity Metadata Wrappers, I wanted to find a cleaner solution. + +This is my preferred method that uses method chaining. It returns the same value, is less code, and in my opinion, it's cleaner and easier to read. + +```php +$firstName = $accountWrapper + ->get('profile_user_basic') + ->get('field_first_name') + ->value(); +``` diff --git a/source/_posts/creating-custom-phpunit-command-ddev.md b/source/_posts/creating-custom-phpunit-command-ddev.md new file mode 100644 index 00000000..babea9f8 --- /dev/null +++ b/source/_posts/creating-custom-phpunit-command-ddev.md @@ -0,0 +1,78 @@ +--- +title: Creating a custom PHPUnit command for DDEV +description: How to create a custom command to run PHPUnit commands in DDEV. +tags: [DDEV, Drupal, Drupal Planet, PHP] +date: 2020-08-28 +--- + +To begin with, let's create an empty file for our command: + +```bash +touch .ddev/commands/web/phpunit +``` +Commands are located within the `.ddev/commands` directory, with a sub-directory for the container name in which the command should be executed - or `host` if it's a command that is to be run on the host machine. + +As [the example repo](https://github.com/opdavies/ddev-phpunit-command-example) has a `web` sub-directory to mimic my Drupal application structure, the command should be run inside the web container so the file should be placed within the `.ddev/commands/web` directory. + +As we want the command to be 'phpunit', the filename should also be `phpunit`. + +This is an example of a basic command, which is a simple bash script: + +```bash +#!/usr/bin/env bash + +echo 'running phpunit...' +``` + +To begin with, let's echo some simple text to check that the command is working. It should also be listed if you run the `ddev` command. + +To check the working directory that it used when the command is run, add the following line in the command file: + +```bash +echo $(pwd) +``` + +In the example, it is `/var/www/html/web`. Note that we are already inside the `web` sub-directory. + +## Running PHPUnit + +To run PHPUnit, I can add the following to the command file: + +``` +../vendor/bin/phpunit --config .. $* +``` + +As we're already in the `web` directory, the command needs to go up on level before running the PHPUnit command, and uses `--config` to define the path to the `phpunit.xml.dist` file which is also in the parent directory. + +Using `$*` adds any additional arguments from the CLI to the command inside the container. + +The command could be made simpler by overridding the `working_directory` value in `.ddev/config`: + +```json +working_dir: + web: /var/www/html +``` + +This means that we start in `/var/www/html` rather than inside the `web` directory, and that we can simplify the command to be: + +``` +vendor/bin/phpunit $* +``` + +Because the `phpunit.xml.dist` file is inside the working directory, I no longer need to specify its path. + +## Adding documentation + +To add documentation and help text to the command, add these lines to the command file: + +```bash +## Description: Run PHPUnit tests inside the web container. +## Usage: phpunit +## Example: "ddev phpunit" or with additional arguments such as "ddev phpunit --testdox" +``` + +These will be parsed and shown when someone runs `ddev phpunit -h`, and can be used to show various examples such as adding additional arguments for the PHPUnit command. + +With this all in place, we can run commands like `ddev phpunit` or `ddev phpunit --testdox`, or even `ddev phpunit modules/custom/opdavies_talks --filter=TalkEventDateTest` for a Drupal project, and have that command and tests running inside DDEV! + +For more information on DDEV and creating custom commands, see the [DDEV documentation](https://ddev.readthedocs.io/en/stable/users/extend/custom-commands). diff --git a/source/_posts/decorating-entity-metadata-wrapper-add-refactor-methods.md b/source/_posts/decorating-entity-metadata-wrapper-add-refactor-methods.md new file mode 100644 index 00000000..6eca7e3e --- /dev/null +++ b/source/_posts/decorating-entity-metadata-wrapper-add-refactor-methods.md @@ -0,0 +1,137 @@ +--- +title: Decorating an Entity Metadata Wrapper to add and refactor methods +description: How to use the Decorator design pattern with Drupal 7's EntityMetadataWrapper to extend it, and add and refactor custom methods. +tags: [Drupal, Drupal 7, Drupal Planet, PHP] +date: 2021-02-24 +--- + +Following [yesterday's Entity Metadata Wrapper blog post](/blog/cleanly-retrieving-user-profile-data-using-entity-metadata-wrapper) and as I continued to work on this task, I noticed some duplication and found that I was repeating several of the same chaining steps in different methods in the same file. For example: + +```php +public function getFirstName(): string { + return $this + ->get('profile_user_basic') // Get the pupil's profile. + ->get('field_first_name') + ->value(); +} + +private function getTeacherFirstName(): string { + $this + ->get('profile_student') // Get the pupil's profile. + ->get('field_class') // Get the pupil's class. + ->get('field_teacher') // Get the class' teacher. + ->get('profile_user_basic') // Get the teacher's profile. + ->get('field_first_name') + ->value(); +} +``` + +In both cases, the last three lines are the same, where the same profile type is loaded, and the value is loaded from a field. + +I wanted to find a way to remove this duplication whilst also making the code more readable. Ideally, this would mean adding a method like `getFirstNameFromBasicProfile()` that would group the last three steps. + +## Extending the EntityDrupalWrapper + +I've done this before, where I've created a custom wrapper class with its own methods and extends `EntityDrupalWrapper`. This is how that might look: + +```php +final class PupilWrapper extends \EntityDrupalWrapper { + + public function __construct(\stdClass $data, $info = []) { + parent::__construct('user', $data, $info); + } + + public function getFirstName(): string { + return $this->getFirstNameFromBasicProfile(); + } + + public function getTeacherFirstName(): string { + return $this + ->get('profile_student') + ->get('field_class') + ->get('field_teacher') + ->getFirstNameFromBasicProfile(); + } + + private function getFirstNameFromBasicProfile(): string { + return $this + ->get('profile_user_basic') + ->get('field_first_name') + ->value(); + } + +} +``` + +Whilst this has worked in previous situations, this time I had this error: + +> Error: Call to undefined method EntityDrupalWrapper::getFirstNameFromBasicProfile() in Drupal\my_module\EntityWrapper\PupilWrapper->getTeacherFirstName + +This is because the `get()` method is returning an instance of `EntityStructureWrapper` (another class that extends `EntityDrupalWrapper`) which means that `getFirstNameFromBasicProfile()` is not accessible though it's in the same file. + +I tried overridding the `get()` method but wasn't able to get this to work. + +## Decorating the EntityDrupalWrapper + +Another option that I tried was to follow the Decorator design pattern, and add a new class that takes an `EntityDrupalWrapper` as an argument as uses it internally but doesn't extend it. Here's an example: + +```php +final class PupilWrapper { + + private $accountWrapper; + + public function __construct(\EntityMetadataWrapper $accountWrapper) { + $this->accountWrapper = $accountWrapper; + } + + public function getFirstName(): string { + return $this->getFirstNameFromBasicProfile(); + } + + public function getTeacherFirstName(): string { + return $this + ->get('profile_student') + ->get('field_class') + ->get('field_teacher') + ->getFirstNameFromBasicProfile(); + } + + private function getFirstNameFromBasicProfile(): string { + return $this + ->get('profile_user_basic') + ->get('field_first_name') + ->value(); + } + +} +``` + +In this case, the constructor argument is an instance of `EntityMetadataWrapper` so that it could be either an `EntityDrupalWrapper` or `EntityStructureWrapper`. + +### Re-adding required wrapper methods + +As the `get()` method is missing, this would cause an error: + +> Error: Call to undefined method Drupal\my_module\EntityWrapper\PupilWrapper::get() in Drupal\my_module\EntityWrapper\PupilWrapper->getFirstName() + +However, we can re-add it, have it get the value from `accountWrapper` and return another instance of `PupilWrapper` so that `getFirstNameFromBasicProfile()` will be available. + +```php +public function get(string $property): self { + return new self($this->accountWrapper->get($property)); +} +``` + +The `value()` method is also required, but this can delegate to the decorated wrapper: + +> Error: Call to undefined method Drupal\my_module\EntityWrapper\PupilWrapper::value() in Drupal\my_module\EntityWrapper\PupilWrapper->getFirstName() + +```php +public function value(): string { + return $this->accountWrapper->value(); +} +``` + +## Conclusion + +This was the first time that I tried extending Drupal 7's entity metadata wrappers in this way, but it worked well, removes the duplication and cleans up the code further. diff --git a/source/_posts/docker-resources.md b/source/_posts/docker-resources.md new file mode 100644 index 00000000..f0239045 --- /dev/null +++ b/source/_posts/docker-resources.md @@ -0,0 +1,21 @@ +--- +title: Docker resources +description: A list of Docker resources that I've compiled. +tags: [Docker] +date: 2021-04-13 +--- + +I've been speaking with a few people recently about Docker. Here are some resources that I found useful when I was learning Docker: + +- [The Docker documentation](https://docs.docker.com) +- [Shipping Docker video course by Chris Fidao](https://serversforhackers.com/shipping-docker) +- [Docker for PHP Developers eBook and video course by Paul Redmond](https://leanpub.com/docker-for-php-developers) +- [Docker for Developers eBook by Chris Tankersley](https://leanpub.com/dockerfordevs) +- [Docker YouTube video playlist that I've curated](https://www.youtube.com/playlist?list=PLHn41Ay7w7kdt1thq6N6hpVABb2YNI50b) +- [AltF4Stream on Twitch](https://www.twitch.tv/thealtf4stream) +- [The "Full Stack Live" stream on Twitch](https://www.twitch.tv/fullstacklive) +- ["Docker Mastery" course on Udemy](https://www.udemy.com/course/docker-mastery) + +I'm sure that I'll remember some others after I publish this post, but I'll come back and add them here afterward. + +Know of any more? Let me know on [Twitter](https://twitter.com/opdavies). diff --git a/source/_posts/drupal-automated-testing-workshop-notes.md b/source/_posts/drupal-automated-testing-workshop-notes.md new file mode 100644 index 00000000..9c254dbe --- /dev/null +++ b/source/_posts/drupal-automated-testing-workshop-notes.md @@ -0,0 +1,13 @@ +--- +title: Drupal automated testing workshop notes +description: If you attended my automated testing with Drupal workshop this weekend, here are the links. +tags: [Drupal] +date: 2020-11-15 +--- + +If you attended my automated testing and test driven development workshop this weekend at DrupalCamp NYC, or at DrupalCamp London in March, [here are the notes][notes] that we went through during the session. + +There is also [a separate code repository][code] that contains the example code, broken down commit by commit, and uses GitHub Actions to run the tests automatically on each push. + +[code]: https://github.com/opdavies/workshop-drupal-automated-testing-code +[notes]: https://github.com/opdavies/workshop-drupal-automated-testing diff --git a/source/_posts/github-actions-phpunit-colours.md b/source/_posts/github-actions-phpunit-colours.md new file mode 100644 index 00000000..dbbdda98 --- /dev/null +++ b/source/_posts/github-actions-phpunit-colours.md @@ -0,0 +1,8 @@ +--- +title: Coloured output with PHPUnit and GitHub Actions +description: How to have colours in your PHPUnit output when running with GitHub Actions. +date: 2020-08-12 +tags: [PHPUnit, Testing, GitHub Actions] +--- + +10 years ago today, I started my first full-time Web Developer job, working for @HorseAndCountry on their (at the time) #Drupal 6 website.
— Oliver Davies (@opdavies) July 19, 2020
diff --git a/source/_posts/ignoring-phpcs-sniffs-phpunit-tests.md b/source/_posts/ignoring-phpcs-sniffs-phpunit-tests.md new file mode 100644 index 00000000..63944fe5 --- /dev/null +++ b/source/_posts/ignoring-phpcs-sniffs-phpunit-tests.md @@ -0,0 +1,73 @@ +--- +title: Ignoring PHPCS sniffs for PHPUnit tests +description: How to exclude certain PHPCS sniffs within your PHPUnit tests, so that you can write your tests methods how you'd like without getting coding standards errors. +tags: [Drupal, Drupal Planet, PHP, PHPUnit] +date: 2021-01-04 +--- + +**Note:** This post is written with a Drupal context, but applies to any PHP project. + +This is a test that I wrote recently, which uses the camel case method name that is recommended by the Drupal and PSR-2 coding standards: + +```php +public function testThatPathAliasesAreNotTransferredToTheNewLanguageWhenOneIsAdded(): void { + // ... +} +``` +It has a long method name that describes the test that is being run. However, it's quite hard to read. Generally, I prefer to write tests like this, using the `@test` annotation (so that I can remove the `test` prefix) and snake case method names: + +```php +/** @test */ +public function path_aliases_are_not_transferred_to_the_new_language_when_one_is_added(): void { + // ... +} +``` + +This to me is a lot easier to read, particularly for long and descriptive test method names, and is commonly used within parts of the PHP community. + +This approach, however, can result in some errors from PHPCS: + +- The open comment tag must be the only content on the line +- Public method name "DefinedLanguageNodeTest::path_aliases_are_not_transferred_to_the_new_language_when_one_is_added" is not in lowerCamel format + +We can avoid the errors by excluding the files when running PHPCS, or modifying rules within phpcs.xml (or phpcs.xml.dist) file to change the severity value for the rules. These approaches would mean either ignoring all PHPCS sniffs within the test files or ignoring some checks within all files, neither of which is an ideal approach. + +## Ignoring whole or partial files + +We can tell PHPCS to ignore whole or partial files by adding comments - there's [an example of this](https://git.drupalcode.org/project/drupal/-/blob/ad34608ab0bb115c53f4aaa0573c30dd8dc5b23a/sites/default/default.settings.php#L3 "Drupal's default.settings.php file with a 'coding standards ignore' comment") at the top of `default.settings.php` file: + +```php +// @codingStandardsIgnoreFile +``` + +The `@codingStandards` syntax, however, is deprecated and will be removed in PHP_CodeSniffer version 4.0. The new syntax to do this is: + +```php +// phpcs:ignoreFile +``` + +As well as `phpcs:ignoreFile` which ignores all of the sniffs in an entire file, there are also commands to disable and re-enable PHPCS at different points within the same file: + +```php +// Stop PHPCS checking. +// phpcs:disable + +// Start PHPCS checking. +// phpcs:enable +``` + +## Disabling specific rules in a file + +As well as excluding a section of code from checks, with `phpcs:ignore` you can also specify a list of sniffs to ignore. For example: + +```php +// phpcs:disable Drupal.Commenting.DocComment, Drupal.NamingConventions.ValidFunctionName +``` + +By adding this to the top of the test class, these specific sniffs will be ignored so no errors will be reported, and any other sniffs will continue to work as normal. + +If you're unsure what the names of the sniffs are that you want to ignore, add `-s` to the PHPCS command to have it include the sniff names in its output. + +For more information on ignoring files, folders, part of files, and limiting results, see the [Advanced Usage page for the PHP CodeSniffer project](https://github.com/squizlabs/PHP_CodeSniffer/wiki/Advanced-Usage) on GitHub. + +You can also see this being used in [some of the tests for this website](https://github.com/opdavies/oliverdavies-uk/tree/production/web/modules/custom/blog/tests/src/Kernel). diff --git a/source/_posts/interview-drupal-expert-code-enigma.md b/source/_posts/interview-drupal-expert-code-enigma.md new file mode 100644 index 00000000..48c6a783 --- /dev/null +++ b/source/_posts/interview-drupal-expert-code-enigma.md @@ -0,0 +1,10 @@ +--- +title: Interview with a Drupal Expert (with Code Enigma) +description: I recently did an interview with Code Enigma for their blog. +tags: [Drupal, Interview, Personal] +date: 2020-08-31 +--- + +I recently did an interview with Drupal and PHP agency [Code Enigma](https://www.codeenigma.com) for their blog, in which we talked about getting started in the Drupal community, [working for 10 years full-time with Drupal and PHP](/blog/10-years-working-full-time-drupal-php), companies adopting open source technologies, and my favourite Drupal events. + +To read it, go to [the Code Enigma blog](https://blog.codeenigma.com/interview-with-a-drupal-expert-9fcd8e0fad28 "'Interview with a Drupal Expert' on the Code Enigma blog"). diff --git a/source/_posts/migrating-drupal-8-introduction.md b/source/_posts/migrating-drupal-8-introduction.md new file mode 100644 index 00000000..f42075e0 --- /dev/null +++ b/source/_posts/migrating-drupal-8-introduction.md @@ -0,0 +1,19 @@ +--- +title: 'Migrating to Drupal 8: Introduction' +description: An introduction to the 'Migrating to Drupal 8' blog post series. +date: 2020-08-12 +tags: [Drupal, Drupal 8, Drupal Planet] +--- + +I recently finished porting this website from a static site generator to Drupal 8, meaning that this site has now been powered by three different major versions of Drupal (6, 7 and 8) as well as by two static site generators since it was first launched in early 2010. + +The majority of the content was imported using migrations from JSON feeds that I created. This included: + +- Blog tags +- Blog posts +- Talks +- Redirects + +In some follow-up posts, I'll be looking at each migration separately, describing any issues and look at how it was used to import its respective content. + +I'll update this post with the links to the follow-up posts, and they are also available from the [blog series' page](/taxonomy/term/165). diff --git a/source/_posts/presenting-pdf-slides-using-pdfpc-pdf-presenter-console.md b/source/_posts/presenting-pdf-slides-using-pdfpc-pdf-presenter-console.md new file mode 100644 index 00000000..70b72800 --- /dev/null +++ b/source/_posts/presenting-pdf-slides-using-pdfpc-pdf-presenter-console.md @@ -0,0 +1,90 @@ +--- +title: Presenting from PDF slides using pdfpc (PDF Presenter Console) +description: My notes from using pdfpc (PDF Presenter Console). +tags: [Speaking] +date: 2021-04-23 +--- + +I recently started using PDF files for presentation slides and gave [a talk about a tool called rst2pdf](/talks/building-presenting-slide-decks-rst2pdf) that I use to write slides in reStructuredText and convert them to PDF. This blog post is about another tool that I use to present from the PDF file, which is called the [PDF Presenter Console](https://pdfpc.github.io "The pdfpc website") (or `pdfpc`). + +This is the basic version that you get by running `pdfpc slides.pdf`: + +If you're using GitHub Actions to run tests for your PHP projects and want colours in the output, append `--colors=always` to your phpunit command. pic.twitter.com/0AVwxCP4Bv
— Oliver Davies (@opdavies) May 13, 2020
+ +As well as this, I also applied to some open calls for papers for remote conferences, such as [CMS Philly](https://cmsphilly.org "The CMS Philly conference") (formerly Drupaldelphia) that was taking place online this year. + +At the time of writing, these are the talks that I've given remotely or are already planned for future dates. I'll be updating this list going forward as new talks are added, as well as my [talks page](/talks "My upcoming and past talks"). + +If you'd like me to speak at your online conference or user group and be added to this list, please contact me and we can see if we can find a suitable date. + +## Test Driven Drupal + +An overview of automated testing in Drupal, and a demo of building a new Drupal 8 (or 9) module using test driven development. + +- [NWDUG](http://nwdrupal.org.uk) - 11th May +- [BADCamp 2020](https://2020.badcamp.org/session/tdd-test-driven-drupal) - 16th October +- [DrupalCon Europe 2020](https://events.drupal.org/europe2020/sessions/tdd-test-driven-drupal) - 8th December + +## Deploying PHP with Ansible and Ansistrano + +How to use Ansible, Ansible Vault and Ansistrano to deploy PHP applications, using a Drupal 8 application for a demo. + +- [Drupal Edinburgh](https://www.meetup.com/Drupal-Edinburgh/events/267905594) - 11th March +- [CMS Philly](https://cmsphilly.org) - 30th April +- [Drupal Yorkshire](https://www.meetup.com/DrupalYorkshire/events/zwzsfpybchbcc) - 20th May +- [PHP London](https://www.meetup.com/phplondon/events/270930524) - 4th June +- [PHP North East](https://www.meetup.com/phpnortheast) - 16th June +- [PHP Sussex](https://www.meetup.com/PHP-Sussex) - 1st July +- [Midwest PHP 2021](https://midwestphp.org/talks/1q5XUF2tTdXXLYOoujMkpF/Deploying_PHP_applications_with_Ansible,_Ansible_Vault_and_Ansistrano) - 23rd April 2021 + +## Taking Flight with Tailwind CSS + +An introduction to utility-based CSS and how to use Tailwind CSS in PHP projects using tools such as Webpack Encore and Laravel Mix. + +- [CMS Philly](https://cmsphilly.org) - 30th April +- [PHP Hampshire](https://www.meetup.com/meetup-group-yzpbvTYv) - 8th July +- [Drupal Yorkshire](https://www.meetup.com/DrupalYorkshire/events/zwzsfpybclbbc) - 20th August +- [DigitalCamp Atlanta](https://www.drupalcampatlanta.com/2020/sessions/taking-flight-tailwind-css) - 11th September +- [Bristol JS](https://techtalks.io/events/f8e26038-2561-484e-8a74-7a1e3a0369b8) - 30th September +- [Drupal Virtual Cafe](https://groups.drupal.org/node/536142) (Drupal Kyiv) - 15th October +- [PHP Cambridge](https://www.meetup.com/phpcambridge/events/273686561) - 19th January 2021 +- [Nashville PHP](https://www.meetup.com/nashvillephp/events/kzkdwryccdbmb) - 9th February 2021 + +## Updating to Drupal 9 + +How to update your site to Drupal 9, and why it's much different to any major Drupal version upgrade before! + +- [Drupal NYC](https://ti.to/drupalnyc/meetup-2020-08-05) - 2nd September +- [Leeds PHP](https://www.meetup.com/leedsphp/events/272504993) - 23rd September +- [Midwest PHP 2021](https://midwestphp.org/talks/7C0m4I87vq72cDoXvsHFRp/Upgrading_your_site_to_Drupal_9) - 22nd April 2021 + +## Working with Workspace + +- [NWDUG](https://www.meetup.com/nwdrupal/events/272098270) - 11th August (lightning talk) +- [PHP South West](https://www.meetup.com/php-sw/events/272787346) - 9th September (lightning talk) +- PHP North West - 2nd February 2021 + +## Automated testing and test-driven development in Drupal 8 (workshop) + +- [DrupalCamp London](https://drupalcamp.london/training/Automated-Testing-and-Test-Driven-Development-in-Drupal-8) - 13th March (in-person, just before UK lockdown) +- [DrupalCamp NYC](https://2020.drupalcamp.nyc/training/automated-testing-and-test-driven-development-drupal-8) - 14th November + +## Building slides and presenting with rst2pdf + +- [PHP South Wales](https://www.meetup.com/PHP-South-Wales/events/275625320) - January 28th 2021 + +## Soaring with utility CSS and Tailwind (workshop) + +- [DrupalCamp Florida 2021](https://www.fldrupal.camp/training/soaring-utility-css-and-tailwind) - Feburary 18th 2021 diff --git a/source/_posts/streaming-spabby-gary-hockin-about-drupal.md b/source/_posts/streaming-spabby-gary-hockin-about-drupal.md new file mode 100644 index 00000000..ee8bfdd9 --- /dev/null +++ b/source/_posts/streaming-spabby-gary-hockin-about-drupal.md @@ -0,0 +1,18 @@ +--- +title: Streaming with Spabby (Gary Hockin) about Drupal +description: I recently joined my friend Gary on his stream to discuss Drupal. +tags: [Drupal, PHP, Drupal 9, Streaming] +date: 2020-07-30 +--- + +I recently joined my friend and fellow [PHP South Wales](https://phpsouthwales.uk) regular [Gary Hockin](https://twitter.com/GeeH "Gary on Twitter") (aka GeeH, aka Spabby) on his stream to discuss one of my favourite topics, Drupal. + +I've noticed that a lot of Developers within the wider PHP community have maybe used or looked at an earlier version of Drupal, like 4, 5 or 6, but not a more recent version, so this seemed like a good opportunity to discuss and demo some of the modern features and improvements in Drupal to Gary's mostly PHP focussed audience. + +You can currently [view the video on Gary's Twitch page](https://www.twitch.tv/videos/689269586), or I've embedded it below. + +We touched on the topic of decoupled Drupal, and we're planning a follow-up stream where we pair program and set up Drupal together with a front-end React application, which would be great fun! + +#Drupal and #PHP usergroups (and others):
— Oliver Davies (@opdavies) April 16, 2020
I have three talks that I'd be happy to do for any remote meetups:
- Deploying PHP applications with Ansible, Ansible Vault and Ansistrano
- Taking Flight with Tailwind CSS
- TDD - Test Driven Drupal
Ping me if you need a speaker...