tome export
This commit is contained in:
parent
d689be14f2
commit
328502c279
1646 changed files with 110071 additions and 7 deletions
|
@ -34,17 +34,17 @@
|
|||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-02T07:25:00+00:00"
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"imported": [
|
||||
{
|
||||
"value": "2025-05-02T07:25:00+00:00"
|
||||
"value": "2025-05-11T06:11:07+00:00"
|
||||
}
|
||||
],
|
||||
"next": [
|
||||
{
|
||||
"value": "2025-05-02T19:25:00+00:00"
|
||||
"value": "2025-05-11T18:11:07+00:00"
|
||||
}
|
||||
],
|
||||
"queued": [
|
||||
|
@ -67,7 +67,7 @@
|
|||
],
|
||||
"item_count": [
|
||||
{
|
||||
"value": 853
|
||||
"value": 1673
|
||||
}
|
||||
]
|
||||
}
|
File diff suppressed because it is too large
Load diff
100
content/node.00519b3f-3eaf-4595-9620-4ff1a1fb3b6d.json
Normal file
100
content/node.00519b3f-3eaf-4595-9620-4ff1a1fb3b6d.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "00519b3f-3eaf-4595-9620-4ff1a1fb3b6d"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Building different-looking UIs with consistent class names"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-11-22T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/11\/22\/building-different-looking-uis-with-consistent-class-names",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Something I've said when <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/taking-flight-with-tailwind-css.md\">speaking about Tailwind CSS<\/a> and also during <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/19\/tailwind-css-v4-is-so-easy-to-set-up\">my recent consulting engagement<\/a>, is that you can build dramatically different-looking UIs even though you're using the same class names.<\/p>\n\n<p>For example, I've rebuilt <a href=\"https:\/\/rebuilding-bartik.oliverdavies.uk\">the Bartik theme<\/a>, <a href=\"https:\/\/rebuilding-acquia.oliverdavies.uk\">the Acquia hosting dashboard<\/a> and <a href=\"https:\/\/rebuilding-bristol-js.oliverdavies.uk\">various other UIs<\/a> for talk demos - none of which look the same or are even similar.<\/p>\n\n<p>This website is themed with Tailwind CSS.<\/p>\n\n<p>As the classes are very low-level, there is no \"Tailwind-looking website\" like there is with other CSS frameworks.<\/p>\n\n<p>And, when you move to other application, the same classes are there and available to use.<\/p>\n\n<p>You just need to customise them, use what you need and ignore what you don't.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Something I've said when <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/taking-flight-with-tailwind-css.md\">speaking about Tailwind CSS<\/a> and also during <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/19\/tailwind-css-v4-is-so-easy-to-set-up\">my recent consulting engagement<\/a>, is that you can build dramatically different-looking UIs even though you're using the same class names.<\/p>\n\n<p>For example, I've rebuilt <a href=\"https:\/\/rebuilding-bartik.oliverdavies.uk\">the Bartik theme<\/a>, <a href=\"https:\/\/rebuilding-acquia.oliverdavies.uk\">the Acquia hosting dashboard<\/a> and <a href=\"https:\/\/rebuilding-bristol-js.oliverdavies.uk\">various other UIs<\/a> for talk demos - none of which look the same or are even similar.<\/p>\n\n<p>This website is themed with Tailwind CSS.<\/p>\n\n<p>As the classes are very low-level, there is no \"Tailwind-looking website\" like there is with other CSS frameworks.<\/p>\n\n<p>And, when you move to other application, the same classes are there and available to use.<\/p>\n\n<p>You just need to customise them, use what you need and ignore what you don't.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "5b4b4815f291bc6b2a7f37552c3d1102",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.01090310-9114-436a-93d8-55c966a816ea.json
Normal file
100
content/node.01090310-9114-436a-93d8-55c966a816ea.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "01090310-9114-436a-93d8-55c966a816ea"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "How long should a feature flag live?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-06-05T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/06\/05\/how-long-should-a-feature-flag-live",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Instead of creating a branch that lives for as long as the code takes to write, if it's behind a feature flag, the code can be merged into the mainline branch without affecting the rest of the codebase.<\/p>\n\n<p>Being able to release changes incrementally lowers the risk compared to releasing a large change all at once.<\/p>\n\n<p>But the same issue can occur with feature flags, and the longer that code is behind a feature flag, the more risk there will be when enabling the feature.<\/p>\n\n<p>So, like feature branches, feature flags should be short-lived and only used for as long as is needed to create the first releasable version of the feature. The feature flag can be removed once the feature is live, and the feature can continue to be iterated on and improved.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Instead of creating a branch that lives for as long as the code takes to write, if it's behind a feature flag, the code can be merged into the mainline branch without affecting the rest of the codebase.<\/p>\n\n<p>Being able to release changes incrementally lowers the risk compared to releasing a large change all at once.<\/p>\n\n<p>But the same issue can occur with feature flags, and the longer that code is behind a feature flag, the more risk there will be when enabling the feature.<\/p>\n\n<p>So, like feature branches, feature flags should be short-lived and only used for as long as is needed to create the first releasable version of the feature. The feature flag can be removed once the feature is live, and the feature can continue to be iterated on and improved.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d7e1f6d61d5541ac83cd2bfe9bc3e669",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.012bd3a8-e679-4f0c-acf3-cef4523591f7.json
Normal file
100
content/node.012bd3a8-e679-4f0c-acf3-cef4523591f7.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "012bd3a8-e679-4f0c-acf3-cef4523591f7"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Open source software all the way down"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-12-07T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/12\/07\/open-source",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As someone who develops with open-source software such as Drupal, Symfony, and Sculpin and uses Linux to <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/28\/running-nixos-in-the-cloud\">host my applications<\/a> and <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/23\/no-more-random-packages\">configure my laptop<\/a>, I've recently started to explore creating a home lab and self-hosting services based on other open source software.<\/p>\n\n<p>I've started using Jellyfin for media management and playback, Immich for photos, Gitea for hosting my private Git repositories, and Tube Archivist for backing up YouTube videos.<\/p>\n\n<p>There are a lot of other popular applications that people self-host that I want to look at, as well as maybe hosting my own website.<\/p>\n\n<p>I've removed proprietary note-taking applications <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/10\/write-plain-text-files\">in favour of plain text files<\/a> and continued searching for free and open source alternatives to services I've used.<\/p>\n\n<p>My ethos is to be open source first and to favour an open source solution if there is one.<\/p>\n\n<p>And if there isn't, I can write one.<\/p>\n\n<p>As well as creating free and open source software, I want to use it as much as I can as well as using open source software to create my open source software.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As someone who develops with open-source software such as Drupal, Symfony, and Sculpin and uses Linux to <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/28\/running-nixos-in-the-cloud\">host my applications<\/a> and <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/23\/no-more-random-packages\">configure my laptop<\/a>, I've recently started to explore creating a home lab and self-hosting services based on other open source software.<\/p>\n\n<p>I've started using Jellyfin for media management and playback, Immich for photos, Gitea for hosting my private Git repositories, and Tube Archivist for backing up YouTube videos.<\/p>\n\n<p>There are a lot of other popular applications that people self-host that I want to look at, as well as maybe hosting my own website.<\/p>\n\n<p>I've removed proprietary note-taking applications <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/10\/write-plain-text-files\">in favour of plain text files<\/a> and continued searching for free and open source alternatives to services I've used.<\/p>\n\n<p>My ethos is to be open source first and to favour an open source solution if there is one.<\/p>\n\n<p>And if there isn't, I can write one.<\/p>\n\n<p>As well as creating free and open source software, I want to use it as much as I can as well as using open source software to create my open source software.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "826ea7f42a178becea87291123dedc78",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.015fc769-e2c2-49c2-9eb6-95bfc3bfe06e.json
Normal file
100
content/node.015fc769-e2c2-49c2-9eb6-95bfc3bfe06e.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "015fc769-e2c2-49c2-9eb6-95bfc3bfe06e"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Running tests in parallel with Paratest"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-02-07T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/02\/07\/running-tests-in-parallel-with-paratest",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Something that I've recently added to my PHP projects is <a href=\"https:\/\/github.com\/paratestphp\/paratest\">Paratest<\/a>.<\/p>\n\n<p>It adds parallel testing to PHPUnit, so your tests will be run in parallel instead of sequentially.<\/p>\n\n<p>For the example module in my <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">automated testing in Drupal email course<\/a>, using Paratest reduces the execution time from ~16 seconds to ~8 seconds.<\/p>\n\n<p>In a client project with 136 tests, it reduces the time from four and a half minutes to less than two minutes.<\/p>\n\n<p>This is a big improvement just from running a single Composer command to add Paratest.<\/p>\n\n<p>There's also <a href=\"https:\/\/www.drupal.org\/project\/drupal\/issues\/2781123\">an open issue<\/a> for using it for Drupal core's tests, which is something I'll keep an eye on and will look to contribute to.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Something that I've recently added to my PHP projects is <a href=\"https:\/\/github.com\/paratestphp\/paratest\">Paratest<\/a>.<\/p>\n\n<p>It adds parallel testing to PHPUnit, so your tests will be run in parallel instead of sequentially.<\/p>\n\n<p>For the example module in my <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">automated testing in Drupal email course<\/a>, using Paratest reduces the execution time from ~16 seconds to ~8 seconds.<\/p>\n\n<p>In a client project with 136 tests, it reduces the time from four and a half minutes to less than two minutes.<\/p>\n\n<p>This is a big improvement just from running a single Composer command to add Paratest.<\/p>\n\n<p>There's also <a href=\"https:\/\/www.drupal.org\/project\/drupal\/issues\/2781123\">an open issue<\/a> for using it for Drupal core's tests, which is something I'll keep an eye on and will look to contribute to.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d6723cf0326f529b61786870511d23ff",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.01d71d60-5764-4631-9294-38db7515d1d4.json
Normal file
100
content/node.01d71d60-5764-4631-9294-38db7515d1d4.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "01d71d60-5764-4631-9294-38db7515d1d4"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "The best solution is the one that gets the tests to pass\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-10-04T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/10\/04\/the-best-solution-is-the-one-that-gets-the-tests-to-pass",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As I said yesterday, there is no perfect solution or approach for every situation.<\/p>\n\n<p>However, when doing test-driven development, there is a best solution.<\/p>\n\n<p>The simplest thing that gets a failing test to pass.<\/p>\n\n<p>Whether it's hard-coding a return value or putting the initial logic in a Controller, that's the objective.<\/p>\n\n<p>Once the test is passing, you can refactor the code or continue writing tests, which will each have their own best solution.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As I said yesterday, there is no perfect solution or approach for every situation.<\/p>\n\n<p>However, when doing test-driven development, there is a best solution.<\/p>\n\n<p>The simplest thing that gets a failing test to pass.<\/p>\n\n<p>Whether it's hard-coding a return value or putting the initial logic in a Controller, that's the objective.<\/p>\n\n<p>Once the test is passing, you can refactor the code or continue writing tests, which will each have their own best solution.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "f999f40729d1c4017022ac0e4fd81a1d",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.01edae5a-f2cd-4e26-8de3-999d4ea7af3a.json
Normal file
100
content/node.01edae5a-f2cd-4e26-8de3-999d4ea7af3a.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "01edae5a-f2cd-4e26-8de3-999d4ea7af3a"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Docker or Nix?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-07-02T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/07\/02\/docker-or-nix",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I've been a Nix user for about a year, starting with its package manager on my previously installed Linux distribution.<\/p>\n\n<p>I started to use Home Manager for my user configuration and dotfiles and later switched to the NixOS operating system.<\/p>\n\n<h2 id=\"using-nix-for-software-development\">Using Nix for software development<\/h2>\n\n<p>I've also been using Nix Flakes for per-project configuration.<\/p>\n\n<p>A Flake file is a simple file written in the Nix language that defines the project's dependencies and installs them from the Nix package manager.<\/p>\n\n<p>Here is an example Flake for a PHP CLI application:<\/p>\n\n<pre><code class=\"nix\">{\n\u00a0 inputs.nixpkgs.url = \"github:NixOS\/nixpkgs\/nixos-unstable\";\n\n\u00a0 outputs = inputs@{ flake-parts, ... }:\n\u00a0 \u00a0 flake-parts.lib.mkFlake { inherit inputs; } {\n\u00a0 \u00a0 \u00a0 systems = [ \"x86_64-linux\" ];\n\n\u00a0 \u00a0 \u00a0 perSystem = { config, self', inputs', pkgs, system, ... }: {\n\u00a0 \u00a0 \u00a0 \u00a0 devShells = {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 default = pkgs.mkShell {\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 buildInputs = with pkgs; [ php82 php82Packages.composer ];\n\u00a0 \u00a0 \u00a0 \u00a0 \u00a0 };\n\u00a0 \u00a0 \u00a0 \u00a0 };\n\u00a0 \u00a0 \u00a0 };\n\u00a0 \u00a0 };\n}\n<\/code><\/pre>\n\n<p>It declares that PHP 8.2 and Composer are available, even if I have different versions installed globally.<\/p>\n\n<h2 id=\"will-nix-replace-docker%3F\">Will Nix replace Docker?<\/h2>\n\n<p>Nix and Flakes have replaced Docker for me on some projects.<\/p>\n\n<p>If I have a simple setup and need a specific version of PHP or Node and some additional programs, I can get those from the Flake.<\/p>\n\n<p>I don't know if it'll replace Docker for me completely and work on more complex projects, but it's working well for me where I'm using it.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I've been a Nix user for about a year, starting with its package manager on my previously installed Linux distribution.<\/p>\n\n<p>I started to use Home Manager for my user configuration and dotfiles and later switched to the NixOS operating system.<\/p>\n\n<h2 id=\"using-nix-for-software-development\">Using Nix for software development<\/h2>\n\n<p>I've also been using Nix Flakes for per-project configuration.<\/p>\n\n<p>A Flake file is a simple file written in the Nix language that defines the project's dependencies and installs them from the Nix package manager.<\/p>\n\n<p>Here is an example Flake for a PHP CLI application:<\/p>\n\n<pre><code class=\"nix\">{\n inputs.nixpkgs.url = \"github:NixOS\/nixpkgs\/nixos-unstable\";\n\n outputs = inputs@{ flake-parts, ... }:\n flake-parts.lib.mkFlake { inherit inputs; } {\n systems = [ \"x86_64-linux\" ];\n\n perSystem = { config, self', inputs', pkgs, system, ... }: {\n devShells = {\n default = pkgs.mkShell {\n buildInputs = with pkgs; [ php82 php82Packages.composer ];\n };\n };\n };\n };\n}\n<\/code><\/pre>\n\n<p>It declares that PHP 8.2 and Composer are available, even if I have different versions installed globally.<\/p>\n\n<h2 id=\"will-nix-replace-docker%3F\">Will Nix replace Docker?<\/h2>\n\n<p>Nix and Flakes have replaced Docker for me on some projects.<\/p>\n\n<p>If I have a simple setup and need a specific version of PHP or Node and some additional programs, I can get those from the Flake.<\/p>\n\n<p>I don't know if it'll replace Docker for me completely and work on more complex projects, but it's working well for me where I'm using it.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "7f55d425fa5b0836f5c8d0f6980cc54e",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.01f4015e-252c-4e96-9e0c-91cf1045044b.json
Normal file
100
content/node.01f4015e-252c-4e96-9e0c-91cf1045044b.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "01f4015e-252c-4e96-9e0c-91cf1045044b"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Busy working on client projects\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-03-02T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/03\/02\/busy-working-on-client-projects",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As well as starting to speak again at conferences and meetups, I've been very busy lately with various client projects. I've been working on completing the next phase and launch of the next website for a long-term client and handed over some other completed projects.<\/p>\n\n<p>This has affected me sending out these emails every day and I missed a few days last month.<\/p>\n\n<p>I'll do better!<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As well as starting to speak again at conferences and meetups, I've been very busy lately with various client projects. I've been working on completing the next phase and launch of the next website for a long-term client and handed over some other completed projects.<\/p>\n\n<p>This has affected me sending out these emails every day and I missed a few days last month.<\/p>\n\n<p>I'll do better!<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "6b223577d98aafcacf18ecbf423a3497",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.020b3de3-da10-4107-9616-a40786092144.json
Normal file
100
content/node.020b3de3-da10-4107-9616-a40786092144.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "020b3de3-da10-4107-9616-a40786092144"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't estimate separately for testing\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-08-13T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/08\/13\/dont-estimate-separately-for-testing",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>A common issue I see for people introducing automated testing is estimating the testing and implementation of a task separately.<\/p>\n\n<p>Something like, \"It'll take x to do the work and x to write the tests for it\".<\/p>\n\n<p>As well as implying you'd write all the code and then all the tests or vice versa, if you provide separate estimates, it's easy for someone to think the tests are optional and can be removed.<\/p>\n\n<p>If you provide one estimate for both, this can't happen.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>A common issue I see for people introducing automated testing is estimating the testing and implementation of a task separately.<\/p>\n\n<p>Something like, \"It'll take x to do the work and x to write the tests for it\".<\/p>\n\n<p>As well as implying you'd write all the code and then all the tests or vice versa, if you provide separate estimates, it's easy for someone to think the tests are optional and can be removed.<\/p>\n\n<p>If you provide one estimate for both, this can't happen.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "b2a503f52e0d13b65158e0770ce490d5",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.027d3741-bf06-4348-9293-9993b2adb5e3.json
Normal file
100
content/node.027d3741-bf06-4348-9293-9993b2adb5e3.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "027d3741-bf06-4348-9293-9993b2adb5e3"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "One more month of Drupal 7"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-12-06T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/12\/06\/one-more-month",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>On the 5th of January, Drupal 7 will be end of life and have no further updates.<\/p>\n\n<p><a href=\"https:\/\/www.drupal.org\/blog\/drupal-70-is-released\">Released in January 2011<\/a>, Drupal 7 will be 14 years old in January and will have outlived Drupal 8 and 9 which are already unsupported.<\/p>\n\n<p>There are a lot of Drupal 7 sites still in production, but it's been interesting to see usage numbers for the Override Node Options module <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/16\/an-interesting-thing-i-spotted-about-the-override-node-options-module\">decrease for Drupal 7 and increase for Drupal 8+<\/a> over the last year.<\/p>\n\n<p>I'm excited to see Drupal usage continue to move towards the newer versions so everyone can benefit from the new features and improvements in Drupal 10 and 11 and the new Drupal CMS project.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>On the 5th of January, Drupal 7 will be end of life and have no further updates.<\/p>\n\n<p><a href=\"https:\/\/www.drupal.org\/blog\/drupal-70-is-released\">Released in January 2011<\/a>, Drupal 7 will be 14 years old in January and will have outlived Drupal 8 and 9 which are already unsupported.<\/p>\n\n<p>There are a lot of Drupal 7 sites still in production, but it's been interesting to see usage numbers for the Override Node Options module <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/16\/an-interesting-thing-i-spotted-about-the-override-node-options-module\">decrease for Drupal 7 and increase for Drupal 8+<\/a> over the last year.<\/p>\n\n<p>I'm excited to see Drupal usage continue to move towards the newer versions so everyone can benefit from the new features and improvements in Drupal 10 and 11 and the new Drupal CMS project.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e93df0be19a187ce2cfa64f7e7f55371",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.04078ba0-6948-42fc-8417-0765f70d4482.json
Normal file
100
content/node.04078ba0-6948-42fc-8417-0765f70d4482.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "04078ba0-6948-42fc-8417-0765f70d4482"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Is testing a chore?"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-09-29T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/09\/29\/is-testing-a-chore",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p><a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/09\/28\/testing-personal-projects\">Do some Developers skip writing tests for their personal projects<\/a> because they think it's a chore?<\/p>\n\n<p>If they've written the code, so they then think it's too much work to write tests or need to move on to the next task?<\/p>\n\n<p>Is it boring to write tests for code that's already written and will pass straight away?<\/p>\n\n<p>This is why I do test-driven development and start with a failing test and then write code to make it pass.<\/p>\n\n<p>Then, I add more to the test until it fails and then get that to pass.<\/p>\n\n<p>When that test is finished, I'll move to a new test for a different piece of functionality.<\/p>\n\n<p>I like this approach of working in small feedback cycles and alternating between failing and passing tests.<\/p>\n\n<p>Testing this way isn't boring or a chore and much more interesting for me compared to writing all the code first and maybe writing the tests later.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p><a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/09\/28\/testing-personal-projects\">Do some Developers skip writing tests for their personal projects<\/a> because they think it's a chore?<\/p>\n\n<p>If they've written the code, so they then think it's too much work to write tests or need to move on to the next task?<\/p>\n\n<p>Is it boring to write tests for code that's already written and will pass straight away?<\/p>\n\n<p>This is why I do test-driven development and start with a failing test and then write code to make it pass.<\/p>\n\n<p>Then, I add more to the test until it fails and then get that to pass.<\/p>\n\n<p>When that test is finished, I'll move to a new test for a different piece of functionality.<\/p>\n\n<p>I like this approach of working in small feedback cycles and alternating between failing and passing tests.<\/p>\n\n<p>Testing this way isn't boring or a chore and much more interesting for me compared to writing all the code first and maybe writing the tests later.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "4b2d47376db0c887f15bedf49de35711",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.04174e15-cb3b-4d35-98be-9d2f5d89999a.json
Normal file
100
content/node.04174e15-cb3b-4d35-98be-9d2f5d89999a.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "04174e15-cb3b-4d35-98be-9d2f5d89999a"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "How and why I started using PostCSS\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-12-09T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/12\/09\/how-and-why-i-started-using-postcss",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I assume that, like many other Developers, when I started learning front-end development, I wrote normal, plain CSS and later discovered and adopted pre-processors like Less and Sass that added features such as variables and nesting to my stylesheets.<\/p>\n\n<p>This was the case when I first saw what became Tailwind CSS, which were some stylesheets written in Less and ported manually between projects.<\/p>\n\n<p>I remember watching one of those streams, and a fellow viewer suggested PostCSS, which Tailwind CSS would later be written in.<\/p>\n\n<p>PostCSS, a CSS post-processor rather than a pre-processor, has become my preferred way of writing CSS because of Tailwind.<\/p>\n\n<p>When I started using Tailwind in my projects, I was layering it on top of another CSS framework or styles that were written using Less or Sass, so I needed to pre-process them into CSS first and then run PostCSS - essentially running two build steps and adding to the build time.<\/p>\n\n<p>I moved to use PostCSS by default - removing one of the build steps.<\/p>\n\n<p>What I liked about it, as well as the quicker build times, was that I could start with plain CSS and add the extra features I needed. I didn't use all of Sass and Less' features, and now, if I needed nesting or real-time imports, I could add it via a PostCSS plugin or write my own.<\/p>\n\n<p>It's also quick and easy to use, using the PostCSS CLI tool and without more complex tools like Webpack.<\/p>\n\n<p>If you haven't tried PostCSS, I recommend taking a look.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I assume that, like many other Developers, when I started learning front-end development, I wrote normal, plain CSS and later discovered and adopted pre-processors like Less and Sass that added features such as variables and nesting to my stylesheets.<\/p>\n\n<p>This was the case when I first saw what became Tailwind CSS, which were some stylesheets written in Less and ported manually between projects.<\/p>\n\n<p>I remember watching one of those streams, and a fellow viewer suggested PostCSS, which Tailwind CSS would later be written in.<\/p>\n\n<p>PostCSS, a CSS post-processor rather than a pre-processor, has become my preferred way of writing CSS because of Tailwind.<\/p>\n\n<p>When I started using Tailwind in my projects, I was layering it on top of another CSS framework or styles that were written using Less or Sass, so I needed to pre-process them into CSS first and then run PostCSS - essentially running two build steps and adding to the build time.<\/p>\n\n<p>I moved to use PostCSS by default - removing one of the build steps.<\/p>\n\n<p>What I liked about it, as well as the quicker build times, was that I could start with plain CSS and add the extra features I needed. I didn't use all of Sass and Less' features, and now, if I needed nesting or real-time imports, I could add it via a PostCSS plugin or write my own.<\/p>\n\n<p>It's also quick and easy to use, using the PostCSS CLI tool and without more complex tools like Webpack.<\/p>\n\n<p>If you haven't tried PostCSS, I recommend taking a look.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "df6cac0e06b78b0e457c5d6f45c51e64",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.043d3014-82f2-445a-8bed-d576c51de576.json
Normal file
100
content/node.043d3014-82f2-445a-8bed-d576c51de576.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "043d3014-82f2-445a-8bed-d576c51de576"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Passing tests doesn't mean a working application"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-11-03T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/11\/03\/passing-tests-doesnt-mean-a-working-application",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Having a passing test suite doesn't mean everything in your application is working.<\/p>\n\n<p>It means the functionality you previously tested is working.<\/p>\n\n<p>There may be edge cases you haven't covered or whole tests you haven't written yet, which may be working or could be broken.<\/p>\n\n<p>If you have tests that were passing that are now failing, you know you've broken something.<\/p>\n\n<p>Something that was previously working is broken and shouldn't be deployed.<\/p>\n\n<p>That's why having tests is important - they give you the ability to identify and fix regressions before they are released.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Having a passing test suite doesn't mean everything in your application is working.<\/p>\n\n<p>It means the functionality you previously tested is working.<\/p>\n\n<p>There may be edge cases you haven't covered or whole tests you haven't written yet, which may be working or could be broken.<\/p>\n\n<p>If you have tests that were passing that are now failing, you know you've broken something.<\/p>\n\n<p>Something that was previously working is broken and shouldn't be deployed.<\/p>\n\n<p>That's why having tests is important - they give you the ability to identify and fix regressions before they are released.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "ee9c7fdfadc92a583c9a83309b14f644",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.04b6be07-d875-4952-95cf-512c788b61cd.json
Normal file
100
content/node.04b6be07-d875-4952-95cf-512c788b61cd.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "04b6be07-d875-4952-95cf-512c788b61cd"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Experimenting with the Nix package manager"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-09-26T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/09\/26\/experimenting-with-the-nix-package-manager",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>After seeing it on some recent live streams and YouTube videos, I've recently been trying out the Nix package manager and looking into how I might use it for my local environment setup - potentially replacing some of my current Ansible configuration.<\/p>\n\n<p>Separate from the NixOS operating system, Nix is a cross-platform package manager, so instead of using <code>apt<\/code> on Ubuntu and <code>brew<\/code> on macOS, you could run Nix on both and install from the 80,000 packages listed on https:\/\/search.nixos.org\/packages.<\/p>\n\n<p>There is a community project called Home Manager which can be installed alongside Nix which, similar to Stow or what I'm doing with Ansible, can manage your dotfiles or even create them from your Home Manager configuration, and can manage plugins for other tools such as ZSH and tmux.<\/p>\n\n<p>There's also a Nix feature called \"Flakes\" which allow you to separate configuration for different operating systems. I currently have a flake for Pop!_OS which installs all of my packages and a minimal flake for my WSL2 environment as some of the packages are installed in Windows instead of Linux.<\/p>\n\n<p>I can see Ansible still being used to set up my post-setup tasks such as cloning my initial projects, but the majority of my current Ansible setup where I'm installing and configuring packages I think could be moved to Nix.<\/p>\n\n<p>I have a work-in-progress Nix-based version <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/tree\/7c3436c553f8b81f99031e6bcddf385d47b7e785\">in my dotfiles repository<\/a> where you can also see <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/blob\/7c3436c553f8b81f99031e6bcddf385d47b7e785\/home-manager\/modules\/git.nix\">how I've configured Git with Home Manager<\/a>.<\/p>\n\n<p>I may install NixOS on an old laptop to test that out too.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>After seeing it on some recent live streams and YouTube videos, I've recently been trying out the Nix package manager and looking into how I might use it for my local environment setup - potentially replacing some of my current Ansible configuration.<\/p>\n\n<p>Separate from the NixOS operating system, Nix is a cross-platform package manager, so instead of using <code>apt<\/code> on Ubuntu and <code>brew<\/code> on macOS, you could run Nix on both and install from the 80,000 packages listed on https:\/\/search.nixos.org\/packages.<\/p>\n\n<p>There is a community project called Home Manager which can be installed alongside Nix which, similar to Stow or what I'm doing with Ansible, can manage your dotfiles or even create them from your Home Manager configuration, and can manage plugins for other tools such as ZSH and tmux.<\/p>\n\n<p>There's also a Nix feature called \"Flakes\" which allow you to separate configuration for different operating systems. I currently have a flake for Pop!_OS which installs all of my packages and a minimal flake for my WSL2 environment as some of the packages are installed in Windows instead of Linux.<\/p>\n\n<p>I can see Ansible still being used to set up my post-setup tasks such as cloning my initial projects, but the majority of my current Ansible setup where I'm installing and configuring packages I think could be moved to Nix.<\/p>\n\n<p>I have a work-in-progress Nix-based version <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/tree\/7c3436c553f8b81f99031e6bcddf385d47b7e785\">in my dotfiles repository<\/a> where you can also see <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/blob\/7c3436c553f8b81f99031e6bcddf385d47b7e785\/home-manager\/modules\/git.nix\">how I've configured Git with Home Manager<\/a>.<\/p>\n\n<p>I may install NixOS on an old laptop to test that out too.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "951d2d9e9835481f997f95a29b18efdf",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.054fd9e2-70f0-4d27-ab7a-e90de9c66847.json
Normal file
100
content/node.054fd9e2-70f0-4d27-ab7a-e90de9c66847.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "054fd9e2-70f0-4d27-ab7a-e90de9c66847"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't make assumptions"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-01-08T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/01\/08\/don-t-make-assumptions",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I was recently writing code for a project and found myself making assumptions about what I was writing.<\/p>\n\n<p>I was creating my own requirements.<\/p>\n\n<p>Something no-one asked for.<\/p>\n\n<p>I was assuming a value was always going to be a certain number of digits long.<\/p>\n\n<p>I was writing code that verified this was true or throw an Exception.<\/p>\n\n<p>Until I found out that that one of the values wasn't the same length as the others.<\/p>\n\n<p>This could be an error in the data or it could correct.<\/p>\n\n<p>No-one told me the lengths were always going to be the same.<\/p>\n\n<p>So why was I checking it?<\/p>\n\n<p>Why was I adding bugs to the code?<\/p>\n\n<p>I've reverted the code that checks the length of the value and gone to find clarification.<\/p>\n\n<p>If it's an issue, it'll be fixed in the source data.<\/p>\n\n<p>If the lengths should all be the same, I'll potentially re-add the check.<\/p>\n\n<p>Until I'm sure, I'll only write what's needed to deliver the feature and stop adding my own requirements and assumptions.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I was recently writing code for a project and found myself making assumptions about what I was writing.<\/p>\n\n<p>I was creating my own requirements.<\/p>\n\n<p>Something no-one asked for.<\/p>\n\n<p>I was assuming a value was always going to be a certain number of digits long.<\/p>\n\n<p>I was writing code that verified this was true or throw an Exception.<\/p>\n\n<p>Until I found out that that one of the values wasn't the same length as the others.<\/p>\n\n<p>This could be an error in the data or it could correct.<\/p>\n\n<p>No-one told me the lengths were always going to be the same.<\/p>\n\n<p>So why was I checking it?<\/p>\n\n<p>Why was I adding bugs to the code?<\/p>\n\n<p>I've reverted the code that checks the length of the value and gone to find clarification.<\/p>\n\n<p>If it's an issue, it'll be fixed in the source data.<\/p>\n\n<p>If the lengths should all be the same, I'll potentially re-add the check.<\/p>\n\n<p>Until I'm sure, I'll only write what's needed to deliver the feature and stop adding my own requirements and assumptions.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "2ddc207d69aba210aead45269c83988b",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0561e467-e490-405e-9a1a-4c54f969fac1.json
Normal file
100
content/node.0561e467-e490-405e-9a1a-4c54f969fac1.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0561e467-e490-405e-9a1a-4c54f969fac1"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "There is no perfect solution\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-10-03T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/10\/03\/there-is-no-perfect-solution",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Something I've said recently when mentoring bootcamp students and working with Junior Developers is that there isn't a perfect solution to each problem, and there are multiple ways to achieve the same result.<\/p>\n\n<p>Similarly, there isn't a perfect tool for every situation.<\/p>\n\n<p>You can use different tools and get the same outcome.<\/p>\n\n<p>In some of my early emails, I talked about <code>run<\/code> files and <code>just<\/code> - two ways to write project-specific commands or aliases that simplify complex commands or group multiple commands together.<\/p>\n\n<p>Both do the same thing, but each have pros and cons.<\/p>\n\n<p><code>run<\/code> files are files written in Bash, which are more verbose but can run anywhere.<\/p>\n\n<p>just is its own program that needs to be installed for it to be available, so Developers will need to have it installed, and it will need to be added to a CI pipeline to be available.<\/p>\n\n<p>I've had CI pipelines fail because they can't download just, and not because of anything in the application code.<\/p>\n\n<p>I like the simplicity of justfiles, though, and that the files are simpler.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>If there isn't a perfect solution, approach, or tool, it comes down to the pros and cons of each. Which option is best for you, your project, or your team?<\/p>\n\n<p>There isn't a \"one size fits all\" solution that works for everyone all the time.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Something I've said recently when mentoring bootcamp students and working with Junior Developers is that there isn't a perfect solution to each problem, and there are multiple ways to achieve the same result.<\/p>\n\n<p>Similarly, there isn't a perfect tool for every situation.<\/p>\n\n<p>You can use different tools and get the same outcome.<\/p>\n\n<p>In some of my early emails, I talked about <code>run<\/code> files and <code>just<\/code> - two ways to write project-specific commands or aliases that simplify complex commands or group multiple commands together.<\/p>\n\n<p>Both do the same thing, but each have pros and cons.<\/p>\n\n<p><code>run<\/code> files are files written in Bash, which are more verbose but can run anywhere.<\/p>\n\n<p>just is its own program that needs to be installed for it to be available, so Developers will need to have it installed, and it will need to be added to a CI pipeline to be available.<\/p>\n\n<p>I've had CI pipelines fail because they can't download just, and not because of anything in the application code.<\/p>\n\n<p>I like the simplicity of justfiles, though, and that the files are simpler.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>If there isn't a perfect solution, approach, or tool, it comes down to the pros and cons of each. Which option is best for you, your project, or your team?<\/p>\n\n<p>There isn't a \"one size fits all\" solution that works for everyone all the time.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "3579f9c1128a7333aacc2788d9b130b3",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.05fbebba-c68c-4066-9af7-bb8d8eee5501.json
Normal file
100
content/node.05fbebba-c68c-4066-9af7-bb8d8eee5501.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "05fbebba-c68c-4066-9af7-bb8d8eee5501"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "TDD and \"Unexpected errors\"\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-08-30T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/08\/30\/tdd-and-unexpected-errors",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>When working on projects, it's common to see messages like \"The website encountered an unexpected error. Please try again later.\".<\/p>\n\n<p>Usually, this is the message shown to the user, whilst a more detailed error message is logged for Developers to diagnose and fix the underlying error.<\/p>\n\n<p>The wording \"unexpected error\" has been intriguing to me, though. When do you expect an error?<\/p>\n\n<p>The best example I can think of for an expected error is when doing test-driven development.<\/p>\n\n<p>When doing TDD, you want to see an error to start as you start with a failing test.<\/p>\n\n<p>Then, you write the code to remove the error and get the test passing.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>When working on projects, it's common to see messages like \"The website encountered an unexpected error. Please try again later.\".<\/p>\n\n<p>Usually, this is the message shown to the user, whilst a more detailed error message is logged for Developers to diagnose and fix the underlying error.<\/p>\n\n<p>The wording \"unexpected error\" has been intriguing to me, though. When do you expect an error?<\/p>\n\n<p>The best example I can think of for an expected error is when doing test-driven development.<\/p>\n\n<p>When doing TDD, you want to see an error to start as you start with a failing test.<\/p>\n\n<p>Then, you write the code to remove the error and get the test passing.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d896323fbe54f5997b5e4edeb7c0c0dc",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.063ea37a-fd11-4f5d-83dc-374e0f1caba7.json
Normal file
100
content/node.063ea37a-fd11-4f5d-83dc-374e0f1caba7.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "063ea37a-fd11-4f5d-83dc-374e0f1caba7"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Strict typing in PHP"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-05-04T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/05\/04\/strict-typing-in-php",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I prefer writing and working with strictly typed code.<\/p>\n\n<p>One of the major improvements in PHP has been the option to enable strict types.<\/p>\n\n<p>For example, this code will usually not error and give the result:<\/p>\n\n<pre><code class=\"php\">function add(int $a, int $b): void\n{\n var_dump($a + $b);\n}\n\nadd(1, '1');\n<\/code><\/pre>\n\n<p>However, I'd prefer if it failed as I'm passing the function an integer and a string, but specifying they should both be integers.<\/p>\n\n<p>Fixing this is simple, by adding this line to the top of the file:<\/p>\n\n<pre><code class=\"php\">declare(strict_types=1);\n<\/code><\/pre>\n\n<p>I add this to every PHP file by default.<\/p>\n\n<p>I want my code to be as strict and predictable as possible, and to error when I want it to and make any bugs more explicit and easier to find and fix.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I prefer writing and working with strictly typed code.<\/p>\n\n<p>One of the major improvements in PHP has been the option to enable strict types.<\/p>\n\n<p>For example, this code will usually not error and give the result:<\/p>\n\n<pre><code class=\"php\">function add(int $a, int $b): void\n{\n var_dump($a + $b);\n}\n\nadd(1, '1');\n<\/code><\/pre>\n\n<p>However, I'd prefer if it failed as I'm passing the function an integer and a string, but specifying they should both be integers.<\/p>\n\n<p>Fixing this is simple, by adding this line to the top of the file:<\/p>\n\n<pre><code class=\"php\">declare(strict_types=1);\n<\/code><\/pre>\n\n<p>I add this to every PHP file by default.<\/p>\n\n<p>I want my code to be as strict and predictable as possible, and to error when I want it to and make any bugs more explicit and easier to find and fix.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "07d6a599d591e31580f215b484e9ae34",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.064bc838-fd38-47ab-9612-83e5df0843cc.json
Normal file
100
content/node.064bc838-fd38-47ab-9612-83e5df0843cc.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "064bc838-fd38-47ab-9612-83e5df0843cc"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Writing tests is an investment\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-10-13T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/10\/13\/writing-tests-is-an-investment",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>It can take time to write automated tests and do test-driven development, but it is an investment in a project's future stability.<\/p>\n\n<p>Spending time to write tests upfront will save time as the project progresses, make the code easier to change, and result in better software, fewer bugs, and quicker changes.<\/p>\n\n<p>Even though it takes time, it's time well spent.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>It can take time to write automated tests and do test-driven development, but it is an investment in a project's future stability.<\/p>\n\n<p>Spending time to write tests upfront will save time as the project progresses, make the code easier to change, and result in better software, fewer bugs, and quicker changes.<\/p>\n\n<p>Even though it takes time, it's time well spent.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "b535eb52679173284d48e852e1dd8e86",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.074f251c-777b-44bc-ba68-87eb526d433b.json
Normal file
100
content/node.074f251c-777b-44bc-ba68-87eb526d433b.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "074f251c-777b-44bc-ba68-87eb526d433b"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Software development is about solving problems and adding value\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-03-27T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/03\/27\/software-development-solving-problems-and-adding-value",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I've recently started as a Mentor for the School of Code, working with a student on their cohort that started last week. Whilst the Bootcamp is focussed on JavaScript and node, and is currently looking at front-end development and using APIs, we've already started talking about different back-end technologies and frameworks.<\/p>\n\n<p>Something that I've believed for a while is that software development is about solving problems and different languages and frameworks are tools to use to solve the problem and achieve the desired result. The programming fundamentals that he's learning now can be applied to different languages and some may be better depending on the problem that needs to be solved.<\/p>\n\n<p>I've also said when speaking with a client this week that development is about adding business value.<\/p>\n\n<p>Whilst there is some value to doing security updates and maintenance to keep an application running and secure, I'd much rather be working on tasks that directly add value for the client like some of the tasks I've done for them recently like improving eCommerce conversions and adding new payment methods or revenue streams.<\/p>\n\n<p>It's easier for the client to justify and see the results of the work, it improves the experience for their customers or users, and it's more interesting and fulfilling for me.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I've recently started as a Mentor for the School of Code, working with a student on their cohort that started last week. Whilst the Bootcamp is focussed on JavaScript and node, and is currently looking at front-end development and using APIs, we've already started talking about different back-end technologies and frameworks.<\/p>\n\n<p>Something that I've believed for a while is that software development is about solving problems and different languages and frameworks are tools to use to solve the problem and achieve the desired result. The programming fundamentals that he's learning now can be applied to different languages and some may be better depending on the problem that needs to be solved.<\/p>\n\n<p>I've also said when speaking with a client this week that development is about adding business value.<\/p>\n\n<p>Whilst there is some value to doing security updates and maintenance to keep an application running and secure, I'd much rather be working on tasks that directly add value for the client like some of the tasks I've done for them recently like improving eCommerce conversions and adding new payment methods or revenue streams.<\/p>\n\n<p>It's easier for the client to justify and see the results of the work, it improves the experience for their customers or users, and it's more interesting and fulfilling for me.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "7256a5bb0e6800a548d88e2979344646",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.07db4821-3295-42d6-bbc0-6026ba1c56cf.json
Normal file
100
content/node.07db4821-3295-42d6-bbc0-6026ba1c56cf.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "07db4821-3295-42d6-bbc0-6026ba1c56cf"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Why I like pair and mob programming\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-05-11T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/05\/11\/why-i-like-pair-and-mob-programming",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>When working as part of a team, I like to do pair or mob programming as much as possible.<\/p>\n\n<p>I like being able to give and receive feedback in real-time; everyone can contribute to the solution and more shared knowledge, so there's less siloing, and it's much harder to block multiple people than a single person.<\/p>\n\n<p>Working in pairs or a mob is a great opportunity to onboard new team members, train and mentor, and share tips and tricks.<\/p>\n\n<p>It's usually more productive than working separately, and it's nice to speak and socialise with other team members whilst working on a task.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>When working as part of a team, I like to do pair or mob programming as much as possible.<\/p>\n\n<p>I like being able to give and receive feedback in real-time; everyone can contribute to the solution and more shared knowledge, so there's less siloing, and it's much harder to block multiple people than a single person.<\/p>\n\n<p>Working in pairs or a mob is a great opportunity to onboard new team members, train and mentor, and share tips and tricks.<\/p>\n\n<p>It's usually more productive than working separately, and it's nice to speak and socialise with other team members whilst working on a task.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "b0e612367a93931235c02addd4091033",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0864f570-d766-488e-aa40-08896621dacc.json
Normal file
100
content/node.0864f570-d766-488e-aa40-08896621dacc.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0864f570-d766-488e-aa40-08896621dacc"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Upgrading from Drupal 9 is easier\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-07-31T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/07\/31\/upgrading-from-drupal-9-is-easier",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Upgrading from Drupal 7 to 8, 9 or 10 is a large task.<\/p>\n\n<p>You must create a new empty site, migrate your configuration and data, manually recreate anything else and rewrite any custom modules and themes.<\/p>\n\n<p>Since Drupal 8, things have been different.<\/p>\n\n<p>You can upgrade your site in place.<\/p>\n\n<p>No large code rewrite or data migration.<\/p>\n\n<p>Many contributed modules support multiple major Drupal versions simultaneously, so they may not need upgrading.<\/p>\n\n<p>Others may need small changes to remove deprecated code or be compatible with breaking changes, and some tools can automate some or all of the changes.<\/p>\n\n<p>The same applies to upgrading from Drupal 9 to 10, which will be the same for Drupal 11 next year.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Upgrading from Drupal 7 to 8, 9 or 10 is a large task.<\/p>\n\n<p>You must create a new empty site, migrate your configuration and data, manually recreate anything else and rewrite any custom modules and themes.<\/p>\n\n<p>Since Drupal 8, things have been different.<\/p>\n\n<p>You can upgrade your site in place.<\/p>\n\n<p>No large code rewrite or data migration.<\/p>\n\n<p>Many contributed modules support multiple major Drupal versions simultaneously, so they may not need upgrading.<\/p>\n\n<p>Others may need small changes to remove deprecated code or be compatible with breaking changes, and some tools can automate some or all of the changes.<\/p>\n\n<p>The same applies to upgrading from Drupal 9 to 10, which will be the same for Drupal 11 next year.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "062455710dfbfed24f6c650fa013d504",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.08829cf3-7798-417c-b71e-d619072bc4b6.json
Normal file
100
content/node.08829cf3-7798-417c-b71e-d619072bc4b6.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "08829cf3-7798-417c-b71e-d619072bc4b6"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Running NixOS in the Cloud"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-11-28T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/11\/28\/running-nixos-in-the-cloud",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Yesterday I explained that Nix, or specifically NixOS, <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/27\/nix-as-an-operating-system\">can be used to manage your entire operating system<\/a> in a declarative and reproducible way.<\/p>\n\n<p>My initial experience was running it on my laptop as a replacement for another Linux distribution, which I use to configure everything about my laptop and development environment, including my i3 window manager, Neovim and tmux configurations.<\/p>\n\n<p>I recently also started to use it on a new VPS to host several static websites, including this one and <a href=\"https:\/\/www.oliverdavies.uk\/blog\/uis-ive-rebuilt-tailwind-css\">various examples I've created as demos<\/a> or for presentations.<\/p>\n\n<p>Similarly to my laptop, I was able to declaratively install any required utilities, enable the Nginx web server, open firewall ports, add my virtual hosts and create and apply the required SSL certificates.<\/p>\n\n<p>And I can do this locally using <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/tree\/ec2767adfb6667184f884080a4f9b5d2a388a03d\/nix\/hosts\/hetznix\">the same NixOS configuration files<\/a> and applying it to the remote server.<\/p>\n\n<p>Now I'm running NixOS everywhere!<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Yesterday I explained that Nix, or specifically NixOS, <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/27\/nix-as-an-operating-system\">can be used to manage your entire operating system<\/a> in a declarative and reproducible way.<\/p>\n\n<p>My initial experience was running it on my laptop as a replacement for another Linux distribution, which I use to configure everything about my laptop and development environment, including my i3 window manager, Neovim and tmux configurations.<\/p>\n\n<p>I recently also started to use it on a new VPS to host several static websites, including this one and <a href=\"https:\/\/www.oliverdavies.uk\/blog\/uis-ive-rebuilt-tailwind-css\">various examples I've created as demos<\/a> or for presentations.<\/p>\n\n<p>Similarly to my laptop, I was able to declaratively install any required utilities, enable the Nginx web server, open firewall ports, add my virtual hosts and create and apply the required SSL certificates.<\/p>\n\n<p>And I can do this locally using <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/tree\/ec2767adfb6667184f884080a4f9b5d2a388a03d\/nix\/hosts\/hetznix\">the same NixOS configuration files<\/a> and applying it to the remote server.<\/p>\n\n<p>Now I'm running NixOS everywhere!<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e7631b334d9daafcfa47e2f3cd60def6",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.08d34480-0983-4759-b06f-0fabab1b5a05.json
Normal file
100
content/node.08d34480-0983-4759-b06f-0fabab1b5a05.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "08d34480-0983-4759-b06f-0fabab1b5a05"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Speaking at Reading College"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-05-04T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/05\/04\/college",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>After recently speaking at a PHP user group, I've been invited to be a guest speaker and speak to a group of students at Reading College.<\/p>\n\n<p>It will be a group of around 40 students who are currently studying Computing and IT with a current focus on web development.<\/p>\n\n<p>I'm planning to speak about my background in both hardware and software, how I started in software development and with open source, and some of the opportunities that I've had from that, including work opportunities, public speaking and mentoring.<\/p>\n\n<p>I'm also going to talk about the hobby side of computing for me - using ThinkPad laptops, Linux and managing a homelab and home server, which I think will be interesting and relevant to a group of Computing and IT students.<\/p>\n\n<p>I have a two hour slot, which I'm sure it will involve some demos, live coding and group programming, which usually happens when I'm giving presentations.<\/p>\n\n<p>This will be a bit different to all the talks and workshops I've done so far, but I'm looking forward to it and I'm sure will be open to doing similar presentations in the future.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>After recently speaking at a PHP user group, I've been invited to be a guest speaker and speak to a group of students at Reading College.<\/p>\n\n<p>It will be a group of around 40 students who are currently studying Computing and IT with a current focus on web development.<\/p>\n\n<p>I'm planning to speak about my background in both hardware and software, how I started in software development and with open source, and some of the opportunities that I've had from that, including work opportunities, public speaking and mentoring.<\/p>\n\n<p>I'm also going to talk about the hobby side of computing for me - using ThinkPad laptops, Linux and managing a homelab and home server, which I think will be interesting and relevant to a group of Computing and IT students.<\/p>\n\n<p>I have a two hour slot, which I'm sure it will involve some demos, live coding and group programming, which usually happens when I'm giving presentations.<\/p>\n\n<p>This will be a bit different to all the talks and workshops I've done so far, but I'm looking forward to it and I'm sure will be open to doing similar presentations in the future.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "745510ed0044be6758cbc74729ab3d08",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.08eb8c13-6259-4500-8829-e5d5854ef10c.json
Normal file
100
content/node.08eb8c13-6259-4500-8829-e5d5854ef10c.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "08eb8c13-6259-4500-8829-e5d5854ef10c"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't run code formatting in your CI pipeline"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-07-29T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/07\/29\/dont-run-code-formatting-in-your-ci-pipeline",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Something I commonly used to see, and did myself, was running code formatting tools, such as PHP CS Fixer or prettier, automatically their CI pipeline.<\/p>\n\n<p>And not using it as a check to fail the pipeline if your code isn't formatted correctly.<\/p>\n\n<p>Running it, fixing any code and committing any updates.<\/p>\n\n<p>It wasn't long before I stopped doing this.<\/p>\n\n<p>Firstly, I wasn't comfortable with a CI pipeline have write access to my codebase. It's fine to be able to clone it and run checks against it, but making changes to my code and pushing it makes me nervous.<\/p>\n\n<p>Particularly if you're doing trunk-based development and everyone works on the same branch.<\/p>\n\n<p>This also causes additional upstream commits, because the pipeline has committed a change. If you don't remember to pull those commits, you can <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/07\/25\/only-have-one-url-per-git-remote\">end up in a tricky situation<\/a>.<\/p>\n\n<p>I'm also not a fan of having a lot of <code>php-cs-fixer fixes<\/code> or <code>prettier fixes<\/code> commits. I'd prefer the commits be correct when they're pushed, if possible, which is why I usually do micro commits locally and tidy things before pushing them.<\/p>\n\n<p>If you're working on a topic branch and creating a pull or merge request, you can squash commits when merging, but <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/05\/11\/don-t-delete-my-commit-messages\">I'm not a fan of squashing commits<\/a>, either.<\/p>\n\n<p>Instead of relying on a CI pipeline to run code formatting, <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2022\/08\/15\/using-run-file-simplify-project-tasks\">make it easy to run those tasks locally<\/a>.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Something I commonly used to see, and did myself, was running code formatting tools, such as PHP CS Fixer or prettier, automatically their CI pipeline.<\/p>\n\n<p>And not using it as a check to fail the pipeline if your code isn't formatted correctly.<\/p>\n\n<p>Running it, fixing any code and committing any updates.<\/p>\n\n<p>It wasn't long before I stopped doing this.<\/p>\n\n<p>Firstly, I wasn't comfortable with a CI pipeline have write access to my codebase. It's fine to be able to clone it and run checks against it, but making changes to my code and pushing it makes me nervous.<\/p>\n\n<p>Particularly if you're doing trunk-based development and everyone works on the same branch.<\/p>\n\n<p>This also causes additional upstream commits, because the pipeline has committed a change. If you don't remember to pull those commits, you can <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/07\/25\/only-have-one-url-per-git-remote\">end up in a tricky situation<\/a>.<\/p>\n\n<p>I'm also not a fan of having a lot of <code>php-cs-fixer fixes<\/code> or <code>prettier fixes<\/code> commits. I'd prefer the commits be correct when they're pushed, if possible, which is why I usually do micro commits locally and tidy things before pushing them.<\/p>\n\n<p>If you're working on a topic branch and creating a pull or merge request, you can squash commits when merging, but <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/05\/11\/don-t-delete-my-commit-messages\">I'm not a fan of squashing commits<\/a>, either.<\/p>\n\n<p>Instead of relying on a CI pipeline to run code formatting, <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2022\/08\/15\/using-run-file-simplify-project-tasks\">make it easy to run those tasks locally<\/a>.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d54ad8e941f721ec3bbb3abacd9ca123",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.08ed7d91-f12d-45fb-bef4-edc979ff46cf.json
Normal file
100
content/node.08ed7d91-f12d-45fb-bef4-edc979ff46cf.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "08ed7d91-f12d-45fb-bef4-edc979ff46cf"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Small and fast"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-02-12T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/02\/12\/small-and-fast",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Due to an local outage, I've had no broadband connection and been mostly offline for the last few days.<\/p>\n\n<p>The only connection I've had is a weak 4G signal from my mobile phone that I've been able to tether from to check emails, etc.<\/p>\n\n<p>But this is slow and I struggled to load the majority of websites.<\/p>\n\n<p>Some would take a number of seconds or minutes to load, or fail.<\/p>\n\n<p>As websites and applications develop and grow, it's important to try and keep your codebase as lean and performant as possible.<\/p>\n\n<p>You never know what connection people will be using your code from.<\/p>\n\n<p>What if their broadband goes down or they're in an area with a poor mobile signal?<\/p>\n\n<p>They may not be able to download your large CSS or JS file, or execute the unoptimised database query.<\/p>\n\n<p>You can't assume everyone will be using a high speed Internet connection, so avoid feature bloat, optimise for performance and keep things small and fast.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Due to an local outage, I've had no broadband connection and been mostly offline for the last few days.<\/p>\n\n<p>The only connection I've had is a weak 4G signal from my mobile phone that I've been able to tether from to check emails, etc.<\/p>\n\n<p>But this is slow and I struggled to load the majority of websites.<\/p>\n\n<p>Some would take a number of seconds or minutes to load, or fail.<\/p>\n\n<p>As websites and applications develop and grow, it's important to try and keep your codebase as lean and performant as possible.<\/p>\n\n<p>You never know what connection people will be using your code from.<\/p>\n\n<p>What if their broadband goes down or they're in an area with a poor mobile signal?<\/p>\n\n<p>They may not be able to download your large CSS or JS file, or execute the unoptimised database query.<\/p>\n\n<p>You can't assume everyone will be using a high speed Internet connection, so avoid feature bloat, optimise for performance and keep things small and fast.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "f6c37d9d9fa156de34d1f69cd5c937cc",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.09659c9b-a176-4ccb-916d-bab6ecfc102d.json
Normal file
100
content/node.09659c9b-a176-4ccb-916d-bab6ecfc102d.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "09659c9b-a176-4ccb-916d-bab6ecfc102d"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Patching Drupal"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-01-14T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/01\/14\/patching-drupal",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Yesterday I wrote about <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2025\/01\/13\/patches\">how I used a patch file to customise a project in my Nix configuration<\/a>.<\/p>\n\n<p>I'm familiar with patch files from my Drupal contributions, when we used to create and upload patch files and attach them to issues to contribute changes.<\/p>\n\n<p>Although patches aren't used to contribute to Drupal any more, you can still apply patches to Drupal code in your own projects if you need to.<\/p>\n\n<p>If there's a customisation or fix you need you need to apply, instead of altering and \"hacking\" the source files, you can apply changes with patch files.<\/p>\n\n<p>Instead of Nix, I use <a href=\"https:\/\/github.com\/cweagans\/composer-patches\">composer-patches<\/a> to automatically apply patches when running <code>composer install<\/code>.<\/p>\n\n<p>For example, in my composer.json file, I can add something like this:<\/p>\n\n<pre><code class=\"json\">\"extra\": {\n \"patches\": {\n \"drupal\/default_content\": {\n \"Issue #2698425: Do not reimport existing entities (https:\/\/www.drupal.org\/project\/default_content\/issues\/2698425#comment-15593214)\": \"patches\/default_content-2698425-do-not-reimport-196.patch\",\n \"Issue #3160146: Add a Normalizer and Denormalizer to support Layout Builder (https:\/\/www.drupal.org\/project\/default_content\/issues\/3160146#comment-14814050)\": \"patches\/default_content-3160146-53.patch\"\n }\n },\n},\n<\/code><\/pre>\n\n<p>This will apply these two patch files to the Default Content module (which are the same as running <code>git diff<\/code> between two commits), which I needed to do for a recent project.<\/p>\n\n<p>If the upstream issue is fixed and the patch is no longer needed, they can be removed and the module can be updated to the latest version.<\/p>\n\n<p>And this works for core and contrib projects.<\/p>\n\n<p>The same as the tmux-sessionizer example, this approach means I can apply any changes without needing to duplicate or alter the code, and it makes it easy to contribute by testing other people's patches or applying and contributing your own.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Yesterday I wrote about <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2025\/01\/13\/patches\">how I used a patch file to customise a project in my Nix configuration<\/a>.<\/p>\n\n<p>I'm familiar with patch files from my Drupal contributions, when we used to create and upload patch files and attach them to issues to contribute changes.<\/p>\n\n<p>Although patches aren't used to contribute to Drupal any more, you can still apply patches to Drupal code in your own projects if you need to.<\/p>\n\n<p>If there's a customisation or fix you need you need to apply, instead of altering and \"hacking\" the source files, you can apply changes with patch files.<\/p>\n\n<p>Instead of Nix, I use <a href=\"https:\/\/github.com\/cweagans\/composer-patches\">composer-patches<\/a> to automatically apply patches when running <code>composer install<\/code>.<\/p>\n\n<p>For example, in my composer.json file, I can add something like this:<\/p>\n\n<pre><code class=\"json\">\"extra\": {\n \"patches\": {\n \"drupal\/default_content\": {\n \"Issue #2698425: Do not reimport existing entities (https:\/\/www.drupal.org\/project\/default_content\/issues\/2698425#comment-15593214)\": \"patches\/default_content-2698425-do-not-reimport-196.patch\",\n \"Issue #3160146: Add a Normalizer and Denormalizer to support Layout Builder (https:\/\/www.drupal.org\/project\/default_content\/issues\/3160146#comment-14814050)\": \"patches\/default_content-3160146-53.patch\"\n }\n },\n},\n<\/code><\/pre>\n\n<p>This will apply these two patch files to the Default Content module (which are the same as running <code>git diff<\/code> between two commits), which I needed to do for a recent project.<\/p>\n\n<p>If the upstream issue is fixed and the patch is no longer needed, they can be removed and the module can be updated to the latest version.<\/p>\n\n<p>And this works for core and contrib projects.<\/p>\n\n<p>The same as the tmux-sessionizer example, this approach means I can apply any changes without needing to duplicate or alter the code, and it makes it easy to contribute by testing other people's patches or applying and contributing your own.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "64930ff9734d8caf5d32c9d3840e4b0a",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.09aec80d-9f5f-4ec1-96af-dd99d4f1da7b.json
Normal file
100
content/node.09aec80d-9f5f-4ec1-96af-dd99d4f1da7b.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "09aec80d-9f5f-4ec1-96af-dd99d4f1da7b"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "The first test is the hardest"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-05-16T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/05\/16\/the-first-test-is-the-hardest",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Whether you're writing tests before the implementation code or not, the first test is always the hardest to write.<\/p>\n\n<p>What will the arrange and act phases look like?<\/p>\n\n<p>What dependencies will you need?<\/p>\n\n<p>What do you need to mock or create fakes of?<\/p>\n\n<p>In a Drupal test, what other modules and configuration do you need to install?<\/p>\n\n<p>What installation profile and default theme do you need to use?<\/p>\n\n<p>What other unknown or complicated setup steps are there?<\/p>\n\n<p>Do you need to configure your environment to run the tests and get the expected output?<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>The hardest part is getting the arrange\/setup phase working and getting to when the test is running your business logic.<\/p>\n\n<p>Once you've got the first test running, adding more for similar use cases will be much easier.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Whether you're writing tests before the implementation code or not, the first test is always the hardest to write.<\/p>\n\n<p>What will the arrange and act phases look like?<\/p>\n\n<p>What dependencies will you need?<\/p>\n\n<p>What do you need to mock or create fakes of?<\/p>\n\n<p>In a Drupal test, what other modules and configuration do you need to install?<\/p>\n\n<p>What installation profile and default theme do you need to use?<\/p>\n\n<p>What other unknown or complicated setup steps are there?<\/p>\n\n<p>Do you need to configure your environment to run the tests and get the expected output?<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>The hardest part is getting the arrange\/setup phase working and getting to when the test is running your business logic.<\/p>\n\n<p>Once you've got the first test running, adding more for similar use cases will be much easier.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "9932561d0945f63746a1bb5ddd951b0a",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0a3854c2-e230-4255-82a5-749e90e06ba9.json
Normal file
100
content/node.0a3854c2-e230-4255-82a5-749e90e06ba9.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0a3854c2-e230-4255-82a5-749e90e06ba9"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Simpler code doesn't mean less code"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-02-09T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/02\/09\/simpler",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Just because I consider some code to be simpler, that doesn't necessarily mean there's less code.<\/p>\n\n<p>It's possible to write a whole function or class on one line, but that doesn't mean it's simple to read or understand.<\/p>\n\n<p>The opposite is also true.<\/p>\n\n<p>I can extract business logic from Controller classes into different service classes, commands or actions.<\/p>\n\n<p>I can use data transfer objects (DTOs), value objects and Collection classes to give names and meanings to things instead of always using generic strings, arrays or objects.<\/p>\n\n<p>I can follow design patterns and implement Repositories, Decorators, Factories and Builders to better organise code and make it easier to use and update.<\/p>\n\n<p>I can write tests that act as examples and executable documentation for people to see how to use the code I've written.<\/p>\n\n<p>This can all make code easier to read, understand and use - even though there is more of it.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Just because I consider some code to be simpler, that doesn't necessarily mean there's less code.<\/p>\n\n<p>It's possible to write a whole function or class on one line, but that doesn't mean it's simple to read or understand.<\/p>\n\n<p>The opposite is also true.<\/p>\n\n<p>I can extract business logic from Controller classes into different service classes, commands or actions.<\/p>\n\n<p>I can use data transfer objects (DTOs), value objects and Collection classes to give names and meanings to things instead of always using generic strings, arrays or objects.<\/p>\n\n<p>I can follow design patterns and implement Repositories, Decorators, Factories and Builders to better organise code and make it easier to use and update.<\/p>\n\n<p>I can write tests that act as examples and executable documentation for people to see how to use the code I've written.<\/p>\n\n<p>This can all make code easier to read, understand and use - even though there is more of it.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e59143196c70adc39a01487205db060b",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0a66ac44-9c33-4d4e-af97-f74acb95779a.json
Normal file
100
content/node.0a66ac44-9c33-4d4e-af97-f74acb95779a.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0a66ac44-9c33-4d4e-af97-f74acb95779a"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Git is not GitHub"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-11-15T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/11\/15\/github-is-not-git",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>A common misunderstanding for new Developers is that Git and GitHub are the same thing, but they aren't.<\/p>\n\n<p>Git is decentralised, so doesn't rely on using external repositories on services like GitHub, GitLab or Bitbucket.<\/p>\n\n<p>You can run <code>git init<\/code> and use it locally without pushing to any remote services.<\/p>\n\n<p>These services also add extra terminology, such as forks, syncing and pull or merge requests which aren't part of Git itself.<\/p>\n\n<p>This can cause confusion, which is why <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2022\/08\/23\/git-gui-command-line\">I think it's important to learn Git itself<\/a> instead of relying on external services or desktop apps.<\/p>\n\n<p>And, if you're going to use a remote repository, consider something like Gitea, which you can host yourself and keep control of your data.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>A common misunderstanding for new Developers is that Git and GitHub are the same thing, but they aren't.<\/p>\n\n<p>Git is decentralised, so doesn't rely on using external repositories on services like GitHub, GitLab or Bitbucket.<\/p>\n\n<p>You can run <code>git init<\/code> and use it locally without pushing to any remote services.<\/p>\n\n<p>These services also add extra terminology, such as forks, syncing and pull or merge requests which aren't part of Git itself.<\/p>\n\n<p>This can cause confusion, which is why <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2022\/08\/23\/git-gui-command-line\">I think it's important to learn Git itself<\/a> instead of relying on external services or desktop apps.<\/p>\n\n<p>And, if you're going to use a remote repository, consider something like Gitea, which you can host yourself and keep control of your data.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "22be20101f09fc0d4e10cd3c6b867b76",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0ad4d292-e5ee-45b9-b990-1870844b29bb.json
Normal file
100
content/node.0ad4d292-e5ee-45b9-b990-1870844b29bb.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0ad4d292-e5ee-45b9-b990-1870844b29bb"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't use arbitrary values in Tailwind CSS\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-01-02T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/01\/02\/dont-use-arbitrary-values-in-tailwind-css",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>It's been almost five years since I gave the first version of my \"<a href=\"https:\/\/www.oliverdavies.uk\/talks\/taking-flight-with-tailwind-css\">Taking Flight with Tailwind CSS<\/a>\" talk at the Drupal Bristol meetup in January 2018.<\/p>\n\n<p>It's a talk that I've updated every time I've given it, showing new rebuilt example UIs and the new features in the framework, as well as tweaking content like installation steps for different audiences.<\/p>\n\n<p>As I prepare for the Norfolk Developers Conference (nordevcon) next month, I'm updating the talk again.<\/p>\n\n<p>One feature that wasn't in the last version of the talk is arbitrary values in class names. This, I think, is an antipattern and something that I avoid using.<\/p>\n\n<p>Whilst you could always add arbitrary values in custom CSS, one of my original reasons for liking and adopting Tailwind CSS was that there was a predefined list of classes to choose from.<\/p>\n\n<p>A set list of colours, text sizes, margins and padding, for example, meant that UIs looked more consistent and the generated CSS was smaller.<\/p>\n\n<p>If you need an additional value or to replace the existing values, you can do so within your <code>tailwind.config.js<\/code> file, and Tailwind will generate classes accordingly.<\/p>\n\n<p>Whilst writing custom CSS, inline styles, and arbitrary values are all possible, I'd suggest using the configuration file, generating the classes that you need, and sticking to them as much as you can and enjoying the consistency and benefits that brings.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>It's been almost five years since I gave the first version of my \"<a href=\"https:\/\/www.oliverdavies.uk\/talks\/taking-flight-with-tailwind-css\">Taking Flight with Tailwind CSS<\/a>\" talk at the Drupal Bristol meetup in January 2018.<\/p>\n\n<p>It's a talk that I've updated every time I've given it, showing new rebuilt example UIs and the new features in the framework, as well as tweaking content like installation steps for different audiences.<\/p>\n\n<p>As I prepare for the Norfolk Developers Conference (nordevcon) next month, I'm updating the talk again.<\/p>\n\n<p>One feature that wasn't in the last version of the talk is arbitrary values in class names. This, I think, is an antipattern and something that I avoid using.<\/p>\n\n<p>Whilst you could always add arbitrary values in custom CSS, one of my original reasons for liking and adopting Tailwind CSS was that there was a predefined list of classes to choose from.<\/p>\n\n<p>A set list of colours, text sizes, margins and padding, for example, meant that UIs looked more consistent and the generated CSS was smaller.<\/p>\n\n<p>If you need an additional value or to replace the existing values, you can do so within your <code>tailwind.config.js<\/code> file, and Tailwind will generate classes accordingly.<\/p>\n\n<p>Whilst writing custom CSS, inline styles, and arbitrary values are all possible, I'd suggest using the configuration file, generating the classes that you need, and sticking to them as much as you can and enjoying the consistency and benefits that brings.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "6922005e460c87b7b1c677699162005b",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0c4da7ae-33ea-48bc-ba10-534e4ad6ae7e.json
Normal file
100
content/node.0c4da7ae-33ea-48bc-ba10-534e4ad6ae7e.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0c4da7ae-33ea-48bc-ba10-534e4ad6ae7e"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "What'll be in Drupal 11?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-11-20T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/11\/20\/whatll-be-in-drupal-11",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Drupal 9 is end-of-life and no longer supported.<\/p>\n\n<p>Drupal 10 is the current stable version, and the development branch for Drupal 11 has just been started.<\/p>\n\n<p>But what will be in Drupal 11?<\/p>\n\n<p>Well, we don't know yet.<\/p>\n\n<p>Drupal's release schedule is based on fixed dates and not on features.<\/p>\n\n<p>Whatever is ready on the release date will be included. If something isn't ready, it'll be in a future version.<\/p>\n\n<p>If something is ready sooner, it'll be in a minor 10 version, such as Drupal 10.2 or 10.3. We've seen it recently with various UI improvements in 10.1 - with more in 10.2.<\/p>\n\n<p>We saw new features, such as Layout Builder, added to Drupal core within the Drupal 8 lifecycle, and there's still time to add more to Drupal 10.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>But, like Drupal 9 and 10, Drupal 11 won't mean a major rewrite to your code.<\/p>\n\n<p>Drupal 11 is based on Drupal 10, so the modules and themes you use will be able to work with both, allowing you to upgrade incrementally.<\/p>\n\n<p>While there isn't a definitive list of new features or changes for Drupal 11, based on things I saw and learned about at DrupalCon, I'm excited to see what makes it.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Drupal 9 is end-of-life and no longer supported.<\/p>\n\n<p>Drupal 10 is the current stable version, and the development branch for Drupal 11 has just been started.<\/p>\n\n<p>But what will be in Drupal 11?<\/p>\n\n<p>Well, we don't know yet.<\/p>\n\n<p>Drupal's release schedule is based on fixed dates and not on features.<\/p>\n\n<p>Whatever is ready on the release date will be included. If something isn't ready, it'll be in a future version.<\/p>\n\n<p>If something is ready sooner, it'll be in a minor 10 version, such as Drupal 10.2 or 10.3. We've seen it recently with various UI improvements in 10.1 - with more in 10.2.<\/p>\n\n<p>We saw new features, such as Layout Builder, added to Drupal core within the Drupal 8 lifecycle, and there's still time to add more to Drupal 10.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>But, like Drupal 9 and 10, Drupal 11 won't mean a major rewrite to your code.<\/p>\n\n<p>Drupal 11 is based on Drupal 10, so the modules and themes you use will be able to work with both, allowing you to upgrade incrementally.<\/p>\n\n<p>While there isn't a definitive list of new features or changes for Drupal 11, based on things I saw and learned about at DrupalCon, I'm excited to see what makes it.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d0230fb0c7af7c9de0491edbea342ca1",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0c88f38d-b143-4299-983d-78b026854fff.json
Normal file
100
content/node.0c88f38d-b143-4299-983d-78b026854fff.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0c88f38d-b143-4299-983d-78b026854fff"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Avoiding primitive obsession"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-09-09T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/09\/09\/avoiding-primitive-obsession",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Something interesting that <a href=\"https:\/\/www.daveliddament.co.uk\">Dave Liddament<\/a> and I discussed was the use of value objects in application code.<\/p>\n\n<p>Instead of using a primitive type, such as <code>string<\/code>, you can create a new value object for a specific type of string, such as an <code>EmailAddress<\/code> or, in my side project, a <code>LicenceKey<\/code>.<\/p>\n\n<p>Both are strings, but using value objects of specific types can make the code more readable and its intent clearer.<\/p>\n\n<p>A value object can contain additional logic, such as validation to execute an ensure the value object is valid, such as making sure a string is not empty, is a specific length or only contains valid characters.<\/p>\n\n<p>This an approach that I'm going to use more going forward.<\/p>\n\n<p>I also found <a href=\"https:\/\/www.youtube.com\/watch?v=yJpvObzKewY\">a lighting talk by Dave<\/a> at a PHPSW meetup where he explains this further and, of course, you can listen to the podcast episode after it's been released.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Something interesting that <a href=\"https:\/\/www.daveliddament.co.uk\">Dave Liddament<\/a> and I discussed was the use of value objects in application code.<\/p>\n\n<p>Instead of using a primitive type, such as <code>string<\/code>, you can create a new value object for a specific type of string, such as an <code>EmailAddress<\/code> or, in my side project, a <code>LicenceKey<\/code>.<\/p>\n\n<p>Both are strings, but using value objects of specific types can make the code more readable and its intent clearer.<\/p>\n\n<p>A value object can contain additional logic, such as validation to execute an ensure the value object is valid, such as making sure a string is not empty, is a specific length or only contains valid characters.<\/p>\n\n<p>This an approach that I'm going to use more going forward.<\/p>\n\n<p>I also found <a href=\"https:\/\/www.youtube.com\/watch?v=yJpvObzKewY\">a lighting talk by Dave<\/a> at a PHPSW meetup where he explains this further and, of course, you can listen to the podcast episode after it's been released.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "60b18ba23e94d04d883b816e371d3836",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0cb684e0-951a-477f-8df7-1145fd9b1b5c.json
Normal file
100
content/node.0cb684e0-951a-477f-8df7-1145fd9b1b5c.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0cb684e0-951a-477f-8df7-1145fd9b1b5c"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Browsing in plain text"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-12-16T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/12\/16\/browsing-in-plain-text",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Did you know you can use programs like lynx or w3m to browse the web on the command line?<\/p>\n\n<p>No CSS, JavaScript or images, just plain text.<\/p>\n\n<p>Similar to using a screen reader, you can quickly tab between focusable elements like links and buttons to find what you need.<\/p>\n\n<p>While it will probably not replace Firefox or Chrome as a daily driver, it is useful to know if you're on a server without a browser or need to quickly find information without distractions.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Did you know you can use programs like lynx or w3m to browse the web on the command line?<\/p>\n\n<p>No CSS, JavaScript or images, just plain text.<\/p>\n\n<p>Similar to using a screen reader, you can quickly tab between focusable elements like links and buttons to find what you need.<\/p>\n\n<p>While it will probably not replace Firefox or Chrome as a daily driver, it is useful to know if you're on a server without a browser or need to quickly find information without distractions.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "9da4d3a86f1c672f86f84b3581e8b6e9",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0ccb25c5-e938-4605-a204-8a11f62fe820.json
Normal file
100
content/node.0ccb25c5-e938-4605-a204-8a11f62fe820.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0ccb25c5-e938-4605-a204-8a11f62fe820"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Always be learning"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-08-26T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/08\/26\/always-be-learning",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I've been a Developer for 15 years and one thing that I've always focussed on is to always keep learning.<\/p>\n\n<p>From starting as a self-taught Developer, initially learning HTML and CSS, to later learning PHP and Drupal as well as other languages, frameworks and tools.<\/p>\n\n<p>For the last couple of days, I've been experimenting with Next.js - a React-based web framework. I hadn't used React before and have typically reached for Vue.js or sometimes Alpine.js based on what I needed to do. However, I'm always looking for opportunities to learn and implement new things, and see how I can use them in any of my projects.<\/p>\n\n<p>This afternoon, I started a new Next.js and TypeScript project, and refactored a small codebase that used a static site generator to create a small number of landing pages from Markdown files.<\/p>\n\n<p>It took me a short time to set up a Docker environment for it based on some of my Vue.js projects, ported across the application to recreate the pages, and finally, updated the CI pipeline that generated the static pages and uploaded them to an S3 bucket.<\/p>\n\n<p>The end result is the same - the same HTML pages are generated and uploaded - but, for me, trying and experimenting with new things keeps my work interesting and my knowledge fresh, which benefits me as well as my colleagues and clients.<\/p>\n\n<p>As I said in a previous email, one of the great things about software development is that there's always something new to learn.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I've been a Developer for 15 years and one thing that I've always focussed on is to always keep learning.<\/p>\n\n<p>From starting as a self-taught Developer, initially learning HTML and CSS, to later learning PHP and Drupal as well as other languages, frameworks and tools.<\/p>\n\n<p>For the last couple of days, I've been experimenting with Next.js - a React-based web framework. I hadn't used React before and have typically reached for Vue.js or sometimes Alpine.js based on what I needed to do. However, I'm always looking for opportunities to learn and implement new things, and see how I can use them in any of my projects.<\/p>\n\n<p>This afternoon, I started a new Next.js and TypeScript project, and refactored a small codebase that used a static site generator to create a small number of landing pages from Markdown files.<\/p>\n\n<p>It took me a short time to set up a Docker environment for it based on some of my Vue.js projects, ported across the application to recreate the pages, and finally, updated the CI pipeline that generated the static pages and uploaded them to an S3 bucket.<\/p>\n\n<p>The end result is the same - the same HTML pages are generated and uploaded - but, for me, trying and experimenting with new things keeps my work interesting and my knowledge fresh, which benefits me as well as my colleagues and clients.<\/p>\n\n<p>As I said in a previous email, one of the great things about software development is that there's always something new to learn.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "a0bc3463255d3adc14c37179d7838fec",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0d01b877-9c31-438f-9ada-5d79dc365e28.json
Normal file
100
content/node.0d01b877-9c31-438f-9ada-5d79dc365e28.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0d01b877-9c31-438f-9ada-5d79dc365e28"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Next week is DrupalCon Barcelona"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-09-17T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/09\/17\/next-week-is-drupalcon-barcelona",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Next week is DrupalCon in Barcelona.<\/p>\n\n<p>I'm not speaking this year but if you're there and want to discuss automated testing, test-driven development, static analysis, Sculpin, Tailwind CSS, Nix, or anything else, I'll be there all week and would love to meet up and chat.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Next week is DrupalCon in Barcelona.<\/p>\n\n<p>I'm not speaking this year but if you're there and want to discuss automated testing, test-driven development, static analysis, Sculpin, Tailwind CSS, Nix, or anything else, I'll be there all week and would love to meet up and chat.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d1416da5c89de0128a5e492e9ddafdfb",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0d5835eb-bcce-451e-983c-cc3b723ac683.json
Normal file
100
content/node.0d5835eb-bcce-451e-983c-cc3b723ac683.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0d5835eb-bcce-451e-983c-cc3b723ac683"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Sculpin from Scratch"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-12-04T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/12\/04\/sculpin-from-scratch",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Over the next few weeks, I'm going to create another email course, this time about building websites with the <a href=\"https:\/\/sculpin.io\">Sculpin static site generator<\/a>.<\/p>\n\n<p>I've been using Sculpin since 2015 when <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/test-drive-twig-with-sculpin\">I used it to learn Twig<\/a> before Drupal 8's release and I use it to generate my website.<\/p>\n\n<p>I've recently been <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/building-static-websites-sculpin\">speaking about it at user groups<\/a> like PHP South West, BrumPHP and PHP Berkshire.<\/p>\n\n<p>Similar to my <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">automated testing email course<\/a>, this will send a lesson every day straight to your inbox and will show how to build a website with Sculpin from scratch.<\/p>\n\n<p>If you want to be added when it's ready or have questions, reply to this email and let me know.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Over the next few weeks, I'm going to create another email course, this time about building websites with the <a href=\"https:\/\/sculpin.io\">Sculpin static site generator<\/a>.<\/p>\n\n<p>I've been using Sculpin since 2015 when <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/test-drive-twig-with-sculpin\">I used it to learn Twig<\/a> before Drupal 8's release and I use it to generate my website.<\/p>\n\n<p>I've recently been <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/building-static-websites-sculpin\">speaking about it at user groups<\/a> like PHP South West, BrumPHP and PHP Berkshire.<\/p>\n\n<p>Similar to my <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">automated testing email course<\/a>, this will send a lesson every day straight to your inbox and will show how to build a website with Sculpin from scratch.<\/p>\n\n<p>If you want to be added when it's ready or have questions, reply to this email and let me know.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "6b905a72c2e1be12adf25aea58ea044c",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0d89691c-67a2-4a81-9acd-280702895ee3.json
Normal file
100
content/node.0d89691c-67a2-4a81-9acd-280702895ee3.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0d89691c-67a2-4a81-9acd-280702895ee3"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Discussing Drupal's ECA module"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-10-07T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/10\/07\/discussing-drupals-eca-module",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>In the most recent episode of the Beyond Blocks podcast, I spoke with J\u00fcrgen Haas about Drupal's ECA module.<\/p>\n\n<p>ECA stands for Events, Conditions and Actions and is a module I was aware of, but haven't used before - so I was great to learn more about it.<\/p>\n\n<p>I also got to meet J\u00fcrgen at DrupalCon in Barcelona, as well as several other podcast guests, which was fantastic.<\/p>\n\n<p><a href=\"https:\/\/www.oliverdavies.uk\/podcast\/23-jurgen-haas-eca\">Listen to the episode now<\/a>.<\/p>\n\n<p>If you'd like to be a guest on the podcast or want to suggest a topic, reply and let me know!<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>In the most recent episode of the Beyond Blocks podcast, I spoke with J\u00fcrgen Haas about Drupal's ECA module.<\/p>\n\n<p>ECA stands for Events, Conditions and Actions and is a module I was aware of, but haven't used before - so I was great to learn more about it.<\/p>\n\n<p>I also got to meet J\u00fcrgen at DrupalCon in Barcelona, as well as several other podcast guests, which was fantastic.<\/p>\n\n<p><a href=\"https:\/\/www.oliverdavies.uk\/podcast\/23-jurgen-haas-eca\">Listen to the episode now<\/a>.<\/p>\n\n<p>If you'd like to be a guest on the podcast or want to suggest a topic, reply and let me know!<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "cf37bf626cc98ddb264219b228efc723",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0ddf5791-bcad-45f8-be48-8a8b5a341101.json
Normal file
100
content/node.0ddf5791-bcad-45f8-be48-8a8b5a341101.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0ddf5791-bcad-45f8-be48-8a8b5a341101"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Write the test backwards\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-04-27T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/04\/27\/tdd-write-the-test-backwards",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>When writing a test, something that I like to do is start by writing the first assertion first, and then work backwards.<\/p>\n\n<p>My first assertion might be <code>self::assertTrue($result)<\/code>.<\/p>\n\n<p>If I ran this test, it would fail because of the undefined <code>$result<\/code> variable - but it's clear to me what I need next by asking, \"Where does <code>$result<\/code> come from?\".<\/p>\n\n<p>If I need to call a method on another class and get the result, I'll add it before the assertion. Then I repeat the process and ask, \"What do I need for this to work?\".<\/p>\n\n<p>Maybe I need to create some users or content in the application for the class to query and return a result based on it, so I'll create those.<\/p>\n\n<p>With this approach, I'm not making any assumptions about the test's prerequisites, and I usually find that I end up with cleaner and more focused tests.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>When writing a test, something that I like to do is start by writing the first assertion first, and then work backwards.<\/p>\n\n<p>My first assertion might be <code>self::assertTrue($result)<\/code>.<\/p>\n\n<p>If I ran this test, it would fail because of the undefined <code>$result<\/code> variable - but it's clear to me what I need next by asking, \"Where does <code>$result<\/code> come from?\".<\/p>\n\n<p>If I need to call a method on another class and get the result, I'll add it before the assertion. Then I repeat the process and ask, \"What do I need for this to work?\".<\/p>\n\n<p>Maybe I need to create some users or content in the application for the class to query and return a result based on it, so I'll create those.<\/p>\n\n<p>With this approach, I'm not making any assumptions about the test's prerequisites, and I usually find that I end up with cleaner and more focused tests.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "05685b54939905d0714bbd9c928bd011",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0e49f146-c989-4ed0-b5b3-f1203b5d6661.json
Normal file
100
content/node.0e49f146-c989-4ed0-b5b3-f1203b5d6661.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0e49f146-c989-4ed0-b5b3-f1203b5d6661"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Another way to create test module configuration"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-02-17T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/02\/17\/another-way-to-create-test-module-configuration",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>In one of the lessons in my <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">free automated testing in Drupal email course<\/a>, I explain how I create configuration that I need within my tests, such as adding a custom field:<\/p>\n\n<blockquote>\n <p>But how do you know what to name the configuration files and what content to put in them?<\/p>\n \n <p>Rather than trying to write them by hand, I create the configuration I need, such as fields, within a Drupal site and then export and edit the files I need.<\/p>\n<\/blockquote>\n\n<p>As well as creating the fields in the Drupal UI, I was also using it to export the configuration files I needed:<\/p>\n\n<blockquote>\n <p>Once Drupal is installed and the configuration has been created, you can go to - \/admin\/config\/development\/configuration\/single\/export and select the configuration type and name.<\/p>\n \n <p>The filename is shown at the bottom of the page, and you can copy the content into files within your module.<\/p>\n<\/blockquote>\n\n<h2 id=\"there%27s-another-way\">There's another way<\/h2>\n\n<p>After reading that lesson, somene replied and reminded me that there's a <code>--destination<\/code> option you can use with the <code>drush config:export<\/code> command.<\/p>\n\n<p>Instead of exporting to the standard configuration directory, I can do it to a temporary directory:<\/p>\n\n<pre><code class=\"language-shell\">run drush cex --destination \/app\/.ignored\/config\n<\/code><\/pre>\n\n<p>Everyhing in a <code>.ignored<\/code> direcotry is automatically ignored by Git, and to get the files I need, I can use Linux's <code>find<\/code> command to find any files that contain the field name and copy them into my test module directory:<\/p>\n\n<pre><code class=\"language-shell\">find .ignored\/config \\\n -type f \\\n -name \\*drupal_project\\* \\\n -exec cp -r {} web\/modules\/custom\/foo\/modules\/foo_test\/config\/install \\;\n<\/code><\/pre>\n\n<p>I still need to edit the files to remove the <code>uuid<\/code> and <code>_core<\/code> values, but this approach means less clicking in the Drupal UI which makes me more productive.<\/p>\n\n<p>I used this approach when <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/02\/16\/keep-logic-within-tests-for-as-long-as-you-can\">writing my SaaS code yesterday<\/a> and it worked well.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>In one of the lessons in my <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">free automated testing in Drupal email course<\/a>, I explain how I create configuration that I need within my tests, such as adding a custom field:<\/p>\n\n<blockquote>\n <p>But how do you know what to name the configuration files and what content to put in them?<\/p>\n \n <p>Rather than trying to write them by hand, I create the configuration I need, such as fields, within a Drupal site and then export and edit the files I need.<\/p>\n<\/blockquote>\n\n<p>As well as creating the fields in the Drupal UI, I was also using it to export the configuration files I needed:<\/p>\n\n<blockquote>\n <p>Once Drupal is installed and the configuration has been created, you can go to - \/admin\/config\/development\/configuration\/single\/export and select the configuration type and name.<\/p>\n \n <p>The filename is shown at the bottom of the page, and you can copy the content into files within your module.<\/p>\n<\/blockquote>\n\n<h2 id=\"there%27s-another-way\">There's another way<\/h2>\n\n<p>After reading that lesson, somene replied and reminded me that there's a <code>--destination<\/code> option you can use with the <code>drush config:export<\/code> command.<\/p>\n\n<p>Instead of exporting to the standard configuration directory, I can do it to a temporary directory:<\/p>\n\n<pre><code class=\"language-shell\">run drush cex --destination \/app\/.ignored\/config\n<\/code><\/pre>\n\n<p>Everyhing in a <code>.ignored<\/code> direcotry is automatically ignored by Git, and to get the files I need, I can use Linux's <code>find<\/code> command to find any files that contain the field name and copy them into my test module directory:<\/p>\n\n<pre><code class=\"language-shell\">find .ignored\/config \\\n -type f \\\n -name \\*drupal_project\\* \\\n -exec cp -r {} web\/modules\/custom\/foo\/modules\/foo_test\/config\/install \\;\n<\/code><\/pre>\n\n<p>I still need to edit the files to remove the <code>uuid<\/code> and <code>_core<\/code> values, but this approach means less clicking in the Drupal UI which makes me more productive.<\/p>\n\n<p>I used this approach when <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/02\/16\/keep-logic-within-tests-for-as-long-as-you-can\">writing my SaaS code yesterday<\/a> and it worked well.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "c22cd0a275dfae98de9b0fedf7c17fd2",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0e9e4771-7967-473d-aa46-63f5ee960298.json
Normal file
100
content/node.0e9e4771-7967-473d-aa46-63f5ee960298.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0e9e4771-7967-473d-aa46-63f5ee960298"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Things to know about PHP\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-01-17T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/01\/17\/things-to-know-about-php",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>The talk that I gave last week at PHP Stoke was <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/things-you-should-know-about-php\">Things to know about PHP<\/a> - a talk that I was originally asked to give at the Swansea Software Development Meetup (SSDC) in January 2019, and this was the second time that I've been asked to give this talk at a PHP meetup.<\/p>\n\n<p>Originally to give a group of various Software Developers an introduction to PHP, I didn't want the talk to be focused just on the language itself and be a walkthough the PHP manual.<\/p>\n\n<p>Whilst there is some code in the talk so demonstrate what it can do, the other half of the talk is about the other parts of the PHP ecosystem such as tooling and the community. I talk about tools like Composer, PHPStan, Xdebug, PHPUnit and Pest, the CMSes and frameworks that are available, and the various online learning tools like SymfonyCasts and Laracasts as well as certification programs that are available.<\/p>\n\n<p>It's great to give this talk at meetups as that's where the community starts, where people come to share and learn, and what larger conferences like PHP UK, php[tek] and others are built on. I love attending meetups and events and meeting other members of the PHP community.<\/p>\n\n<p>Oh, and elePHPants!<\/p>\n\n<p>The latest versions of the slides are on the Talks section of my website (the link is at the top of the email).<\/p>\n\n<p>If you'd like me to come and speak at your meetup or conference, please get in touch!<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>The talk that I gave last week at PHP Stoke was <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/things-you-should-know-about-php\">Things to know about PHP<\/a> - a talk that I was originally asked to give at the Swansea Software Development Meetup (SSDC) in January 2019, and this was the second time that I've been asked to give this talk at a PHP meetup.<\/p>\n\n<p>Originally to give a group of various Software Developers an introduction to PHP, I didn't want the talk to be focused just on the language itself and be a walkthough the PHP manual.<\/p>\n\n<p>Whilst there is some code in the talk so demonstrate what it can do, the other half of the talk is about the other parts of the PHP ecosystem such as tooling and the community. I talk about tools like Composer, PHPStan, Xdebug, PHPUnit and Pest, the CMSes and frameworks that are available, and the various online learning tools like SymfonyCasts and Laracasts as well as certification programs that are available.<\/p>\n\n<p>It's great to give this talk at meetups as that's where the community starts, where people come to share and learn, and what larger conferences like PHP UK, php[tek] and others are built on. I love attending meetups and events and meeting other members of the PHP community.<\/p>\n\n<p>Oh, and elePHPants!<\/p>\n\n<p>The latest versions of the slides are on the Talks section of my website (the link is at the top of the email).<\/p>\n\n<p>If you'd like me to come and speak at your meetup or conference, please get in touch!<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "05ba98327bf894b02b9686a1f5c9b14f",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0eabeb82-af67-44b4-82c5-ca948daf2372.json
Normal file
100
content/node.0eabeb82-af67-44b4-82c5-ca948daf2372.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0eabeb82-af67-44b4-82c5-ca948daf2372"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Small commits and good commit messges\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-01-24T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/01\/24\/small-commits-and-good-commit-messges",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>An important thing when using a tool like <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2023\/01\/23\/debugging-with-git-bisect\">git bisect<\/a> as well as reviewing pull\/merge requests and commits is to have small (aka \"atomic\") commits.<\/p>\n\n<p>Commits with small changes make them easier to review and, if needed, to revert and debug with bisect. If a commit has ten new or changed lines, it's much easier to see and fix a bug than if the commit had a hundred lines.<\/p>\n\n<p>If you're doing code reviews or \"Showing\" in a Ship\/Show\/Ask format, you'll likely get better and more valuable feedback if the commits are smaller and only doing one thing.<\/p>\n\n<p>If you're submitting a change for review, commit a failing test first so that it can be seen failing before committing the code to make it pass. This makes it easier to see that the code is actually making the test pass.<\/p>\n\n<p>Also take some time to write good, informative commit messages.<\/p>\n\n<p>As well as the short one-line subject, you can add as much detail as you need to the body of the message about the change that's being committed, why it's needed, what other approaches were considered or tried, as well as links to supporting documentation such as ADRs, technical design documents or diagrams.<\/p>\n\n<p>Having as much information as possible makes it much easier when someone needs to review or fix a specific commit. I like to use the <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2022\/09\/01\/conventional-commits-changelogs\">conventional commits specification<\/a>, though the main objective is to have all of the information documented so it's available in the future.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>An important thing when using a tool like <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2023\/01\/23\/debugging-with-git-bisect\">git bisect<\/a> as well as reviewing pull\/merge requests and commits is to have small (aka \"atomic\") commits.<\/p>\n\n<p>Commits with small changes make them easier to review and, if needed, to revert and debug with bisect. If a commit has ten new or changed lines, it's much easier to see and fix a bug than if the commit had a hundred lines.<\/p>\n\n<p>If you're doing code reviews or \"Showing\" in a Ship\/Show\/Ask format, you'll likely get better and more valuable feedback if the commits are smaller and only doing one thing.<\/p>\n\n<p>If you're submitting a change for review, commit a failing test first so that it can be seen failing before committing the code to make it pass. This makes it easier to see that the code is actually making the test pass.<\/p>\n\n<p>Also take some time to write good, informative commit messages.<\/p>\n\n<p>As well as the short one-line subject, you can add as much detail as you need to the body of the message about the change that's being committed, why it's needed, what other approaches were considered or tried, as well as links to supporting documentation such as ADRs, technical design documents or diagrams.<\/p>\n\n<p>Having as much information as possible makes it much easier when someone needs to review or fix a specific commit. I like to use the <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2022\/09\/01\/conventional-commits-changelogs\">conventional commits specification<\/a>, though the main objective is to have all of the information documented so it's available in the future.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "ef62cb3ca57e2e9ff518c139412e1563",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0ed28868-6aa5-4b1c-a7f2-11a3a246058e.json
Normal file
100
content/node.0ed28868-6aa5-4b1c-a7f2-11a3a246058e.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0ed28868-6aa5-4b1c-a7f2-11a3a246058e"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Drupal is older than..."
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-06-08T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/06\/08\/drupal-is-older-than",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Whilst writing <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/06\/07\/not-invented-here\">yesterday's email<\/a> about \"not invented here\", I started thinking about how Drupal's timeline (which was created 23 years ago) compares to some of the other similar or related projects.<\/p>\n\n<p>Here's a list of project release dates from ChatGPT, which seem correct to me at a glance:<\/p>\n\n<ul>\n<li>Drupal: January 15, 2001.<\/li>\n<li>Git: April 7, 2005.<\/li>\n<li>Symfony 1: October 22, 2005.<\/li>\n<li>GitHub and Bitbucket: 2008.<\/li>\n<li>GitLab: October 2011.<\/li>\n<li>Laravel: June 9, 2011.<\/li>\n<li>Drupal 7: January 5, 2011.<\/li>\n<li>Symfony 2: July 28, 2011.<\/li>\n<li>Composer: March 1, 2012.<\/li>\n<li>Drupal 8: November 19, 2015.<\/li>\n<\/ul>\n\n<p>Looking at this list, when speaking about \"not invented here\", a lot of what Drupal would come to use and depend on just didn't exist in its early years.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Whilst writing <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/06\/07\/not-invented-here\">yesterday's email<\/a> about \"not invented here\", I started thinking about how Drupal's timeline (which was created 23 years ago) compares to some of the other similar or related projects.<\/p>\n\n<p>Here's a list of project release dates from ChatGPT, which seem correct to me at a glance:<\/p>\n\n<ul>\n<li>Drupal: January 15, 2001.<\/li>\n<li>Git: April 7, 2005.<\/li>\n<li>Symfony 1: October 22, 2005.<\/li>\n<li>GitHub and Bitbucket: 2008.<\/li>\n<li>GitLab: October 2011.<\/li>\n<li>Laravel: June 9, 2011.<\/li>\n<li>Drupal 7: January 5, 2011.<\/li>\n<li>Symfony 2: July 28, 2011.<\/li>\n<li>Composer: March 1, 2012.<\/li>\n<li>Drupal 8: November 19, 2015.<\/li>\n<\/ul>\n\n<p>Looking at this list, when speaking about \"not invented here\", a lot of what Drupal would come to use and depend on just didn't exist in its early years.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "26c761c39af062f8236f0e3f605571b4",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0f83e137-8106-4b13-b9ef-e35ed2dacf98.json
Normal file
100
content/node.0f83e137-8106-4b13-b9ef-e35ed2dacf98.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0f83e137-8106-4b13-b9ef-e35ed2dacf98"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Aliases and abbreviations"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-06-22T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/06\/22\/aliases-and-abbreviations",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Yesterday, I said <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/06\/21\/dont-use-aliases\">not to use custom shell aliases and functions<\/a> during presentations and group programming sessions to avoid confusion.<\/p>\n\n<p>I use aliases, but they expand after I type them, the same as as snippet in an IDE or text editor.<\/p>\n\n<p>Me and everyone else can see the underlying command, and that's also what's saved in my shell history.<\/p>\n\n<p>I still have the benefit of not having to type the whole command without obscuring it.<\/p>\n\n<p>I used to have custom code in my zsh configuration, but recently <a href=\"https:\/\/github.com\/opdavies\/dotfiles.nix\/commit\/0df5f17dae4328546b5d08eef141656a5de2b522\">switched to zsh-abbr<\/a>.<\/p>\n\n<p>The first impressions are positive and I no longer need to maintain my custom code.<\/p>\n\n<p>I use aliases for commands I don't want to expand, but I've moved everything else has moved to abbreviations.<\/p>\n\n<p>If you use zsh, I recommend trying it.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Yesterday, I said <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/06\/21\/dont-use-aliases\">not to use custom shell aliases and functions<\/a> during presentations and group programming sessions to avoid confusion.<\/p>\n\n<p>I use aliases, but they expand after I type them, the same as as snippet in an IDE or text editor.<\/p>\n\n<p>Me and everyone else can see the underlying command, and that's also what's saved in my shell history.<\/p>\n\n<p>I still have the benefit of not having to type the whole command without obscuring it.<\/p>\n\n<p>I used to have custom code in my zsh configuration, but recently <a href=\"https:\/\/github.com\/opdavies\/dotfiles.nix\/commit\/0df5f17dae4328546b5d08eef141656a5de2b522\">switched to zsh-abbr<\/a>.<\/p>\n\n<p>The first impressions are positive and I no longer need to maintain my custom code.<\/p>\n\n<p>I use aliases for commands I don't want to expand, but I've moved everything else has moved to abbreviations.<\/p>\n\n<p>If you use zsh, I recommend trying it.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e8c940daa789af9482140efa9f72c6fe",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0fdc9168-3654-4df4-b88b-4d47ceb9b9af.json
Normal file
100
content/node.0fdc9168-3654-4df4-b88b-4d47ceb9b9af.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0fdc9168-3654-4df4-b88b-4d47ceb9b9af"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Maintaining backward compatibility"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-07-30T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/07\/30\/maintaining-backward-compatibility",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I've recently decided I'm going to open source <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/building-build-configs\">Build Configs tool<\/a> that I use to generate build configuration files for Drupal, Sculpin and Fractal projects.<\/p>\n\n<p>Inspired by <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/working-with-workspace\">Workspace<\/a> and others, and based on previous versions of similar tools - most recently by <a href=\"https:\/\/github.com\/ALT-F4-LLC\/build-configs\">TheAltF4Stream's project with the same name<\/a> (which is written in Rust and supports different template types) - I've been using this tool to manage configuration files for various personal, client and open-source projects.<\/p>\n\n<p>Before I open-source it, there are some changes I'd like to make, such as renaming some template types and updating the format and keys within the configuration file.<\/p>\n\n<p>Changes to the configuration file would be a breaking change and, whilst it's only me using it, I want my other projects to keep working and for me to continue supporting the prior versions - at least for now, so I want to make sure any changes are backward compatible.<\/p>\n\n<h2 id=\"how-it-works\">How it works<\/h2>\n\n<p>There are four steps performed when generating files for a project:<\/p>\n\n<ul>\n<li>Create a final configuration object from the project's configuration file as well as any defaults.<\/li>\n<li>Validate the final configuration.<\/li>\n<li>Create a list of files to generate.<\/li>\n<li>Generate the files.<\/li>\n<\/ul>\n\n<p>If I change <code>sculpin<\/code> to <code>sculpin-site<\/code> in a configuration file, for example, it will fail the validation step.<\/p>\n\n<p>But, I have an opportunity within the first step to perform any normalisation that's needed and to provide a compatibility layer - such as changing <code>sculpin-site<\/code>, which is an invalid value, to <code>sculpin<\/code>.<\/p>\n\n<p>I also renamed <code>symfony<\/code> to <code>symfony-cli<\/code> by performing the same step.<\/p>\n\n<p>This means the validation step will receive valid data that it can use and the new changes have been encapsulated within a single step of the process. I haven't needed to change any code elsewhere.<\/p>\n\n<p>I can also add deprecation warnings if legacy values are used.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>Similar to feature flags, this is temporary code that will later be removed when I'm ready to remove the compatibility layer, similar to how <code>drupal_set_message()<\/code> was deprecated and changed to use the <code>Messenger<\/code> service before being removed in Drupal 9.<\/p>\n\n<p>In the future, I can refactor the internal logic to use a different approach and when I'm ready, eventually remove the compatibility layer and tag a new major version with the breaking changes.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I've recently decided I'm going to open source <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/building-build-configs\">Build Configs tool<\/a> that I use to generate build configuration files for Drupal, Sculpin and Fractal projects.<\/p>\n\n<p>Inspired by <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/working-with-workspace\">Workspace<\/a> and others, and based on previous versions of similar tools - most recently by <a href=\"https:\/\/github.com\/ALT-F4-LLC\/build-configs\">TheAltF4Stream's project with the same name<\/a> (which is written in Rust and supports different template types) - I've been using this tool to manage configuration files for various personal, client and open-source projects.<\/p>\n\n<p>Before I open-source it, there are some changes I'd like to make, such as renaming some template types and updating the format and keys within the configuration file.<\/p>\n\n<p>Changes to the configuration file would be a breaking change and, whilst it's only me using it, I want my other projects to keep working and for me to continue supporting the prior versions - at least for now, so I want to make sure any changes are backward compatible.<\/p>\n\n<h2 id=\"how-it-works\">How it works<\/h2>\n\n<p>There are four steps performed when generating files for a project:<\/p>\n\n<ul>\n<li>Create a final configuration object from the project's configuration file as well as any defaults.<\/li>\n<li>Validate the final configuration.<\/li>\n<li>Create a list of files to generate.<\/li>\n<li>Generate the files.<\/li>\n<\/ul>\n\n<p>If I change <code>sculpin<\/code> to <code>sculpin-site<\/code> in a configuration file, for example, it will fail the validation step.<\/p>\n\n<p>But, I have an opportunity within the first step to perform any normalisation that's needed and to provide a compatibility layer - such as changing <code>sculpin-site<\/code>, which is an invalid value, to <code>sculpin<\/code>.<\/p>\n\n<p>I also renamed <code>symfony<\/code> to <code>symfony-cli<\/code> by performing the same step.<\/p>\n\n<p>This means the validation step will receive valid data that it can use and the new changes have been encapsulated within a single step of the process. I haven't needed to change any code elsewhere.<\/p>\n\n<p>I can also add deprecation warnings if legacy values are used.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>Similar to feature flags, this is temporary code that will later be removed when I'm ready to remove the compatibility layer, similar to how <code>drupal_set_message()<\/code> was deprecated and changed to use the <code>Messenger<\/code> service before being removed in Drupal 9.<\/p>\n\n<p>In the future, I can refactor the internal logic to use a different approach and when I'm ready, eventually remove the compatibility layer and tag a new major version with the breaking changes.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "a38ce17b89e3700c2d33876324be5747",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.0ff92b0d-5dd5-4afd-a0b0-e4699d5e5b5b.json
Normal file
100
content/node.0ff92b0d-5dd5-4afd-a0b0-e4699d5e5b5b.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "0ff92b0d-5dd5-4afd-a0b0-e4699d5e5b5b"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Start with a vague test\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-08-25T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/08\/25\/start-with-a-vague-test",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>If you're unsure what your first test should be, start by writing a test with an intentionally vague name, just to get you started.<\/p>\n\n<p>It may not be clear straight away what you're trying to test.<\/p>\n\n<p>Once you get the ball rolling and you write more, it will usually become clear.<\/p>\n\n<p>Then you can go back and rename the test method to something more specific.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>If you're unsure what your first test should be, start by writing a test with an intentionally vague name, just to get you started.<\/p>\n\n<p>It may not be clear straight away what you're trying to test.<\/p>\n\n<p>Once you get the ball rolling and you write more, it will usually become clear.<\/p>\n\n<p>Then you can go back and rename the test method to something more specific.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "019e5d597f894b924aac0c6b461b07fd",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.10118aa2-ab09-49be-9ac3-62f554d7ab46.json
Normal file
100
content/node.10118aa2-ab09-49be-9ac3-62f554d7ab46.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "10118aa2-ab09-49be-9ac3-62f554d7ab46"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "An interesting thing I spotted about the Override Node Options module"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-11-16T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/11\/16\/an-interesting-thing-i-spotted-about-the-override-node-options-module",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Before <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/13\/speaking-at-the-drupal-london-meetup\">my remote talk for the Drupal London meetup<\/a>, I'm updating the usage statistics for <a href=\"https:\/\/www.drupal.org\/project\/override_node_options\">the Override Node Options module<\/a> - one of the modules I maintain on Drupal.org.<\/p>\n\n<p>In my slides for DrupalCamp Belgium, I showed the usage figures from October 2023, which showed 38,096 installations and it being the 173rd most installed module.<\/p>\n\n<p>This week, the number of installations has slightly increased to 38,223.<\/p>\n\n<p>What's interesting is that whilst the number of installations has been consistent, there are a lot less Drupal 7 websites using the module and a lot more Drupal 8+ sites using it.<\/p>\n\n<h2 id=\"october-2023\">October 2023<\/h2>\n\n<ul>\n<li>5.x-1.x: 1<\/li>\n<li>6.x-1.x: 297<\/li>\n<li>7.x-1.x: 13,717<\/li>\n<li>8.x-2.x: 24,081<\/li>\n<li>Total: 38,096<\/li>\n<\/ul>\n\n<h2 id=\"november-2024\">November 2024<\/h2>\n\n<ul>\n<li>5.x-1.x: 4<\/li>\n<li>6.x-1.x: 202<\/li>\n<li>7.x-1.x: 10,429<\/li>\n<li>8.x-2.x: 27,588<\/li>\n<li>Total: 38,223<\/li>\n<\/ul>\n\n<p>Assuming these numbers are correct, this makes me feel very positive and happy about the adoption of newer versions of Drupal and that people are upgrading their D7 websites to Drupal 10 or 11.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Before <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/11\/13\/speaking-at-the-drupal-london-meetup\">my remote talk for the Drupal London meetup<\/a>, I'm updating the usage statistics for <a href=\"https:\/\/www.drupal.org\/project\/override_node_options\">the Override Node Options module<\/a> - one of the modules I maintain on Drupal.org.<\/p>\n\n<p>In my slides for DrupalCamp Belgium, I showed the usage figures from October 2023, which showed 38,096 installations and it being the 173rd most installed module.<\/p>\n\n<p>This week, the number of installations has slightly increased to 38,223.<\/p>\n\n<p>What's interesting is that whilst the number of installations has been consistent, there are a lot less Drupal 7 websites using the module and a lot more Drupal 8+ sites using it.<\/p>\n\n<h2 id=\"october-2023\">October 2023<\/h2>\n\n<ul>\n<li>5.x-1.x: 1<\/li>\n<li>6.x-1.x: 297<\/li>\n<li>7.x-1.x: 13,717<\/li>\n<li>8.x-2.x: 24,081<\/li>\n<li>Total: 38,096<\/li>\n<\/ul>\n\n<h2 id=\"november-2024\">November 2024<\/h2>\n\n<ul>\n<li>5.x-1.x: 4<\/li>\n<li>6.x-1.x: 202<\/li>\n<li>7.x-1.x: 10,429<\/li>\n<li>8.x-2.x: 27,588<\/li>\n<li>Total: 38,223<\/li>\n<\/ul>\n\n<p>Assuming these numbers are correct, this makes me feel very positive and happy about the adoption of newer versions of Drupal and that people are upgrading their D7 websites to Drupal 10 or 11.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "cd0913ec770f5778cd0c8fc66aca2797",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.104d1521-1e8a-402b-8136-09f3a2f33a7b.json
Normal file
100
content/node.104d1521-1e8a-402b-8136-09f3a2f33a7b.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "104d1521-1e8a-402b-8136-09f3a2f33a7b"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "A crash course into automated testing with Drupal\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-08-02T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/08\/02\/a-crash-course-into-drupal-testing",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Next week, I'll be presenting a lightning talk at the North West Drupal user group (NWDUG)'s August meetup.<\/p>\n\n<p>It'll be a crash course into automated testing and test-driven development with Drupal, in which I plan to show how to get started by writing and running your first automated tests whilst exploring the different types of tests that are available.<\/p>\n\n<p>It's an online event, so if you'd like to see this and other lightning talks on the 8th of August, RSVP at <a href=\"https:\/\/www.meetup.com\/nwdrupal\/events\/293429104\">https:\/\/www.meetup.com\/nwdrupal\/events\/293429104<\/a>.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Next week, I'll be presenting a lightning talk at the North West Drupal user group (NWDUG)'s August meetup.<\/p>\n\n<p>It'll be a crash course into automated testing and test-driven development with Drupal, in which I plan to show how to get started by writing and running your first automated tests whilst exploring the different types of tests that are available.<\/p>\n\n<p>It's an online event, so if you'd like to see this and other lightning talks on the 8th of August, RSVP at <a href=\"https:\/\/www.meetup.com\/nwdrupal\/events\/293429104\">https:\/\/www.meetup.com\/nwdrupal\/events\/293429104<\/a>.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "770e300e666c4816b8e8fc9943555225",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.10b722e1-1c5b-4267-b661-d0edc94ff17c.json
Normal file
100
content/node.10b722e1-1c5b-4267-b661-d0edc94ff17c.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "10b722e1-1c5b-4267-b661-d0edc94ff17c"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Legacy code is anything older than..."
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-03-22T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/03\/22\/legacy",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>How do you define legacy code?<\/p>\n\n<p>Code that was written by someone else?<\/p>\n\n<p>Code that doesn't have tests?<\/p>\n\n<p>Any code that has been released to production?<\/p>\n\n<p>Code that's more than a day old?<\/p>\n\n<p>In a talk I recently watched, the speaker suggested that any code written more than thirty minutes ago is legacy code.<\/p>\n\n<p>Once you've written some code and left it for half an hour, you need to re-read it to remember and re-learn what the code does and decide how you want to implement your next requirement.<\/p>\n\n<p>This is the same approach for code that was written longer ago or written by someone else.<\/p>\n\n<p>What do you think?<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>How do you define legacy code?<\/p>\n\n<p>Code that was written by someone else?<\/p>\n\n<p>Code that doesn't have tests?<\/p>\n\n<p>Any code that has been released to production?<\/p>\n\n<p>Code that's more than a day old?<\/p>\n\n<p>In a talk I recently watched, the speaker suggested that any code written more than thirty minutes ago is legacy code.<\/p>\n\n<p>Once you've written some code and left it for half an hour, you need to re-read it to remember and re-learn what the code does and decide how you want to implement your next requirement.<\/p>\n\n<p>This is the same approach for code that was written longer ago or written by someone else.<\/p>\n\n<p>What do you think?<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "9983c859dafd94ec45282b7438b9cb59",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.111494e9-16b6-4099-8792-04d562eadbf6.json
Normal file
100
content/node.111494e9-16b6-4099-8792-04d562eadbf6.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "111494e9-16b6-4099-8792-04d562eadbf6"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Creating a Drupal 10 compatible version of Override Node Options\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-02-18T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/02\/18\/drupal-10-version-of-override-node-options",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Today, I reviewed <a href=\"https:\/\/www.drupal.org\/project\/override_node_options\/issues\/3269901\">the issue and merge request<\/a> to make the <a href=\"https:\/\/www.drupal.org\/project\/override_node_options\">Override Node Options<\/a> module compatible with Drupal 10.<\/p>\n\n<p>It's a small patch that mainly affects the module's test suite so has a low risk of breaking the functionality of the module.<\/p>\n\n<p>As well as the automated tests, I've done some manual testing with the patch applied on both Drupal 9.5 and 10.<\/p>\n\n<p>The project page shows the module is currently used on over 34,000 sites including 18,565 Drupal 8 and 9 websites on the 8.x-2.x branch. Hopefully this number will continue to increase once the Drupal 10 version is released.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Today, I reviewed <a href=\"https:\/\/www.drupal.org\/project\/override_node_options\/issues\/3269901\">the issue and merge request<\/a> to make the <a href=\"https:\/\/www.drupal.org\/project\/override_node_options\">Override Node Options<\/a> module compatible with Drupal 10.<\/p>\n\n<p>It's a small patch that mainly affects the module's test suite so has a low risk of breaking the functionality of the module.<\/p>\n\n<p>As well as the automated tests, I've done some manual testing with the patch applied on both Drupal 9.5 and 10.<\/p>\n\n<p>The project page shows the module is currently used on over 34,000 sites including 18,565 Drupal 8 and 9 websites on the 8.x-2.x branch. Hopefully this number will continue to increase once the Drupal 10 version is released.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "a4d60c0bc89cf319cc0a3598dc62b82f",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.111732f0-ada3-423b-a4c0-79b1b6e28272.json
Normal file
100
content/node.111732f0-ada3-423b-a4c0-79b1b6e28272.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "111732f0-ada3-423b-a4c0-79b1b6e28272"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "The Boy Scout rule\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-12-22T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/12\/22\/the-boy-scout-rule",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>The Boy Scout rule is \"Always leave the campground cleaner than you found it\".<\/p>\n\n<p>From a programming perspective, \"Always leave the code better than you find it\".<\/p>\n\n<p>If you're working on some code and see some commented-out lines or unused variables, once you've finished with your changes, remove them too.<\/p>\n\n<p>If there's a variable that could have a more descriptive name, change it.<\/p>\n\n<p>If there are any other refactors you can do, do them and leave the code better than before and easier for the next Developer (whether it's you or someone else) to work with.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>The Boy Scout rule is \"Always leave the campground cleaner than you found it\".<\/p>\n\n<p>From a programming perspective, \"Always leave the code better than you find it\".<\/p>\n\n<p>If you're working on some code and see some commented-out lines or unused variables, once you've finished with your changes, remove them too.<\/p>\n\n<p>If there's a variable that could have a more descriptive name, change it.<\/p>\n\n<p>If there are any other refactors you can do, do them and leave the code better than before and easier for the next Developer (whether it's you or someone else) to work with.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "f37cca5f2692bfc4e92b042590c4cab1",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.11d7adfc-89a7-4d4c-b0b3-47577970178d.json
Normal file
100
content/node.11d7adfc-89a7-4d4c-b0b3-47577970178d.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "11d7adfc-89a7-4d4c-b0b3-47577970178d"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Avoiding nesting"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-04-07T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/04\/07\/avoiding-nesting",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>One of my goals when coding is to reduce the amount of nesting in the code I write.<\/p>\n\n<p>I mean both in my PHP code where if conditions and foreach loops can be nested within each other, and CSS and Sass files, which support nesting CSS rules.<\/p>\n\n<p>My aim is to have a maximum of two or three levels of indentation, though sometimes this isn't possible.<\/p>\n\n<p>Doing so where I can, though, makes my code easier to read and understand and encourages other clean code approaches, such as having small and well-named functions.<\/p>\n\n<p>In CSS or Sass, avoiding nesting makes it easier to find a rule I'm looking for instead of having to find how rules have been nested or names have been concatenated - making it hard to search or grep for a string.<\/p>\n\n<p>This approach is part of \"object callisthenics\", which was introduced by Jeff Bay and includes other approaches that I like to follow, such as not using the <code>else<\/code> keyword and other good practices that I like to try and implement when possible.--<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>One of my goals when coding is to reduce the amount of nesting in the code I write.<\/p>\n\n<p>I mean both in my PHP code where if conditions and foreach loops can be nested within each other, and CSS and Sass files, which support nesting CSS rules.<\/p>\n\n<p>My aim is to have a maximum of two or three levels of indentation, though sometimes this isn't possible.<\/p>\n\n<p>Doing so where I can, though, makes my code easier to read and understand and encourages other clean code approaches, such as having small and well-named functions.<\/p>\n\n<p>In CSS or Sass, avoiding nesting makes it easier to find a rule I'm looking for instead of having to find how rules have been nested or names have been concatenated - making it hard to search or grep for a string.<\/p>\n\n<p>This approach is part of \"object callisthenics\", which was introduced by Jeff Bay and includes other approaches that I like to follow, such as not using the <code>else<\/code> keyword and other good practices that I like to try and implement when possible.--<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "6f502f1378e2ffcb9acf63bd11ff5325",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.121e8b36-a88a-420a-a962-e83efd211961.json
Normal file
100
content/node.121e8b36-a88a-420a-a962-e83efd211961.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "121e8b36-a88a-420a-a962-e83efd211961"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Tailwind CSS v4, with even more CSS"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-07-16T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/07\/16\/tailwind-css-v4--with-even-more-css",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As someone <a href=\"https:\/\/www.oliverdavies.uk\/blog\/uis-ive-rebuilt-tailwind-css\">who has been using Tailwind CSS<\/a> since before 1.0, I'm looking forward to the next major version - Tailwind CSS v4.<\/p>\n\n<p>A main difference compared to previous versions is that it will be configured in CSS using CSS variables (aka custom properties).<\/p>\n\n<p>No more <code>tailwind.config.js<\/code> configuration files, just variables like <code>--color-blue-100<\/code>.<\/p>\n\n<p>As I <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/07\/15\/the-power-of-arbitrary-classes\">already use CSS variables in some situations<\/a>, I like that it will make it easier to re-use them within Tailwind and give a more consistent experience.<\/p>\n\n<p>As well as simple variables, such as colours and spacing, I'm interested to see how everything else will translate to the new configuration approach in Tailwind v4, as well as anything else new that will be included.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As someone <a href=\"https:\/\/www.oliverdavies.uk\/blog\/uis-ive-rebuilt-tailwind-css\">who has been using Tailwind CSS<\/a> since before 1.0, I'm looking forward to the next major version - Tailwind CSS v4.<\/p>\n\n<p>A main difference compared to previous versions is that it will be configured in CSS using CSS variables (aka custom properties).<\/p>\n\n<p>No more <code>tailwind.config.js<\/code> configuration files, just variables like <code>--color-blue-100<\/code>.<\/p>\n\n<p>As I <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/07\/15\/the-power-of-arbitrary-classes\">already use CSS variables in some situations<\/a>, I like that it will make it easier to re-use them within Tailwind and give a more consistent experience.<\/p>\n\n<p>As well as simple variables, such as colours and spacing, I'm interested to see how everything else will translate to the new configuration approach in Tailwind v4, as well as anything else new that will be included.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "38f60865df47fe3136bab0faff10ad7c",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.125a106e-aabb-4425-a72f-95bf6cf968b1.json
Normal file
100
content/node.125a106e-aabb-4425-a72f-95bf6cf968b1.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "125a106e-aabb-4425-a72f-95bf6cf968b1"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "TDD doesn't mean you know everything upfront"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-01-30T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/01\/30\/tdd-doesnt-mean-you-know-everything-upfront",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I'm in the final phase of a Drupal development project for a customer.<\/p>\n\n<p>It has some custom modules and code I wrote with automated tests and test-driven development.<\/p>\n\n<p>Today, the client reported a bug.<\/p>\n\n<p>But, instead of something working incorrectly, this was a use case I hadn't considered.<\/p>\n\n<p>The tests were passing, but there wasn't one for this.<\/p>\n\n<p>I wrote the code for the use cases I was aware of when I started, and now I'm aware of another, I can add a test for it and ensure it's tested and working.<\/p>\n\n<p>To do test-driven development, you don't need to know all the use cases and functionality upfront.<\/p>\n\n<p>Write for what you know at the time, then expand and iterate in the future.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I'm in the final phase of a Drupal development project for a customer.<\/p>\n\n<p>It has some custom modules and code I wrote with automated tests and test-driven development.<\/p>\n\n<p>Today, the client reported a bug.<\/p>\n\n<p>But, instead of something working incorrectly, this was a use case I hadn't considered.<\/p>\n\n<p>The tests were passing, but there wasn't one for this.<\/p>\n\n<p>I wrote the code for the use cases I was aware of when I started, and now I'm aware of another, I can add a test for it and ensure it's tested and working.<\/p>\n\n<p>To do test-driven development, you don't need to know all the use cases and functionality upfront.<\/p>\n\n<p>Write for what you know at the time, then expand and iterate in the future.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "15b5f4507ca4a5cb62249ea0461feb8a",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.127c5133-8772-4c8b-84e9-a85d06d7628a.json
Normal file
100
content/node.127c5133-8772-4c8b-84e9-a85d06d7628a.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "127c5133-8772-4c8b-84e9-a85d06d7628a"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "How easily can you move changes between environments?"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-12-24T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/12\/24\/moving-changes",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Regardless of <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/12\/23\/how-many-environments-do-you-need\">how many environments your application has<\/a>, you need to be able to move changes between them reliably.<\/p>\n\n<p>You don't want to configure each environment and make every change by hand.<\/p>\n\n<p>You want to automate this as much as possible so your changes are the same every time.<\/p>\n\n<p>In Drupal 7, the Features module was used to export changes once and apply them again using a <code>features revert<\/code> command - although its original use case was to extract reusable features for different applications.<\/p>\n\n<p>I've also written a lot of update of update hooks, like <code>mymodule_update_8001<\/code> to apply changes when database updates are applied.<\/p>\n\n<p>Since Drupal 8, we've had configuration management - a first-class way to export and import configuration changes - which I think was one of the best additions to Drupal 8, and something not available in some other CMSes, frameworks and applications.<\/p>\n\n<p>There's an ecosystem around configuration management, including Config Split for per-environment configurations and Config Ignore to ignore sensitive information or changes you don't want to manage via imported configuration.<\/p>\n\n<p>I recently worked on a project where we didn't have a CI pipeline running configuration imports on each change and things were very difficult to manage. Once that was in place, though, things were much easier, more consistent and changes were quicker to release.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Regardless of <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/12\/23\/how-many-environments-do-you-need\">how many environments your application has<\/a>, you need to be able to move changes between them reliably.<\/p>\n\n<p>You don't want to configure each environment and make every change by hand.<\/p>\n\n<p>You want to automate this as much as possible so your changes are the same every time.<\/p>\n\n<p>In Drupal 7, the Features module was used to export changes once and apply them again using a <code>features revert<\/code> command - although its original use case was to extract reusable features for different applications.<\/p>\n\n<p>I've also written a lot of update of update hooks, like <code>mymodule_update_8001<\/code> to apply changes when database updates are applied.<\/p>\n\n<p>Since Drupal 8, we've had configuration management - a first-class way to export and import configuration changes - which I think was one of the best additions to Drupal 8, and something not available in some other CMSes, frameworks and applications.<\/p>\n\n<p>There's an ecosystem around configuration management, including Config Split for per-environment configurations and Config Ignore to ignore sensitive information or changes you don't want to manage via imported configuration.<\/p>\n\n<p>I recently worked on a project where we didn't have a CI pipeline running configuration imports on each change and things were very difficult to manage. Once that was in place, though, things were much easier, more consistent and changes were quicker to release.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "edb67464b9188fe49c1cef46dfa04ac8",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.13287170-0050-466b-bb7e-d7785cd68f8f.json
Normal file
100
content/node.13287170-0050-466b-bb7e-d7785cd68f8f.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "13287170-0050-466b-bb7e-d7785cd68f8f"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Drupal 9 is now end of life\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-11-01T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/11\/01\/drupal-9-is-now-end-of-life",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As of today, Drupal 9 is end-of-life and no longer supported.<\/p>\n\n<h2 id=\"why%3F\">Why?<\/h2>\n\n<p>Drupal 9 relies on several other software projects, including Symfony, CKEditor, and Twig.<\/p>\n\n<p>With Symfony 4's end of life, CKEditor 4's end of life, and Twig 2's end of life all coming up soon, Drupal 9 went end of life on November 1st, 2023.<\/p>\n\n<h2 id=\"what-do-i-do-next%3F\">What do I do next?<\/h2>\n\n<p>There will be no further releases of Drupal 9 so you need to upgrade.<\/p>\n\n<p>If you're stuck on Drupal 9, 8, or 7, get unstuck with a <a href=\"https:\/\/www.oliverdavies.uk\/drupal-upgrade\">Drupal upgrade roadmap<\/a> and get directions how to upgrade to Drupal 10.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As of today, Drupal 9 is end-of-life and no longer supported.<\/p>\n\n<h2 id=\"why%3F\">Why?<\/h2>\n\n<p>Drupal 9 relies on several other software projects, including Symfony, CKEditor, and Twig.<\/p>\n\n<p>With Symfony 4's end of life, CKEditor 4's end of life, and Twig 2's end of life all coming up soon, Drupal 9 went end of life on November 1st, 2023.<\/p>\n\n<h2 id=\"what-do-i-do-next%3F\">What do I do next?<\/h2>\n\n<p>There will be no further releases of Drupal 9 so you need to upgrade.<\/p>\n\n<p>If you're stuck on Drupal 9, 8, or 7, get unstuck with a <a href=\"https:\/\/www.oliverdavies.uk\/drupal-upgrade\">Drupal upgrade roadmap<\/a> and get directions how to upgrade to Drupal 10.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "6e4460ba8f2e7ef1df4c709299bfb0a6",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1339a3e5-43bf-4a7a-a6e2-ba8e8d950353.json
Normal file
100
content/node.1339a3e5-43bf-4a7a-a6e2-ba8e8d950353.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1339a3e5-43bf-4a7a-a6e2-ba8e8d950353"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Do we still need CSS preprocessors?"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-02-28T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/02\/28\/preprocessors",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Before I started to use [Tailwind CSS][0], I used CSS preprocessors like Less and Sass to add features like variables and nesting to my CSS files.<\/p>\n\n<p>Stylesheets would be written in .scss, .sass or .less files and processed to create the stylesheets that would be used by browsers.<\/p>\n\n<p>But, with the recent improvements to CSS, do we still need these preprocessors?<\/p>\n\n<p>Here's a very small example of some CSS that just works:<\/p>\n\n<pre><code class=\"css\">:root {\n --color-primary: red;\n --color-secondary: green;\n}\n\na {\n color: var(--color-primary);\n\n &:hover, &:focus {\n color: var(--color-secondary);\n }\n}\n<\/code><\/pre>\n\n<p>It looks like a Sass file, but it's native CSS.<\/p>\n\n<p>It has variables (a.k.a. custom properties) and nesting, which I think are the most used features from preprocessors.<\/p>\n\n<p>But there's no additional build step to generate the end stylesheet. I can use this stylesheet as it is - making it easier to work on and less confusing for new Developers.<\/p>\n\n<p>If I'm not using Tailwind CSS or atomic styles, writing plain CSS files is the approach I'd use.<\/p>\n\n<p>No preprocessors needed.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Before I started to use [Tailwind CSS][0], I used CSS preprocessors like Less and Sass to add features like variables and nesting to my CSS files.<\/p>\n\n<p>Stylesheets would be written in .scss, .sass or .less files and processed to create the stylesheets that would be used by browsers.<\/p>\n\n<p>But, with the recent improvements to CSS, do we still need these preprocessors?<\/p>\n\n<p>Here's a very small example of some CSS that just works:<\/p>\n\n<pre><code class=\"css\">:root {\n --color-primary: red;\n --color-secondary: green;\n}\n\na {\n color: var(--color-primary);\n\n &:hover, &:focus {\n color: var(--color-secondary);\n }\n}\n<\/code><\/pre>\n\n<p>It looks like a Sass file, but it's native CSS.<\/p>\n\n<p>It has variables (a.k.a. custom properties) and nesting, which I think are the most used features from preprocessors.<\/p>\n\n<p>But there's no additional build step to generate the end stylesheet. I can use this stylesheet as it is - making it easier to work on and less confusing for new Developers.<\/p>\n\n<p>If I'm not using Tailwind CSS or atomic styles, writing plain CSS files is the approach I'd use.<\/p>\n\n<p>No preprocessors needed.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "cdd9ab25b0351a9082e1580898e5ecbc",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.13568c60-3efa-495e-9c19-b0ff274da152.json
Normal file
100
content/node.13568c60-3efa-495e-9c19-b0ff274da152.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "13568c60-3efa-495e-9c19-b0ff274da152"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Think smaller with TDD\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-07-04T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/07\/04\/think-smaller-with-tdd",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I've recently added several custom search blocks and pages to a client project.<\/p>\n\n<p>Each requires a results page, a list of autocomplete suggestions for users to select from, a custom form, and a block to place it on the required pages.<\/p>\n\n<p>For each search, I'm first testing the results page, ensuring it exists and contains the correct results before testing the autocomplete results, creating the block and form, and linking everything together.<\/p>\n\n<h2 id=\"thinking-small\">Thinking small<\/h2>\n\n<p>This could seem like a large and daunting task, but with test-driven development, I can break everything into smaller, more manageable tasks.<\/p>\n\n<p>My objective is either to write the next failing test and then get it to pass or to refactor what I've written.<\/p>\n\n<p>I can focus on these small steps and make progress towards the end goal, guided by the tests I'm writing, instead of needing to focus always on one large and complex task.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I've recently added several custom search blocks and pages to a client project.<\/p>\n\n<p>Each requires a results page, a list of autocomplete suggestions for users to select from, a custom form, and a block to place it on the required pages.<\/p>\n\n<p>For each search, I'm first testing the results page, ensuring it exists and contains the correct results before testing the autocomplete results, creating the block and form, and linking everything together.<\/p>\n\n<h2 id=\"thinking-small\">Thinking small<\/h2>\n\n<p>This could seem like a large and daunting task, but with test-driven development, I can break everything into smaller, more manageable tasks.<\/p>\n\n<p>My objective is either to write the next failing test and then get it to pass or to refactor what I've written.<\/p>\n\n<p>I can focus on these small steps and make progress towards the end goal, guided by the tests I'm writing, instead of needing to focus always on one large and complex task.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "9266f4bfd35bc443765c6c434bc5975e",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.135f19e2-67e7-434d-9ca7-c8d78512a9da.json
Normal file
100
content/node.135f19e2-67e7-434d-9ca7-c8d78512a9da.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "135f19e2-67e7-434d-9ca7-c8d78512a9da"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Do you need to branch if you're the only one working on a project?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-11-23T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/11\/23\/do-you-need-to-branch",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Yesterday, I <a href=\"https:\/\/twitter.com\/scottkeckwarren\/status\/1594752744165847040\">saw a tweet<\/a> where the writer said they were \u201cfalling into the branch, pull request, and merge after actions pass I use at work even though I'm the only one working on it\u201d.<\/p>\n\n<p>After reading this, my question is, \"Should you, or do you need to, create branches if you're the only person working on a project?\".<\/p>\n\n<p>These days, I use trunk-based development as much as possible, so I hardly ever create new branches, whether working on a project myself or with a team.<\/p>\n\n<p><a href=\"https:\/\/www.oliverdavies.uk\/presentations\/git-flow\">I used to use Git Flow<\/a> and create branches for every new feature and bug fix, but I remember, whilst demonstrating two work-in-progress features to a client, switching between the different branches caused my local site to break. Whilst it wasn\u2019t a major issue, it wouldn't have seemed professional.<\/p>\n\n<p>In a team environment, feature branches are intended to keep different changes and different people's work separate.<\/p>\n\n<p>But is this needed if you\u2019re the only in the team?<\/p>\n\n<p>Assumingly, you're only working on one change at a time, so what's the benefit of creating a separate branch?<\/p>\n\n<p>If you need to switch to a different task, another approach could be to revert your work-in-progress commits, move them onto another local branch temporarily, or wrap them within a feature flag so that the changes are committed but not active.<\/p>\n\n<p>The other part of the tweet said, \u201cI like the little integrations to make sure the tests pass\u201d.<\/p>\n\n<p>I\u2019m comfortable working on a single branch and committing and pushing small changes often.<\/p>\n\n<p>My CI pipelines run for every change that I push, and if one fails, I\u2019ll either push a small fix to get it passing again or revert the failing change and investigate further.<\/p>\n\n<p>For me, working on a single branch keeps my workflow simple and lean, allowing me to focus on the changes and the tasks that I need to work on and not worry about which branch I\u2019m working on.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Yesterday, I <a href=\"https:\/\/twitter.com\/scottkeckwarren\/status\/1594752744165847040\">saw a tweet<\/a> where the writer said they were \u201cfalling into the branch, pull request, and merge after actions pass I use at work even though I'm the only one working on it\u201d.<\/p>\n\n<p>After reading this, my question is, \"Should you, or do you need to, create branches if you're the only person working on a project?\".<\/p>\n\n<p>These days, I use trunk-based development as much as possible, so I hardly ever create new branches, whether working on a project myself or with a team.<\/p>\n\n<p><a href=\"https:\/\/www.oliverdavies.uk\/presentations\/git-flow\">I used to use Git Flow<\/a> and create branches for every new feature and bug fix, but I remember, whilst demonstrating two work-in-progress features to a client, switching between the different branches caused my local site to break. Whilst it wasn\u2019t a major issue, it wouldn't have seemed professional.<\/p>\n\n<p>In a team environment, feature branches are intended to keep different changes and different people's work separate.<\/p>\n\n<p>But is this needed if you\u2019re the only in the team?<\/p>\n\n<p>Assumingly, you're only working on one change at a time, so what's the benefit of creating a separate branch?<\/p>\n\n<p>If you need to switch to a different task, another approach could be to revert your work-in-progress commits, move them onto another local branch temporarily, or wrap them within a feature flag so that the changes are committed but not active.<\/p>\n\n<p>The other part of the tweet said, \u201cI like the little integrations to make sure the tests pass\u201d.<\/p>\n\n<p>I\u2019m comfortable working on a single branch and committing and pushing small changes often.<\/p>\n\n<p>My CI pipelines run for every change that I push, and if one fails, I\u2019ll either push a small fix to get it passing again or revert the failing change and investigate further.<\/p>\n\n<p>For me, working on a single branch keeps my workflow simple and lean, allowing me to focus on the changes and the tasks that I need to work on and not worry about which branch I\u2019m working on.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "de98c57a7d583eb2f17a08ed813ccc09",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.136a9cc9-db95-4805-ba8d-0d32ab3bd694.json
Normal file
100
content/node.136a9cc9-db95-4805-ba8d-0d32ab3bd694.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "136a9cc9-db95-4805-ba8d-0d32ab3bd694"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't let pride get in the way of productivity"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-12-28T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/12\/28\/pride-and-productivity",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Today, I was reading a support request on a public forum.<\/p>\n\n<p>The poster asked a question about a technical issue and explained the problem they were experiencing. I was experiencing the same thing, which is how I found it.<\/p>\n\n<p>A community member responded and suggested a solution.<\/p>\n\n<p>To this, the original poster responded:<\/p>\n\n<blockquote>\n <p>Not too proud to ask where I [make the change].<\/p>\n<\/blockquote>\n\n<p>The response to this was what caught my attention:<\/p>\n\n<blockquote>\n <p>No problem. Don't let pride get in the way of productivity.<\/p>\n<\/blockquote>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>Don't be afraid to ask questions or say you don't know or understand something.<\/p>\n\n<p>No one knows everything, and there's no such thing as a stupid question.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Today, I was reading a support request on a public forum.<\/p>\n\n<p>The poster asked a question about a technical issue and explained the problem they were experiencing. I was experiencing the same thing, which is how I found it.<\/p>\n\n<p>A community member responded and suggested a solution.<\/p>\n\n<p>To this, the original poster responded:<\/p>\n\n<blockquote>\n <p>Not too proud to ask where I [make the change].<\/p>\n<\/blockquote>\n\n<p>The response to this was what caught my attention:<\/p>\n\n<blockquote>\n <p>No problem. Don't let pride get in the way of productivity.<\/p>\n<\/blockquote>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>Don't be afraid to ask questions or say you don't know or understand something.<\/p>\n\n<p>No one knows everything, and there's no such thing as a stupid question.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "f1921114d6e52e6b1147419cd0c37c8c",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.13983815-5813-4d50-8575-3827d97e85dd.json
Normal file
100
content/node.13983815-5813-4d50-8575-3827d97e85dd.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "13983815-5813-4d50-8575-3827d97e85dd"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Over 100 ATDC subscribers"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-04-11T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/04\/11\/over-100-atdc-subscribers",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Since launching my Automated Testing in Drupal email course, over 100 people have subscribed and received the free ten daily lessons where I explain how to start from scratch to build a Drupal module with automated tests and test-driven development.<\/p>\n\n<p>Thanks to everyone who has taken the course so far and those who have provided feedback.<\/p>\n\n<p>Automated testing and test-driven development were game changers for me and enabled me to deliver better projects.<\/p>\n\n<p>If you'd like to take the course and learn how to do automated testing in Drupal, you can <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">register for free<\/a> and get them direct to your inbox.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Since launching my Automated Testing in Drupal email course, over 100 people have subscribed and received the free ten daily lessons where I explain how to start from scratch to build a Drupal module with automated tests and test-driven development.<\/p>\n\n<p>Thanks to everyone who has taken the course so far and those who have provided feedback.<\/p>\n\n<p>Automated testing and test-driven development were game changers for me and enabled me to deliver better projects.<\/p>\n\n<p>If you'd like to take the course and learn how to do automated testing in Drupal, you can <a href=\"https:\/\/www.oliverdavies.uk\/atdc\">register for free<\/a> and get them direct to your inbox.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "3943dc4ec9de105dc8129ddcc5e62eae",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.13f841cd-af2b-4b42-b28f-86bc8e261e52.json
Normal file
100
content/node.13f841cd-af2b-4b42-b28f-86bc8e261e52.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "13f841cd-af2b-4b42-b28f-86bc8e261e52"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Is PHP a good first programming language?"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-10-18T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/10\/18\/is-php-a-good-first-programming-language",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I started coding in 2007 to build a website for a Tae Kwon-Do School I used to train at.<\/p>\n\n<p>It was written with HTML and CSS and only contained a few small pages.<\/p>\n\n<p>When I wanted to add more dynamic content, such as news articles and events, I started to expand and started to use PHP and MySQL.<\/p>\n\n<p>PHP was a great first programming language for me (ignoring HTML and CSS), and it's gone through so many improvements since 2007, as well as the PHP content management systems and frameworks.<\/p>\n\n<p>I think a lot of new coders only learn or are taught JavaScript and I can understand why if they've only got a short time, such as on a bootcamp, but I also think there is a benefit to learning another language - such as PHP.<\/p>\n\n<p>PHP has Composer to manage dependencies, various robust content management systems and frameworks, PHPUnit and Pest for automated testing, PHPStan and Psalm for static analysis, and much more.<\/p>\n\n<p>I'd definitely recommend taking a look at PHP if you haven't already.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I started coding in 2007 to build a website for a Tae Kwon-Do School I used to train at.<\/p>\n\n<p>It was written with HTML and CSS and only contained a few small pages.<\/p>\n\n<p>When I wanted to add more dynamic content, such as news articles and events, I started to expand and started to use PHP and MySQL.<\/p>\n\n<p>PHP was a great first programming language for me (ignoring HTML and CSS), and it's gone through so many improvements since 2007, as well as the PHP content management systems and frameworks.<\/p>\n\n<p>I think a lot of new coders only learn or are taught JavaScript and I can understand why if they've only got a short time, such as on a bootcamp, but I also think there is a benefit to learning another language - such as PHP.<\/p>\n\n<p>PHP has Composer to manage dependencies, various robust content management systems and frameworks, PHPUnit and Pest for automated testing, PHPStan and Psalm for static analysis, and much more.<\/p>\n\n<p>I'd definitely recommend taking a look at PHP if you haven't already.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e69a1241f2245a8193f94d701b369c7c",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.14099636-145e-47c4-b501-69ab2d872515.json
Normal file
100
content/node.14099636-145e-47c4-b501-69ab2d872515.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "14099636-145e-47c4-b501-69ab2d872515"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Automated tests mean you can make changes quicker"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-01-31T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/01\/31\/automated-tests-mean-you-can-make-changes-quicker",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Before fixing <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/01\/30\/tdd-doesnt-mean-you-know-everything-upfront\">yesterday's bug<\/a>, because I'd written automated tests, I ran them to ensure they were all passing.<\/p>\n\n<p>Then, I was able to focus solely on adding the new use case - starting with a failing test to replicate the issue and then getting it to pass.<\/p>\n\n<p>Because it was already tested, I didn't need to worry about breaking any other functionality and introducing regressions.<\/p>\n\n<p>When the new test was passing, I could run the whole test suite and ensure they still passed and things continued to work.<\/p>\n\n<p>Without the tests, I'd either need to check everything else manually (which takes time) or worry that something could potentially be broken.<\/p>\n\n<p>Having tests meant I could be confident that the new and existing functionality worked.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Before fixing <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/01\/30\/tdd-doesnt-mean-you-know-everything-upfront\">yesterday's bug<\/a>, because I'd written automated tests, I ran them to ensure they were all passing.<\/p>\n\n<p>Then, I was able to focus solely on adding the new use case - starting with a failing test to replicate the issue and then getting it to pass.<\/p>\n\n<p>Because it was already tested, I didn't need to worry about breaking any other functionality and introducing regressions.<\/p>\n\n<p>When the new test was passing, I could run the whole test suite and ensure they still passed and things continued to work.<\/p>\n\n<p>Without the tests, I'd either need to check everything else manually (which takes time) or worry that something could potentially be broken.<\/p>\n\n<p>Having tests meant I could be confident that the new and existing functionality worked.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "abcc748af8e6e888fd2ed7c8b02d7911",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.14daa17c-793d-4a76-a292-09c6a7c8e9b9.json
Normal file
100
content/node.14daa17c-793d-4a76-a292-09c6a7c8e9b9.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "14daa17c-793d-4a76-a292-09c6a7c8e9b9"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Tailwind CSS at the Norfolk Developer Conference\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-03-01T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/03\/01\/tailwind-css-at-the-norfolk-developer-conference",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Last week, I was at the Norfolk Developer's Conference, aka <code>nor(DEV):con<\/code> - my first in-person conference since DrupalCamp London in February 2020.<\/p>\n\n<p>I've been excited about this conference since I received the acceptance email in November, inviting me to give my <a href=\"https:\/\/www.oliverdavies.uk\/talks\/taking-flight-with-tailwind-css\">Taking Flight with Tailwind CSS<\/a> talk.<\/p>\n\n<p>The talk itself went well and included some changes following the Bristol Software Development meetup last month. The last time I gave this talk prior to that was remotely for Nashville PHP in February 2021 and a lot of new things have been added to Tailwind CSS since then for me to include.<\/p>\n\n<p>My next talk will be at the PHP London meetup next month (subject TBC) as I continue working towards my hundredth presentation.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Last week, I was at the Norfolk Developer's Conference, aka <code>nor(DEV):con<\/code> - my first in-person conference since DrupalCamp London in February 2020.<\/p>\n\n<p>I've been excited about this conference since I received the acceptance email in November, inviting me to give my <a href=\"https:\/\/www.oliverdavies.uk\/talks\/taking-flight-with-tailwind-css\">Taking Flight with Tailwind CSS<\/a> talk.<\/p>\n\n<p>The talk itself went well and included some changes following the Bristol Software Development meetup last month. The last time I gave this talk prior to that was remotely for Nashville PHP in February 2021 and a lot of new things have been added to Tailwind CSS since then for me to include.<\/p>\n\n<p>My next talk will be at the PHP London meetup next month (subject TBC) as I continue working towards my hundredth presentation.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e15720a4ab8c5005c73431fcac145c86",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.15616f5d-f226-4516-a181-c47375e5f7f1.json
Normal file
100
content/node.15616f5d-f226-4516-a181-c47375e5f7f1.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "15616f5d-f226-4516-a181-c47375e5f7f1"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Ask questions"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-05-30T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/05\/30\/ask-questions",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As a Software Developer, it's common to hear that you need to ask questions to progress or work efficiently.<\/p>\n\n<p>You shouldn't just ask technical questions, though.<\/p>\n\n<p>Also ask questions like:<\/p>\n\n<ul>\n<li>What do we want to achieve by delivering this feature?<\/li>\n<li>How do we know if it's a success (or not)?<\/li>\n<li>What business value does this add and who will benefit?<\/li>\n<li>Why do this now? Why not wait a few months or not do it at all?<\/li>\n<li>Is there an existing solution for this?<\/li>\n<li>Can we achieve the same or a similar result in a different way?<\/li>\n<\/ul>\n\n<p>As well as knowing how to do something, it's important to know why it needs to be done.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As a Software Developer, it's common to hear that you need to ask questions to progress or work efficiently.<\/p>\n\n<p>You shouldn't just ask technical questions, though.<\/p>\n\n<p>Also ask questions like:<\/p>\n\n<ul>\n<li>What do we want to achieve by delivering this feature?<\/li>\n<li>How do we know if it's a success (or not)?<\/li>\n<li>What business value does this add and who will benefit?<\/li>\n<li>Why do this now? Why not wait a few months or not do it at all?<\/li>\n<li>Is there an existing solution for this?<\/li>\n<li>Can we achieve the same or a similar result in a different way?<\/li>\n<\/ul>\n\n<p>As well as knowing how to do something, it's important to know why it needs to be done.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "f0c3d6e951782cfb763d893c57d2dced",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.15953cf4-b54f-4241-9641-88219a0a5fa1.json
Normal file
100
content/node.15953cf4-b54f-4241-9641-88219a0a5fa1.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "15953cf4-b54f-4241-9641-88219a0a5fa1"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Where is the value in your application?"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-01-21T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/01\/21\/where-is-the-value-in-your-application",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Yesterday, I was in Birmingham for a hackathon event organised by the School of Code, who I've been a Bootcamp mentor for for the last few cohorts.<\/p>\n\n<p>At the event, I was mentoring a team of three Bootcamp graduates to plan and build a Christmas-themed application.<\/p>\n\n<p>We decided on a Christmas walking application where people can view upcoming walks, log in and book a place.<\/p>\n\n<p>After designing some initial pages, such as the Home page with a login form, a registration form, a list of walks and a walk detail page, we started to code them.<\/p>\n\n<p>Naturally, we started with the Home page, the login form and the login functionality.<\/p>\n\n<p>But, is that the most valuable part of the application?<\/p>\n\n<p>What differentiates it from other applications, such as the ones being built by other squads at the event?<\/p>\n\n<p>In this case, it's the page showing the list of walks and, if you click one, the details about that walk.<\/p>\n\n<p>The squad needed to give a presentation and demo of the application by the end of the day, so we needed to prioritise.<\/p>\n\n<p>We refocused on the walk pages and built them before moving back to the other pages to complete the user journey so it could be shown.<\/p>\n\n<p>Similarly, we didn't need a fully functional user login and registration system for the demo. We just needed to show the forms we'd built, demo the user journey and show how someone would find and register for an event.<\/p>\n\n<p>When I'm building an application, I identify the most valuable part and focus on it rather than other unrelated functionality that could likely be done manually or another way until that functionality is available.<\/p>\n\n<p>The beginning of the user journey isn't always the best first thing to start developing.<\/p>\n\n<p>It was a great day, our squad won the prize for the event, and I look forward to attending more events and continuing to work with the School of Code.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Yesterday, I was in Birmingham for a hackathon event organised by the School of Code, who I've been a Bootcamp mentor for for the last few cohorts.<\/p>\n\n<p>At the event, I was mentoring a team of three Bootcamp graduates to plan and build a Christmas-themed application.<\/p>\n\n<p>We decided on a Christmas walking application where people can view upcoming walks, log in and book a place.<\/p>\n\n<p>After designing some initial pages, such as the Home page with a login form, a registration form, a list of walks and a walk detail page, we started to code them.<\/p>\n\n<p>Naturally, we started with the Home page, the login form and the login functionality.<\/p>\n\n<p>But, is that the most valuable part of the application?<\/p>\n\n<p>What differentiates it from other applications, such as the ones being built by other squads at the event?<\/p>\n\n<p>In this case, it's the page showing the list of walks and, if you click one, the details about that walk.<\/p>\n\n<p>The squad needed to give a presentation and demo of the application by the end of the day, so we needed to prioritise.<\/p>\n\n<p>We refocused on the walk pages and built them before moving back to the other pages to complete the user journey so it could be shown.<\/p>\n\n<p>Similarly, we didn't need a fully functional user login and registration system for the demo. We just needed to show the forms we'd built, demo the user journey and show how someone would find and register for an event.<\/p>\n\n<p>When I'm building an application, I identify the most valuable part and focus on it rather than other unrelated functionality that could likely be done manually or another way until that functionality is available.<\/p>\n\n<p>The beginning of the user journey isn't always the best first thing to start developing.<\/p>\n\n<p>It was a great day, our squad won the prize for the event, and I look forward to attending more events and continuing to work with the School of Code.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "afd0a9a1478406d663af9a2abb8eedae",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.15d5688c-c30f-4bdf-abac-b38c5048684c.json
Normal file
100
content/node.15d5688c-c30f-4bdf-abac-b38c5048684c.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "15d5688c-c30f-4bdf-abac-b38c5048684c"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Twig, Symfony and SymfonyCasts with Ryan Weaver"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-02-11T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/02\/11\/ryan-weaver",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>This week's guest on Beyond Blocks is <a href=\"https:\/\/www.oliverdavies.uk\/podcast\/10-ryan-weaver-symfonycasts\">Ryan Weaver<\/a>.<\/p>\n\n<p>Ryan is a Symfony Developer, Symfony core team member and writer for SymfonyCasts.<\/p>\n\n<p>We discussed recent developments in Twig templates, SymfonyCasts, release cycles, and similarities between the Drupal and Symfony projects and communities.<\/p>\n\n<p>I've been a long-time subscriber of SymfonyCasts and it was a big help when I was learning Drupal 8 for Twig and object-orientated PHP, so it was great to speak with Ryan.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>This week's guest on Beyond Blocks is <a href=\"https:\/\/www.oliverdavies.uk\/podcast\/10-ryan-weaver-symfonycasts\">Ryan Weaver<\/a>.<\/p>\n\n<p>Ryan is a Symfony Developer, Symfony core team member and writer for SymfonyCasts.<\/p>\n\n<p>We discussed recent developments in Twig templates, SymfonyCasts, release cycles, and similarities between the Drupal and Symfony projects and communities.<\/p>\n\n<p>I've been a long-time subscriber of SymfonyCasts and it was a big help when I was learning Drupal 8 for Twig and object-orientated PHP, so it was great to speak with Ryan.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "77a251bc42faf5a39bab63cacb3bb1bb",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.15e54d03-2a34-490b-a416-a344f1a4111b.json
Normal file
100
content/node.15e54d03-2a34-490b-a416-a344f1a4111b.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "15e54d03-2a34-490b-a416-a344f1a4111b"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Is the Drupal release cycle too fast?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-05-15T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/05\/15\/is-the-drupal-release-cycle-too-fast",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Compared to Drupal 7, <a href=\"https:\/\/oliverdavies.dev\/daily\/2023\/04\/30\/will-we-see-drupal-7-100\">which is almost at version 100<\/a>, the release cycle from Drupal 9 onwards has been quite different.<\/p>\n\n<p>We've adopted semantic versioning with new feature releases every six months, and we've already sunsetted Drupal 8 and moved on to Drupal 9 and 10.<\/p>\n\n<p>Major versions are released more quickly, with Drupal 9 support ending in November 2023 and Drupal 11 potentially being released in May or November 2024.<\/p>\n\n<p>But is it too quick, as someone asked on Twitter?<\/p>\n\n<p>The main reason I'm aware of is to keep in sync with major versions of projects that Drupal uses, such as the components used by Symfony. As they update and release new major versions, we also need to do so.<\/p>\n\n<p>As a module and theme maintainer, I don't think it's too fast and have been happy with the number of changes to upgrade them and make them Drupal 10 compatible. In most cases, I only had to change the <code>core_version_requirement<\/code> key to include the new version.<\/p>\n\n<p>It depends on how well the project is maintained during the earlier versions. If you keep up to date with changes in minor versions and remove any deprecated code, there will be less to do in the future.<\/p>\n\n<p>The same applies to any custom code within website projects, not just contributed modules and themes.<\/p>\n\n<p>The more often you maintain and update what you have; the easier it will be.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Compared to Drupal 7, <a href=\"https:\/\/oliverdavies.dev\/daily\/2023\/04\/30\/will-we-see-drupal-7-100\">which is almost at version 100<\/a>, the release cycle from Drupal 9 onwards has been quite different.<\/p>\n\n<p>We've adopted semantic versioning with new feature releases every six months, and we've already sunsetted Drupal 8 and moved on to Drupal 9 and 10.<\/p>\n\n<p>Major versions are released more quickly, with Drupal 9 support ending in November 2023 and Drupal 11 potentially being released in May or November 2024.<\/p>\n\n<p>But is it too quick, as someone asked on Twitter?<\/p>\n\n<p>The main reason I'm aware of is to keep in sync with major versions of projects that Drupal uses, such as the components used by Symfony. As they update and release new major versions, we also need to do so.<\/p>\n\n<p>As a module and theme maintainer, I don't think it's too fast and have been happy with the number of changes to upgrade them and make them Drupal 10 compatible. In most cases, I only had to change the <code>core_version_requirement<\/code> key to include the new version.<\/p>\n\n<p>It depends on how well the project is maintained during the earlier versions. If you keep up to date with changes in minor versions and remove any deprecated code, there will be less to do in the future.<\/p>\n\n<p>The same applies to any custom code within website projects, not just contributed modules and themes.<\/p>\n\n<p>The more often you maintain and update what you have; the easier it will be.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e338b7c88d5cb20842d58191906582b0",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.15ee547f-b4c3-4735-ae9f-d98e520720a5.json
Normal file
100
content/node.15ee547f-b4c3-4735-ae9f-d98e520720a5.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "15ee547f-b4c3-4735-ae9f-d98e520720a5"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Speaking at the Drupal London meetup"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-11-13T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/11\/13\/speaking-at-the-drupal-london-meetup",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Next Wednesday evening, I'm going to be speaking remotely at the Drupal London meetup.<\/p>\n\n<p>I was originally going to attend in person, but after injuring my foot last week, I can't travel so will have to join remotely.<\/p>\n\n<p>I'm going to be giving a talk and demo of <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/tdd-test-driven-drupal\">automated testing and test-driven development with Drupal<\/a> as well as some Q&A and pair programming, if time allows and we're able to do so remotely.<\/p>\n\n<p>RSVPs are still open for the event and hopefully I'll get to attend Drupal London in person in the future.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Next Wednesday evening, I'm going to be speaking remotely at the Drupal London meetup.<\/p>\n\n<p>I was originally going to attend in person, but after injuring my foot last week, I can't travel so will have to join remotely.<\/p>\n\n<p>I'm going to be giving a talk and demo of <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/tdd-test-driven-drupal\">automated testing and test-driven development with Drupal<\/a> as well as some Q&A and pair programming, if time allows and we're able to do so remotely.<\/p>\n\n<p>RSVPs are still open for the event and hopefully I'll get to attend Drupal London in person in the future.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "9400b956833d34cef7783e6b4ae755bd",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.15fffc33-0029-4635-9fd6-75e422cc2a0a.json
Normal file
100
content/node.15fffc33-0029-4635-9fd6-75e422cc2a0a.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "15fffc33-0029-4635-9fd6-75e422cc2a0a"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "tldr\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-11-22T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/11\/22\/tldr",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p><code>tldr<\/code> is a command-line tool that I've been using a lot recently.<\/p>\n\n<p>Usually, on the command line, you'd use the <code>man<\/code> command to show a manual page for a certain command - like <code>man ls<\/code>.<\/p>\n\n<p><code>tldr<\/code> is \"a collection of simplified and community-driven man pages\".<\/p>\n\n<p>After installing it, run <code>man tldr<\/code> or even <code>tldr tldr<\/code> to learn more about it.<\/p>\n\n<p>Then, run a command like <code>tldr ls<\/code> to get output for a specific command.<\/p>\n\n<p>I like that it shows a short description of what the command does, followed by a link to find out more information and then several valuable examples demonstrating the various options, flags, and arguments the command takes.<\/p>\n\n<p>For <code>ls<\/code>, it shows how to list one file per line, list hidden files, use a long format list, show human-readable size units, long format sorted by size or modification date, and only show directories.<\/p>\n\n<p>For commands like <code>tar<\/code>, <code>rsync<\/code>, and <code>scp<\/code> that I don't use that often or can't remember all of the different options, I like being able to see these examples and figure out what I need at that time.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p><code>tldr<\/code> is a command-line tool that I've been using a lot recently.<\/p>\n\n<p>Usually, on the command line, you'd use the <code>man<\/code> command to show a manual page for a certain command - like <code>man ls<\/code>.<\/p>\n\n<p><code>tldr<\/code> is \"a collection of simplified and community-driven man pages\".<\/p>\n\n<p>After installing it, run <code>man tldr<\/code> or even <code>tldr tldr<\/code> to learn more about it.<\/p>\n\n<p>Then, run a command like <code>tldr ls<\/code> to get output for a specific command.<\/p>\n\n<p>I like that it shows a short description of what the command does, followed by a link to find out more information and then several valuable examples demonstrating the various options, flags, and arguments the command takes.<\/p>\n\n<p>For <code>ls<\/code>, it shows how to list one file per line, list hidden files, use a long format list, show human-readable size units, long format sorted by size or modification date, and only show directories.<\/p>\n\n<p>For commands like <code>tar<\/code>, <code>rsync<\/code>, and <code>scp<\/code> that I don't use that often or can't remember all of the different options, I like being able to see these examples and figure out what I need at that time.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "f8b9fce72ec35d462c229ed98873a255",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.160ff4ff-1e39-4a33-bfd9-e86a6abaa191.json
Normal file
100
content/node.160ff4ff-1e39-4a33-bfd9-e86a6abaa191.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "160ff4ff-1e39-4a33-bfd9-e86a6abaa191"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Learning by reading"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-01-16T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/01\/16\/learning",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>When I'm working as part of a Development team, working on open source projects, watching live streams or reading code that people have released online - such as their website or dotfiles - I read a lot of other people's code.<\/p>\n\n<p>It's an opportunity to learn from others and how they approach things.<\/p>\n\n<p>How they achieved a desired result or fixed a bug, which I can learn from.<\/p>\n\n<p>I can refer to it if I need to do something similar in the future.<\/p>\n\n<p>Or I may find something random that's I didn't know I needed, such as a module, library or configuration setting I wasn't aware of.<\/p>\n\n<p>I recently learned about .mailmap files from Greg Hurrell (wincent)'s dotfiles on GitHub.<\/p>\n\n<p>.mailmap is a file that is used by Git when displaying history, such as running <code>git log<\/code>, and allows you to define canonical names and email addresses for committers and contributors.<\/p>\n\n<p>I've accidentally used the wrong email address or typed my name incorrectly before in my Git configuration, which was there for all to see, but this file allows me to consolidate my identities within a repository so my commits are grouped together and attributed to me, regardless of which email address I used or how I wrote my name.<\/p>\n\n<p>You can see <a href=\"https:\/\/code.oliverdavies.uk\/opdavies\/oliverdavies.uk\/src\/commit\/633e11abedfa4cc8d85d37695c1ca014874fd4c1\/.mailmap\">the one I added to my website directory<\/a>.<\/p>\n\n<p>If I hadn't looked at that repository, I wouldn't have learned about it.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>When I'm working as part of a Development team, working on open source projects, watching live streams or reading code that people have released online - such as their website or dotfiles - I read a lot of other people's code.<\/p>\n\n<p>It's an opportunity to learn from others and how they approach things.<\/p>\n\n<p>How they achieved a desired result or fixed a bug, which I can learn from.<\/p>\n\n<p>I can refer to it if I need to do something similar in the future.<\/p>\n\n<p>Or I may find something random that's I didn't know I needed, such as a module, library or configuration setting I wasn't aware of.<\/p>\n\n<p>I recently learned about .mailmap files from Greg Hurrell (wincent)'s dotfiles on GitHub.<\/p>\n\n<p>.mailmap is a file that is used by Git when displaying history, such as running <code>git log<\/code>, and allows you to define canonical names and email addresses for committers and contributors.<\/p>\n\n<p>I've accidentally used the wrong email address or typed my name incorrectly before in my Git configuration, which was there for all to see, but this file allows me to consolidate my identities within a repository so my commits are grouped together and attributed to me, regardless of which email address I used or how I wrote my name.<\/p>\n\n<p>You can see <a href=\"https:\/\/code.oliverdavies.uk\/opdavies\/oliverdavies.uk\/src\/commit\/633e11abedfa4cc8d85d37695c1ca014874fd4c1\/.mailmap\">the one I added to my website directory<\/a>.<\/p>\n\n<p>If I hadn't looked at that repository, I wouldn't have learned about it.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "87636a91b190a3f76a189dfb1cfa6e92",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.16a4a7d9-df97-4d28-92eb-ccc65d7534ba.json
Normal file
100
content/node.16a4a7d9-df97-4d28-92eb-ccc65d7534ba.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "16a4a7d9-df97-4d28-92eb-ccc65d7534ba"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "When did you last deploy to production?"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-09-12T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/09\/12\/when-did-you-last-deploy-to-production",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>If you've experienced issues or are worried about deploying changes to production, <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/09\/11\/do-you-deploy-on-fridays\">on a Friday or another day<\/a>, when did you last deploy something?<\/p>\n\n<p>Can you make deployments smaller and more frequent?<\/p>\n\n<p>Deploying regularly makes each deployment less risky and having a smaller changeset makes it easier to find and fix any issues that arise.<\/p>\n\n<p>I'm much happier deploying to production if I've already done so that day, or at least that week.<\/p>\n\n<p>Any time more than that, or if the changeset is large, the more likely there will be issues and the longer it will take to resolve them.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>If you've experienced issues or are worried about deploying changes to production, <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/09\/11\/do-you-deploy-on-fridays\">on a Friday or another day<\/a>, when did you last deploy something?<\/p>\n\n<p>Can you make deployments smaller and more frequent?<\/p>\n\n<p>Deploying regularly makes each deployment less risky and having a smaller changeset makes it easier to find and fix any issues that arise.<\/p>\n\n<p>I'm much happier deploying to production if I've already done so that day, or at least that week.<\/p>\n\n<p>Any time more than that, or if the changeset is large, the more likely there will be issues and the longer it will take to resolve them.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e4e7b3f159846b99658730ca08899088",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.16cfae0b-fe10-419e-bffd-4c81a9373a5e.json
Normal file
100
content/node.16cfae0b-fe10-419e-bffd-4c81a9373a5e.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "16cfae0b-fe10-419e-bffd-4c81a9373a5e"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Doing the simplest possible thing\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-11-24T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/11\/24\/doing-the-simplest-possible-thing",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I spent most of today working on some code I wrote for the first phase of a client project a few months ago.<\/p>\n\n<p>The previous version used hard-coded data within a Vue.js application, which was sufficient for the previous criteria and in line with the lean approach we decided to take.<\/p>\n\n<p>It was the simplest thing that worked.<\/p>\n\n<p>A new requirement means that the hard-coded data no longer works, so I need to refactor and enhance the code to work with different configurations. I have a proof of concept of this working using JSON from an API endpoint, but I would also like to use a static JSON file when needed for local development.<\/p>\n\n<p>I experimented with a few different ways to approach this before asking myself, \"What's the simplest possible thing I can do to get this working?\".<\/p>\n\n<p>I already knew that I needed to make a change to the structure of the data, which I was able to do quickly with the hard-coded data that I already had, and whilst a static JSON file would be a nice-to-have, I could quickly move the hard-coded data into the API endpoint that I'd already created and continue building on my proof of concept.<\/p>\n\n<p>The idea of \"What's the simplest thing?\" is something that I use regularly.<\/p>\n\n<p>When teaching or coaching test-driven development, I want to write the smallest failing test and then find the quickest and simplest way to get it to pass - even if it means returning a hard-coded value for now.<\/p>\n\n<p>When working on development tasks, I like to break things down as much as possible and find the smallest thing I can do, commit, and push. This gets the ball rolling, and then I repeat the process.<\/p>\n\n<p>Even when writing an email or blog post, once I start writing, it's much easier to continue once I'm in the flow.<\/p>\n\n<p>Taking the simplest approach and not making assumptions about future requirements or scope means less and more maintainable code, as well as being a productivity hack.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I spent most of today working on some code I wrote for the first phase of a client project a few months ago.<\/p>\n\n<p>The previous version used hard-coded data within a Vue.js application, which was sufficient for the previous criteria and in line with the lean approach we decided to take.<\/p>\n\n<p>It was the simplest thing that worked.<\/p>\n\n<p>A new requirement means that the hard-coded data no longer works, so I need to refactor and enhance the code to work with different configurations. I have a proof of concept of this working using JSON from an API endpoint, but I would also like to use a static JSON file when needed for local development.<\/p>\n\n<p>I experimented with a few different ways to approach this before asking myself, \"What's the simplest possible thing I can do to get this working?\".<\/p>\n\n<p>I already knew that I needed to make a change to the structure of the data, which I was able to do quickly with the hard-coded data that I already had, and whilst a static JSON file would be a nice-to-have, I could quickly move the hard-coded data into the API endpoint that I'd already created and continue building on my proof of concept.<\/p>\n\n<p>The idea of \"What's the simplest thing?\" is something that I use regularly.<\/p>\n\n<p>When teaching or coaching test-driven development, I want to write the smallest failing test and then find the quickest and simplest way to get it to pass - even if it means returning a hard-coded value for now.<\/p>\n\n<p>When working on development tasks, I like to break things down as much as possible and find the smallest thing I can do, commit, and push. This gets the ball rolling, and then I repeat the process.<\/p>\n\n<p>Even when writing an email or blog post, once I start writing, it's much easier to continue once I'm in the flow.<\/p>\n\n<p>Taking the simplest approach and not making assumptions about future requirements or scope means less and more maintainable code, as well as being a productivity hack.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "70b03f1c2962ba75e6f89142c23c6791",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.16dfe92b-2326-4d95-9797-d1940700f9a3.json
Normal file
100
content/node.16dfe92b-2326-4d95-9797-d1940700f9a3.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "16dfe92b-2326-4d95-9797-d1940700f9a3"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Writing more tests than production code"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-02-08T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/02\/08\/more-tests",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As well as <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2025\/02\/07\/less\">having less code than you started with<\/a>, another good type of change is one where there are tests accompanying the production code.<\/p>\n\n<p>Whether the tests were written after the code or before with a test-driven development approach, the main thing is that there are tests when the code is committed.<\/p>\n\n<p>There should also be more test code than production code.<\/p>\n\n<p>There is only one implementation of the production code, but there should be multiple tests for it.<\/p>\n\n<p>There should be different tests for different situations, such as different types of input and no input, testing for throwing Exceptions and other failure cases and not just the \"happy path\".<\/p>\n\n<p>Looking at the diff of a commit or merge request, there should be more changes to the test then the code it's testing.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As well as <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2025\/02\/07\/less\">having less code than you started with<\/a>, another good type of change is one where there are tests accompanying the production code.<\/p>\n\n<p>Whether the tests were written after the code or before with a test-driven development approach, the main thing is that there are tests when the code is committed.<\/p>\n\n<p>There should also be more test code than production code.<\/p>\n\n<p>There is only one implementation of the production code, but there should be multiple tests for it.<\/p>\n\n<p>There should be different tests for different situations, such as different types of input and no input, testing for throwing Exceptions and other failure cases and not just the \"happy path\".<\/p>\n\n<p>Looking at the diff of a commit or merge request, there should be more changes to the test then the code it's testing.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "3da78a8b0a4a8e0177c79d863316c825",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.17286a5f-5033-4f4a-8a5f-c0d7b035e7ef.json
Normal file
100
content/node.17286a5f-5033-4f4a-8a5f-c0d7b035e7ef.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "17286a5f-5033-4f4a-8a5f-c0d7b035e7ef"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Retrofit with Matt Glaman\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-11-10T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/11\/10\/retrofit-with-matt-glaman",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Today, I released <a href=\"https:\/\/www.oliverdavies.uk\/podcast\/1-retrofit\">the first episode of the \"Beyond Blocks\" podcast<\/a>.<\/p>\n\n<p>I spoke with Matt Glaman - Principal Software Engineer at Acquia and author of Retrofit.<\/p>\n\n<p>Retrofit makes it easier to upgrade from Drupal 7 by adding compatibility layers to run your legacy code within Drupal 10 - giving you more time to port it to the modern approaches and standards.<\/p>\n\n<p>I've been aware of Matt and his work for some time, including his work on Drupal Commerce, so it was great to speak with him and for him to be the first guest on the podcast.<\/p>\n\n<p>Future episodes will be <a href=\"https:\/\/www.oliverdavies.uk\/podcast\">published online<\/a> weekly, so feel free to subscribe and let me know if you have feedback, suggestions for future guests and topics, or want to be a guest.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Today, I released <a href=\"https:\/\/www.oliverdavies.uk\/podcast\/1-retrofit\">the first episode of the \"Beyond Blocks\" podcast<\/a>.<\/p>\n\n<p>I spoke with Matt Glaman - Principal Software Engineer at Acquia and author of Retrofit.<\/p>\n\n<p>Retrofit makes it easier to upgrade from Drupal 7 by adding compatibility layers to run your legacy code within Drupal 10 - giving you more time to port it to the modern approaches and standards.<\/p>\n\n<p>I've been aware of Matt and his work for some time, including his work on Drupal Commerce, so it was great to speak with him and for him to be the first guest on the podcast.<\/p>\n\n<p>Future episodes will be <a href=\"https:\/\/www.oliverdavies.uk\/podcast\">published online<\/a> weekly, so feel free to subscribe and let me know if you have feedback, suggestions for future guests and topics, or want to be a guest.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "cfe4233208f6139cd05fc4319defd268",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.173d1cff-2f9a-42f5-9258-c6b70e10175b.json
Normal file
100
content/node.173d1cff-2f9a-42f5-9258-c6b70e10175b.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "173d1cff-2f9a-42f5-9258-c6b70e10175b"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Reproducible or repeatable"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-01-20T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/01\/20\/reproducible",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p><a href=\"https:\/\/www.oliverdavies.uk\/daily\/2025\/01\/19\/minimum-viable-development-environment\">In yesterday's email<\/a>, I showed how I've been using Nix and flake files to build reproducible and shareable development environments for Drupal applications.<\/p>\n\n<p>The reason it's reproducible is the <code>flake.lock<\/code> file.<\/p>\n\n<p>Similar to <code>composer.lock<\/code> or <code>package-lock.json<\/code>, it captures the exact versions of the packages installed from the nixpkgs repository.<\/p>\n\n<p>This file, along with <code>flake.nix<\/code>, can be committed alongside the application code and anyone with Nix installed can run <code>nix develop<\/code> to get a shell with the same packages and dependencies.<\/p>\n\n<p>This isn't the same as other solutions, where you add something like <code>FROM php:8.2<\/code> but, because there's no lockfile, there's no guarantee the same package versions will be installed so there could be mismatches that cause errors.<\/p>\n\n<p>With <code>flake.lock<\/code>, the environment isn't just repeatable - it's completely reproducible.<\/p>\n\n<p>Locally, in a CI pipeline or in production.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p><a href=\"https:\/\/www.oliverdavies.uk\/daily\/2025\/01\/19\/minimum-viable-development-environment\">In yesterday's email<\/a>, I showed how I've been using Nix and flake files to build reproducible and shareable development environments for Drupal applications.<\/p>\n\n<p>The reason it's reproducible is the <code>flake.lock<\/code> file.<\/p>\n\n<p>Similar to <code>composer.lock<\/code> or <code>package-lock.json<\/code>, it captures the exact versions of the packages installed from the nixpkgs repository.<\/p>\n\n<p>This file, along with <code>flake.nix<\/code>, can be committed alongside the application code and anyone with Nix installed can run <code>nix develop<\/code> to get a shell with the same packages and dependencies.<\/p>\n\n<p>This isn't the same as other solutions, where you add something like <code>FROM php:8.2<\/code> but, because there's no lockfile, there's no guarantee the same package versions will be installed so there could be mismatches that cause errors.<\/p>\n\n<p>With <code>flake.lock<\/code>, the environment isn't just repeatable - it's completely reproducible.<\/p>\n\n<p>Locally, in a CI pipeline or in production.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "53ca25f2417162597931bed0d3c8cb57",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.179d4a7f-6b68-41f9-a267-22e002aecbe3.json
Normal file
100
content/node.179d4a7f-6b68-41f9-a267-22e002aecbe3.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "179d4a7f-6b68-41f9-a267-22e002aecbe3"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't use AI to write your automated tests"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-06-01T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/06\/01\/dont-use-ai-to-write-your-automated-tests",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>In <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/05\/31\/putting-glue-on-pizza\">yesterday's email<\/a>, I mentioned some of the recent issues I've seen from AI tools.<\/p>\n\n<p>I'm wary of any code generated by AI, as I've often found it to be incorrect.<\/p>\n\n<p>If you rely on AI-generated code, I'd be especially wary if it also generates the automated tests.<\/p>\n\n<p>Automated tests verify your application works as expected, so you need to ensure they are testing the correct things and the logic is correct.<\/p>\n\n<p>Can you make a test purposely fail by changing some logic within the test or implementation code?<\/p>\n\n<p>Is it clear what each test is doing?<\/p>\n\n<p>Are the tests running the implementation code or just testing mocks or running meaningless assertions like <code>self::assertTrue(TRUE)<\/code>?<\/p>\n\n<p>Writing tests is about building confidence, which you can't do if you don't know what your tests are testing or how.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>In <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/05\/31\/putting-glue-on-pizza\">yesterday's email<\/a>, I mentioned some of the recent issues I've seen from AI tools.<\/p>\n\n<p>I'm wary of any code generated by AI, as I've often found it to be incorrect.<\/p>\n\n<p>If you rely on AI-generated code, I'd be especially wary if it also generates the automated tests.<\/p>\n\n<p>Automated tests verify your application works as expected, so you need to ensure they are testing the correct things and the logic is correct.<\/p>\n\n<p>Can you make a test purposely fail by changing some logic within the test or implementation code?<\/p>\n\n<p>Is it clear what each test is doing?<\/p>\n\n<p>Are the tests running the implementation code or just testing mocks or running meaningless assertions like <code>self::assertTrue(TRUE)<\/code>?<\/p>\n\n<p>Writing tests is about building confidence, which you can't do if you don't know what your tests are testing or how.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "9270caa76092aa60451a52a5d428601a",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.17c6747b-aece-4b96-989d-e062f08cd9c5.json
Normal file
100
content/node.17c6747b-aece-4b96-989d-e062f08cd9c5.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "17c6747b-aece-4b96-989d-e062f08cd9c5"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Documentation and comments get stale. Tests don't.\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-09-22T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/09\/22\/documentation-and-comments-get-stale",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I'm sure you've seen code comments that say the code will do something when, in fact, it does something different.<\/p>\n\n<p>Or documentation that has become outdated and stale and no longer correct.<\/p>\n\n<p>Automated tests and other tools, such as static analysis, are executable documentation, so they can't become stale.<\/p>\n\n<p>If the implementation code changes and no longer matches the tests, the tests will fail, and either the implementation or test can be updated.<\/p>\n\n<p>Then, if you need to refer to the test, as long as it's passing, you know what it shows is still applicable.<\/p>\n\n<p>The same can't be said for markdown files, Confluence pages, Word documents or other static documentation.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I'm sure you've seen code comments that say the code will do something when, in fact, it does something different.<\/p>\n\n<p>Or documentation that has become outdated and stale and no longer correct.<\/p>\n\n<p>Automated tests and other tools, such as static analysis, are executable documentation, so they can't become stale.<\/p>\n\n<p>If the implementation code changes and no longer matches the tests, the tests will fail, and either the implementation or test can be updated.<\/p>\n\n<p>Then, if you need to refer to the test, as long as it's passing, you know what it shows is still applicable.<\/p>\n\n<p>The same can't be said for markdown files, Confluence pages, Word documents or other static documentation.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "1a79c3d8c5b39c15a45407dd2f8915dd",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1849835c-c8df-466b-83cd-53690a44c929.json
Normal file
100
content/node.1849835c-c8df-466b-83cd-53690a44c929.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1849835c-c8df-466b-83cd-53690a44c929"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Are sprints incompatible with Continuous Deployment?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-11-08T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/11\/08\/are-sprints-incompatible-with-continuous-deployment",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>It's been common for me whilst working on software projects to have work organised into sprints or cycles - a period, usually between 1 and 3 weeks, where the team is working on stories and tasks for that project.<\/p>\n\n<p>In my experience, those changes are usually released at the end of that cycle. But it seems that's not always the case; see <a href=\"https:\/\/scrumdictionary.com\/term\/release-sprint\">release sprints<\/a>:<\/p>\n\n<blockquote>\n <p>A specialised sprint whose purpose is to release deliverable results; it contains stories specific to release activities and finishing undone work. A release sprint usually contains no additional development.<\/p>\n<\/blockquote>\n\n<p>If we worked in two-week cycles and released at the end of each one, it would be at least two weeks before a change could be deployed to production. But what if we wanted to follow continuous deployment and release more frequently? Maybe daily or hourly?<\/p>\n\n<p>Instead of waiting for a release sprint, if we released multiple times within a single sprint, how would this fit into or affect the process?<\/p>\n\n<p>Does the release cycle need to be tightly coupled to the sprint cycle or can they be separate and independent of each other?<\/p>\n\n<p>I've worked on projects - including a current one - where I've done multiple releases in a sprint, so of course, it can be done from a technical perspective, but how do we get the best from both processes - whether they work together or separately?<\/p>\n\n<p>This is something that I'm going to continue to experiment with, iterate on, and learn more about going forward.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>It's been common for me whilst working on software projects to have work organised into sprints or cycles - a period, usually between 1 and 3 weeks, where the team is working on stories and tasks for that project.<\/p>\n\n<p>In my experience, those changes are usually released at the end of that cycle. But it seems that's not always the case; see <a href=\"https:\/\/scrumdictionary.com\/term\/release-sprint\">release sprints<\/a>:<\/p>\n\n<blockquote>\n <p>A specialised sprint whose purpose is to release deliverable results; it contains stories specific to release activities and finishing undone work. A release sprint usually contains no additional development.<\/p>\n<\/blockquote>\n\n<p>If we worked in two-week cycles and released at the end of each one, it would be at least two weeks before a change could be deployed to production. But what if we wanted to follow continuous deployment and release more frequently? Maybe daily or hourly?<\/p>\n\n<p>Instead of waiting for a release sprint, if we released multiple times within a single sprint, how would this fit into or affect the process?<\/p>\n\n<p>Does the release cycle need to be tightly coupled to the sprint cycle or can they be separate and independent of each other?<\/p>\n\n<p>I've worked on projects - including a current one - where I've done multiple releases in a sprint, so of course, it can be done from a technical perspective, but how do we get the best from both processes - whether they work together or separately?<\/p>\n\n<p>This is something that I'm going to continue to experiment with, iterate on, and learn more about going forward.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "efd0ec8ddb3fb7929febf9e8017a8f84",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.184c1241-b0cc-4025-bfd1-caca95d831c0.json
Normal file
100
content/node.184c1241-b0cc-4025-bfd1-caca95d831c0.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "184c1241-b0cc-4025-bfd1-caca95d831c0"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Do you need that module?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-10-11T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/10\/11\/do-you-need-that-module",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Drupal includes a lot of default functionality and additional core modules you can enable to extend it.<\/p>\n\n<p>There are also over 50,000 community-contributed modules you can download and add.<\/p>\n\n<p>But is it worth adding every module?<\/p>\n\n<p>If you're browsing the list of modules on Drupal.org and find one of interest, is the functionality it adds more valuable than the cost of maintaining it?<\/p>\n\n<p>Each module increases the number of updates you'll need to do to maintain the website.<\/p>\n\n<p>What if it becomes unmaintained in the future and prevents you from updating your website to the next version of Drupal or has a security issue and introduces a vulnerability?<\/p>\n\n<p>Some modules will be crucial to your website, others you can do without if you prefer a smaller maintenance overhead.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Drupal includes a lot of default functionality and additional core modules you can enable to extend it.<\/p>\n\n<p>There are also over 50,000 community-contributed modules you can download and add.<\/p>\n\n<p>But is it worth adding every module?<\/p>\n\n<p>If you're browsing the list of modules on Drupal.org and find one of interest, is the functionality it adds more valuable than the cost of maintaining it?<\/p>\n\n<p>Each module increases the number of updates you'll need to do to maintain the website.<\/p>\n\n<p>What if it becomes unmaintained in the future and prevents you from updating your website to the next version of Drupal or has a security issue and introduces a vulnerability?<\/p>\n\n<p>Some modules will be crucial to your website, others you can do without if you prefer a smaller maintenance overhead.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "39ad9b31772a4824f9e1b5335fbb0b48",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.190a00cd-098b-4619-9f47-ff2ba4b2a095.json
Normal file
100
content/node.190a00cd-098b-4619-9f47-ff2ba4b2a095.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "190a00cd-098b-4619-9f47-ff2ba4b2a095"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Drupal 7.100.2"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-05-07T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/05\/07\/drupal-7-100-2",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>In <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2023\/04\/30\/will-we-see-drupal-7-100\">April 2023<\/a>, I wondered if we'd see a 7.100 release of Drupal.<\/p>\n\n<p>I just noticed that we did.<\/p>\n\n<p>It was released on the 6th of March.<\/p>\n\n<p>From the release notes:<\/p>\n\n<blockquote>\n <p>Maintenance release of the Drupal 7 series. Includes bug fixes and small API\/feature improvements only (no major, non-backwards-compatible new functionality). Unusually, this release does include a new core module.<\/p>\n<\/blockquote>\n\n<p>This is also the first Drupal release to be affected by the Year 2000 problem, a.k.a. the Y2K problem, or the Millennium Bug:<\/p>\n\n<blockquote>\n <p>Note that this is the first Drupal 7 release with 3 digits. If you receive a report that your version of Drupal is over a decade out of date, see https:\/\/en.wikipedia.org\/wiki\/Year_2000_problem.<\/p>\n<\/blockquote>\n\n<p>According to the usage figures on Drupal.org, there are at least 316,843 active Drupal 7 websites and, with only 243 days left until D7 is end-of-life, hopefully most of them will be upgrading to Drupal 10 (or 11) soon.<\/p>\n\n<p>If you're stuck on Drupal 7, I can help! Reply to this email and let's start a conversation.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>In <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2023\/04\/30\/will-we-see-drupal-7-100\">April 2023<\/a>, I wondered if we'd see a 7.100 release of Drupal.<\/p>\n\n<p>I just noticed that we did.<\/p>\n\n<p>It was released on the 6th of March.<\/p>\n\n<p>From the release notes:<\/p>\n\n<blockquote>\n <p>Maintenance release of the Drupal 7 series. Includes bug fixes and small API\/feature improvements only (no major, non-backwards-compatible new functionality). Unusually, this release does include a new core module.<\/p>\n<\/blockquote>\n\n<p>This is also the first Drupal release to be affected by the Year 2000 problem, a.k.a. the Y2K problem, or the Millennium Bug:<\/p>\n\n<blockquote>\n <p>Note that this is the first Drupal 7 release with 3 digits. If you receive a report that your version of Drupal is over a decade out of date, see https:\/\/en.wikipedia.org\/wiki\/Year_2000_problem.<\/p>\n<\/blockquote>\n\n<p>According to the usage figures on Drupal.org, there are at least 316,843 active Drupal 7 websites and, with only 243 days left until D7 is end-of-life, hopefully most of them will be upgrading to Drupal 10 (or 11) soon.<\/p>\n\n<p>If you're stuck on Drupal 7, I can help! Reply to this email and let's start a conversation.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "5805ba311b8e79cc68de1b251dd3b2ff",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.19324b87-435b-444a-bc14-812865872515.json
Normal file
100
content/node.19324b87-435b-444a-bc14-812865872515.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "19324b87-435b-444a-bc14-812865872515"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "How I've configured Git"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-08-24T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/08\/24\/2022-08-24",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>After yesterday's post on why I prefer using Git on the command line rather than using a GUI tool, today I thought that I'd post about how I've configured Git.<\/p>\n\n<p>First, I rarely ever run the <code>git<\/code> command - I usually run a <code>g<\/code> function that I've created within my zsh configuration.<\/p>\n\n<p>Rather than being an simple alias, it's a shell function that will run <code>git status -sb<\/code> to show the current status of the repository if there are no additional arguments. If there are, such as when running <code>g add<\/code>, then this is executed as a normal Git command. (This is something that I first saw from Thoughtbot, if I remember correctly).<\/p>\n\n<h2 id=\"using-.gitconfig\">Using .gitconfig<\/h2>\n\n<p>The main part of my configuration is within Git's <code>~\/.gitconfig<\/code> file, where I can configure Git to work how I want.<\/p>\n\n<p>For example, I like to avoid merge conflicts, so I always want to use fast-forward merges whilst pulling and also to rebase by default. I can do this by adding <code>ff = only<\/code> and <code>rebase = true<\/code> to the <code>[pull]<\/code> section of my <code>~\/.gitconfig<\/code> file.<\/p>\n\n<p>I can do this manually, or running <code>git config --global pull.rebase true<\/code> will set the option but also update the file automatically.<\/p>\n\n<p>Some of the tweaks that I've made are to only allow fast-forward merges by adding <code>merge.ff = only<\/code>, automatically squash commits when rebasing by setting <code>rebase.autosquash = true<\/code>, and automatically pruning branches by adding <code>fetch.prune = true<\/code>.<\/p>\n\n<h3 id=\"simple-aliases\">Simple aliases<\/h3>\n\n<p>Another way that I configure Git is using aliases, which are also within the <code>~\/.gitconfig<\/code> file.<\/p>\n\n<p>For example, if I ran <code>git config --global alias.b \"branch\"<\/code>, then running <code>git b<\/code> would just run <code>git branch<\/code> which shortens the command and saves some time and keystrokes.<\/p>\n\n<p>I have similar one- or two letter \"short\" aliases for pushing and pulling code, and some that also set some additional arguments such as <code>aa<\/code> for <code>add --all<\/code> and <code>worktrees<\/code> for <code>worktree list<\/code>.<\/p>\n\n<h3 id=\"more-complicated-aliases\">More complicated aliases<\/h3>\n\n<p>Aliases can be more complex if needed by prefixing it with a <code>!<\/code>, meaning that it executes it as a shell command.<\/p>\n\n<p>This means that I can have <code>repush = !git pull --rebase && git push<\/code> to chain two separate Git commands and combine them into one, and <code>ureset = !git reset --hard $(git upstream)<\/code> which executes the full command, including another alias as part of it.<\/p>\n\n<p>I also have <code>issues = !gh issue list --web<\/code> and <code>pulls = !gh pr list --web<\/code> to open the current repository's GitHub issues or pull requests respectively, which can be done as it's not limited to just running <code>git<\/code> commands.<\/p>\n\n<h3 id=\"custom-functions\">Custom functions<\/h3>\n\n<p>Finally, if an alias is getting too long or complex, then it can extracted to it's own file.<\/p>\n\n<p>Any executable file within your <code>$PATH<\/code> that starts with <code>git-<\/code> will automatically become a Git command.<\/p>\n\n<p>One example that I have is <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/blob\/2b20cd1e59ae3b1fa81074077e855cbdfa02f146\/bin\/bin\/git-cm\">git-cm<\/a> which, similar to the <code>g<\/code> function`, is a bash script that checks for any arguments passed to it and runs a slightly different command. It achieves the same thing as if it were an alias, but it does make it easier to write and maintain as it's in a separate file.<\/p>\n\n<p>These are just some examples. If you want to see my entire configuration, then check out <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/tree\/2b20cd1e59ae3b1fa81074077e855cbdfa02f146\/roles\/git\/files\">my dotfiles repository on GitHub<\/a>.<\/p>\n\n<p>How have you configured Git for your workflow? Reply to this email and let me know.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>After yesterday's post on why I prefer using Git on the command line rather than using a GUI tool, today I thought that I'd post about how I've configured Git.<\/p>\n\n<p>First, I rarely ever run the <code>git<\/code> command - I usually run a <code>g<\/code> function that I've created within my zsh configuration.<\/p>\n\n<p>Rather than being an simple alias, it's a shell function that will run <code>git status -sb<\/code> to show the current status of the repository if there are no additional arguments. If there are, such as when running <code>g add<\/code>, then this is executed as a normal Git command. (This is something that I first saw from Thoughtbot, if I remember correctly).<\/p>\n\n<h2 id=\"using-.gitconfig\">Using .gitconfig<\/h2>\n\n<p>The main part of my configuration is within Git's <code>~\/.gitconfig<\/code> file, where I can configure Git to work how I want.<\/p>\n\n<p>For example, I like to avoid merge conflicts, so I always want to use fast-forward merges whilst pulling and also to rebase by default. I can do this by adding <code>ff = only<\/code> and <code>rebase = true<\/code> to the <code>[pull]<\/code> section of my <code>~\/.gitconfig<\/code> file.<\/p>\n\n<p>I can do this manually, or running <code>git config --global pull.rebase true<\/code> will set the option but also update the file automatically.<\/p>\n\n<p>Some of the tweaks that I've made are to only allow fast-forward merges by adding <code>merge.ff = only<\/code>, automatically squash commits when rebasing by setting <code>rebase.autosquash = true<\/code>, and automatically pruning branches by adding <code>fetch.prune = true<\/code>.<\/p>\n\n<h3 id=\"simple-aliases\">Simple aliases<\/h3>\n\n<p>Another way that I configure Git is using aliases, which are also within the <code>~\/.gitconfig<\/code> file.<\/p>\n\n<p>For example, if I ran <code>git config --global alias.b \"branch\"<\/code>, then running <code>git b<\/code> would just run <code>git branch<\/code> which shortens the command and saves some time and keystrokes.<\/p>\n\n<p>I have similar one- or two letter \"short\" aliases for pushing and pulling code, and some that also set some additional arguments such as <code>aa<\/code> for <code>add --all<\/code> and <code>worktrees<\/code> for <code>worktree list<\/code>.<\/p>\n\n<h3 id=\"more-complicated-aliases\">More complicated aliases<\/h3>\n\n<p>Aliases can be more complex if needed by prefixing it with a <code>!<\/code>, meaning that it executes it as a shell command.<\/p>\n\n<p>This means that I can have <code>repush = !git pull --rebase && git push<\/code> to chain two separate Git commands and combine them into one, and <code>ureset = !git reset --hard $(git upstream)<\/code> which executes the full command, including another alias as part of it.<\/p>\n\n<p>I also have <code>issues = !gh issue list --web<\/code> and <code>pulls = !gh pr list --web<\/code> to open the current repository's GitHub issues or pull requests respectively, which can be done as it's not limited to just running <code>git<\/code> commands.<\/p>\n\n<h3 id=\"custom-functions\">Custom functions<\/h3>\n\n<p>Finally, if an alias is getting too long or complex, then it can extracted to it's own file.<\/p>\n\n<p>Any executable file within your <code>$PATH<\/code> that starts with <code>git-<\/code> will automatically become a Git command.<\/p>\n\n<p>One example that I have is <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/blob\/2b20cd1e59ae3b1fa81074077e855cbdfa02f146\/bin\/bin\/git-cm\">git-cm<\/a> which, similar to the <code>g<\/code> function`, is a bash script that checks for any arguments passed to it and runs a slightly different command. It achieves the same thing as if it were an alias, but it does make it easier to write and maintain as it's in a separate file.<\/p>\n\n<p>These are just some examples. If you want to see my entire configuration, then check out <a href=\"https:\/\/github.com\/opdavies\/dotfiles\/tree\/2b20cd1e59ae3b1fa81074077e855cbdfa02f146\/roles\/git\/files\">my dotfiles repository on GitHub<\/a>.<\/p>\n\n<p>How have you configured Git for your workflow? Reply to this email and let me know.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "4d3892ad51836bdd33e47e7043615d75",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1980f689-9ae9-4f1d-ae0e-7d3bb24ea5b2.json
Normal file
100
content/node.1980f689-9ae9-4f1d-ae0e-7d3bb24ea5b2.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1980f689-9ae9-4f1d-ae0e-7d3bb24ea5b2"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Working backwards\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-07-25T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/07\/25\/working-backwards",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Today, I did a show-and-tell session with my team where I demonstrated an integration I've been working on for a few months and recently released to production.<\/p>\n\n<p>The simplified workflow is we collate some data, send it to a third-party system for translation, receive the translated file and import the translations into Drupal's translation system.<\/p>\n\n<h2 id=\"where-did-i-start%3F\">Where did I start?<\/h2>\n\n<p>The first thing I did was not to collate the data and generate the file but to send a minimal, hard-coded version of the contents to the third-party system.<\/p>\n\n<p>I'd have started with the code to import the translated strings if I hadn't already done this in an earlier spike.<\/p>\n\n<p>This allowed me to send the file, check the response from the third party and ensure they could work with that file type and my proposed content structure.<\/p>\n\n<p>If needed, I could have changed direction and avoided investing much time. This wouldn't have been the case if I'd left this until the end of the process.<\/p>\n\n<p>I also have a working end-to-end test, and I can send a file and get the response I need.<\/p>\n\n<p>What if I'd written all the code and discovered something wouldn't work?<\/p>\n\n<h2 id=\"what-next%3F\">What next?<\/h2>\n\n<p>Now, I can work backwards and start to make the content dynamic.<\/p>\n\n<p>I can introduce more authentic and complicated data, remove the hard-coded test data, and check that things still work.<\/p>\n\n<p>I still have the quick feedback loop, as I can always send the data to the third-party system and verify things work as I iterate on my implementation.<\/p>\n\n<p>With the main pieces of the puzzle in place, I can continue building and filling in the others.<\/p>\n\n<p>Once I have a complete feature with all the pieces in place, I can refactor as needed.<\/p>\n\n<p>I still have the same finished puzzle - I just built it in a different order.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Today, I did a show-and-tell session with my team where I demonstrated an integration I've been working on for a few months and recently released to production.<\/p>\n\n<p>The simplified workflow is we collate some data, send it to a third-party system for translation, receive the translated file and import the translations into Drupal's translation system.<\/p>\n\n<h2 id=\"where-did-i-start%3F\">Where did I start?<\/h2>\n\n<p>The first thing I did was not to collate the data and generate the file but to send a minimal, hard-coded version of the contents to the third-party system.<\/p>\n\n<p>I'd have started with the code to import the translated strings if I hadn't already done this in an earlier spike.<\/p>\n\n<p>This allowed me to send the file, check the response from the third party and ensure they could work with that file type and my proposed content structure.<\/p>\n\n<p>If needed, I could have changed direction and avoided investing much time. This wouldn't have been the case if I'd left this until the end of the process.<\/p>\n\n<p>I also have a working end-to-end test, and I can send a file and get the response I need.<\/p>\n\n<p>What if I'd written all the code and discovered something wouldn't work?<\/p>\n\n<h2 id=\"what-next%3F\">What next?<\/h2>\n\n<p>Now, I can work backwards and start to make the content dynamic.<\/p>\n\n<p>I can introduce more authentic and complicated data, remove the hard-coded test data, and check that things still work.<\/p>\n\n<p>I still have the quick feedback loop, as I can always send the data to the third-party system and verify things work as I iterate on my implementation.<\/p>\n\n<p>With the main pieces of the puzzle in place, I can continue building and filling in the others.<\/p>\n\n<p>Once I have a complete feature with all the pieces in place, I can refactor as needed.<\/p>\n\n<p>I still have the same finished puzzle - I just built it in a different order.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "4f3f3eed089d1a4af0d75429f2731bfe",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1b3afa03-4440-45db-8ee6-314509ae00c9.json
Normal file
100
content/node.1b3afa03-4440-45db-8ee6-314509ae00c9.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1b3afa03-4440-45db-8ee6-314509ae00c9"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "The first Beyond Blocks podcast episode is recorded\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-11-06T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/11\/06\/the-first-beyond-blocks-podcast-episode-is-recorded",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>For my first time in the podcast host chair, I interviewed Matt Glaman - Principal Software Engineer at Acquia.<\/p>\n\n<p>I initially knew Matt from his work on Drupal Commerce, but I wanted to learn about his new project, Retrofit - a tool to make it easier to upgrade from Drupal 7 (which will be end of life in January 2025) to Drupal 10.<\/p>\n\n<p>We also talked briefly about PHPStan Drupal and drupal-check, which are some of Matt's other projects and contributions to the Drupal community.<\/p>\n\n<p>Thank you, Matt, for being the first guest on the Beyond Blocks podcast.<\/p>\n\n<p>I have other guests booked for this week, so the episode with Matt will be <a href=\"https:\/\/www.oliverdavies.uk\/podcast\">published soon<\/a>.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>For my first time in the podcast host chair, I interviewed Matt Glaman - Principal Software Engineer at Acquia.<\/p>\n\n<p>I initially knew Matt from his work on Drupal Commerce, but I wanted to learn about his new project, Retrofit - a tool to make it easier to upgrade from Drupal 7 (which will be end of life in January 2025) to Drupal 10.<\/p>\n\n<p>We also talked briefly about PHPStan Drupal and drupal-check, which are some of Matt's other projects and contributions to the Drupal community.<\/p>\n\n<p>Thank you, Matt, for being the first guest on the Beyond Blocks podcast.<\/p>\n\n<p>I have other guests booked for this week, so the episode with Matt will be <a href=\"https:\/\/www.oliverdavies.uk\/podcast\">published soon<\/a>.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "a813d4b849fdced0618aa5694a3bdadd",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1b4a12e5-78e4-466e-8662-0b7641855a05.json
Normal file
100
content/node.1b4a12e5-78e4-466e-8662-0b7641855a05.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1b4a12e5-78e4-466e-8662-0b7641855a05"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't put HTML in your body field"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-05-24T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/05\/24\/dont-put-html-in-your-body-field",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I often see Drupal projects where people have put raw HTML code into their body or other rich-text fields.<\/p>\n\n<p>Whilst it can be useful for short-term prototyping, I don't think it should be done for content that will be reused or kept for a period of time.<\/p>\n\n<p>If you have structured HTML code in multiple nodes, you can't make changes without editing each instance.<\/p>\n\n<p>What if you need to fix a bug and have hundreds or thousands of instances?<\/p>\n\n<p>If you have inline styles, they won't be updated or affected by changes to your stylesheets, such as changing colour or font family.<\/p>\n\n<p>Instead, create first-class components that use templates that are easier to change and maintain and have a single source of truth that adheres to your design system.<\/p>\n\n<p>In Drupal, use structured data in fields with Paragraphs or Layout Builder and build the templates around them.<\/p>\n\n<p>This makes it easier to maintain and also for people to add and edit content.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I often see Drupal projects where people have put raw HTML code into their body or other rich-text fields.<\/p>\n\n<p>Whilst it can be useful for short-term prototyping, I don't think it should be done for content that will be reused or kept for a period of time.<\/p>\n\n<p>If you have structured HTML code in multiple nodes, you can't make changes without editing each instance.<\/p>\n\n<p>What if you need to fix a bug and have hundreds or thousands of instances?<\/p>\n\n<p>If you have inline styles, they won't be updated or affected by changes to your stylesheets, such as changing colour or font family.<\/p>\n\n<p>Instead, create first-class components that use templates that are easier to change and maintain and have a single source of truth that adheres to your design system.<\/p>\n\n<p>In Drupal, use structured data in fields with Paragraphs or Layout Builder and build the templates around them.<\/p>\n\n<p>This makes it easier to maintain and also for people to add and edit content.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "c81fcb760babf4b27ac37f42d606aade",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1b89a389-5899-4ce5-a3b3-b15ddb2169d8.json
Normal file
100
content/node.1b89a389-5899-4ce5-a3b3-b15ddb2169d8.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1b89a389-5899-4ce5-a3b3-b15ddb2169d8"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Dependency-free PHP Collections"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-03-29T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/03\/29\/collections",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>A few months ago, <a href=\"https:\/\/www.oliverdavies.uk\/podcast\/6-dan-leech-php-tui\">Beyond Blocks podcast guest Dan Leech<\/a> give another talk at the PHP South West user group.<\/p>\n\n<p>This talk was about <a href=\"https:\/\/www.youtube.com\/watch?v=UpyVAcWGQhg\">building an expression language from scratch<\/a>, but in one part of the talk, Dan showed how he creates Collection classes.<\/p>\n\n<p>I use Collection classes a lot, have <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/using-illuminate-collections-outside-laravel\">given talks about them<\/a> and <a href=\"https:\/\/www.drupal.org\/project\/collection_class\">wrote a Collections module for Drupal 7<\/a>.<\/p>\n\n<p>In Dan's talk, instead of using a Collection from Laravel or Doctrine, <a href=\"https:\/\/github.com\/dantleech\/onehourexpr\/blob\/8c4ee4a3c1680455118e16a3e1be2a08418ab207\/src\/Tokens.php\">he created his own<\/a>.<\/p>\n\n<p>His extended PHP's <code>IteratorAggregate<\/code> class so had no external dependencies.<\/p>\n\n<p>He could then add whatever additional methods and functionality he needed.<\/p>\n\n<p>Looking at other repositories on GitHub, I was able to find other examples.<\/p>\n\n<p>I've done this on projects since Dan's talk and like taking the minimalist approach - avoiding adding a dependency to my project and only adding the functionality I need and functionality that's more specific to my domain.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>A few months ago, <a href=\"https:\/\/www.oliverdavies.uk\/podcast\/6-dan-leech-php-tui\">Beyond Blocks podcast guest Dan Leech<\/a> give another talk at the PHP South West user group.<\/p>\n\n<p>This talk was about <a href=\"https:\/\/www.youtube.com\/watch?v=UpyVAcWGQhg\">building an expression language from scratch<\/a>, but in one part of the talk, Dan showed how he creates Collection classes.<\/p>\n\n<p>I use Collection classes a lot, have <a href=\"https:\/\/www.oliverdavies.uk\/presentations\/using-illuminate-collections-outside-laravel\">given talks about them<\/a> and <a href=\"https:\/\/www.drupal.org\/project\/collection_class\">wrote a Collections module for Drupal 7<\/a>.<\/p>\n\n<p>In Dan's talk, instead of using a Collection from Laravel or Doctrine, <a href=\"https:\/\/github.com\/dantleech\/onehourexpr\/blob\/8c4ee4a3c1680455118e16a3e1be2a08418ab207\/src\/Tokens.php\">he created his own<\/a>.<\/p>\n\n<p>His extended PHP's <code>IteratorAggregate<\/code> class so had no external dependencies.<\/p>\n\n<p>He could then add whatever additional methods and functionality he needed.<\/p>\n\n<p>Looking at other repositories on GitHub, I was able to find other examples.<\/p>\n\n<p>I've done this on projects since Dan's talk and like taking the minimalist approach - avoiding adding a dependency to my project and only adding the functionality I need and functionality that's more specific to my domain.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "94b06833489046a4c26442548eee3ca2",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1b926453-4550-4be0-9f73-da25c10e6ed4.json
Normal file
100
content/node.1b926453-4550-4be0-9f73-da25c10e6ed4.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1b926453-4550-4be0-9f73-da25c10e6ed4"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "ADRs and Technical Design Documents"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-09-23T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022\/09\/23\/adrs-technical-design-documents",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <h2 id=\"architectural-decision-records\">Architectural Decision Records<\/h2>\n\n<p>Architectural Decision Records (ADRs) are documents to record software design choices. They could be saved in your code repository as plain-text or Markdown files, or stored in Confluence or a wiki - wherever your team stores its documentation.<\/p>\n\n<p>They usually consist of the sections:<\/p>\n\n<ul>\n<li>Status - is it proposed, accepted, rejected, deprecated, superseded, etc.?<\/li>\n<li>Context - what is the issue that is causing the decision or change?<\/li>\n<li>Decision - what is the change that's being done or proposed?<\/li>\n<li>Consequences - what becomes easier or more difficult to do?<\/li>\n<\/ul>\n\n<p>Any change that is architecturally significant should require an ADR to be written, after which it can be reviewed and potentially actioned.<\/p>\n\n<p>These will remain in place to form a decision log, with specific ADRs being marked as superseded if a newer ADR replaces it.<\/p>\n\n<h2 id=\"technical-design-documents\">Technical Design Documents<\/h2>\n\n<p>A similar type of document are Technical Design Documents (TDDs), that I first saw on TheAltF4Stream. I like to think of these as lightweight ADRs.<\/p>\n\n<p>The first heading is always \"What problem are we trying to solve?\", or sometimes just \"The problem\".<\/p>\n\n<p>Similar to the Context heading in an ADR, this should include a short paragraph describing the issue.<\/p>\n\n<p>Unlike ADRs, there are no other set headings but these are some suggested ones:<\/p>\n\n<ul>\n<li>What is the current process?<\/li>\n<li>What are any requirements?<\/li>\n<li>How do we solve this problem?<\/li>\n<li>Alternative approaches<\/li>\n<\/ul>\n\n<p>I like after describing the problem, being able to move straight into describing what's appropriate and relevant for this task and ignore sections that aren't needed.<\/p>\n\n<p>When I started writing ADRs, they all had the 'Accepted' status as I was either writing them for myself or in a pair or mob. As wasn't adding any value, I've removed it since switching to writing TDDs.<\/p>\n\n<p>Whether you use ADRs, TDDs or another approach, it's very useful to have a log of all of your architectural design decisions, both looking back in the future to remember why something was done in a certain way, or before you start implementing a solution to review the problem, evaluate the requirements and all potential solutions and document the selected one any why it was selected.<\/p>\n\n<p><a href=\"https:\/\/adr.github.io\">Find our more about ADRs<\/a> or <a href=\"https:\/\/altf4.wiki\/t\/how-do-i-write-a-tdd\/21\">find out more about TDDs<\/a>.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <h2 id=\"architectural-decision-records\">Architectural Decision Records<\/h2>\n\n<p>Architectural Decision Records (ADRs) are documents to record software design choices. They could be saved in your code repository as plain-text or Markdown files, or stored in Confluence or a wiki - wherever your team stores its documentation.<\/p>\n\n<p>They usually consist of the sections:<\/p>\n\n<ul>\n<li>Status - is it proposed, accepted, rejected, deprecated, superseded, etc.?<\/li>\n<li>Context - what is the issue that is causing the decision or change?<\/li>\n<li>Decision - what is the change that's being done or proposed?<\/li>\n<li>Consequences - what becomes easier or more difficult to do?<\/li>\n<\/ul>\n\n<p>Any change that is architecturally significant should require an ADR to be written, after which it can be reviewed and potentially actioned.<\/p>\n\n<p>These will remain in place to form a decision log, with specific ADRs being marked as superseded if a newer ADR replaces it.<\/p>\n\n<h2 id=\"technical-design-documents\">Technical Design Documents<\/h2>\n\n<p>A similar type of document are Technical Design Documents (TDDs), that I first saw on TheAltF4Stream. I like to think of these as lightweight ADRs.<\/p>\n\n<p>The first heading is always \"What problem are we trying to solve?\", or sometimes just \"The problem\".<\/p>\n\n<p>Similar to the Context heading in an ADR, this should include a short paragraph describing the issue.<\/p>\n\n<p>Unlike ADRs, there are no other set headings but these are some suggested ones:<\/p>\n\n<ul>\n<li>What is the current process?<\/li>\n<li>What are any requirements?<\/li>\n<li>How do we solve this problem?<\/li>\n<li>Alternative approaches<\/li>\n<\/ul>\n\n<p>I like after describing the problem, being able to move straight into describing what's appropriate and relevant for this task and ignore sections that aren't needed.<\/p>\n\n<p>When I started writing ADRs, they all had the 'Accepted' status as I was either writing them for myself or in a pair or mob. As wasn't adding any value, I've removed it since switching to writing TDDs.<\/p>\n\n<p>Whether you use ADRs, TDDs or another approach, it's very useful to have a log of all of your architectural design decisions, both looking back in the future to remember why something was done in a certain way, or before you start implementing a solution to review the problem, evaluate the requirements and all potential solutions and document the selected one any why it was selected.<\/p>\n\n<p><a href=\"https:\/\/adr.github.io\">Find our more about ADRs<\/a> or <a href=\"https:\/\/altf4.wiki\/t\/how-do-i-write-a-tdd\/21\">find out more about TDDs<\/a>.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "ce0fd785eeded51305f4d32749a7ce65",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1c19d543-604f-43e8-bdaa-c7d3df15d4be.json
Normal file
100
content/node.1c19d543-604f-43e8-bdaa-c7d3df15d4be.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1c19d543-604f-43e8-bdaa-c7d3df15d4be"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Creating API endpoints with Astro\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-02-09T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/02\/09\/creating-api-endpoints-with-astro",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As well as <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2023\/02\/08\/fetching-api-data-with-astro\">fetching API data<\/a>, you can also use Astro to generate your own API endpoints.<\/p>\n\n<p>This is an example of an endpoint that I recently created as part of a demo application:<\/p>\n\n<pre><code class=\"javascript\">\/\/ trains.json.ts\n\nimport data from \"@\/data.json\";\nimport type { APIRoute } from \"astro\";\nimport type { Train } from \"@\/types\";\n\nexport const get: APIRoute = () => {\n return {\n body: JSON.stringify(data.trains as Train[]),\n };\n};\n<\/code><\/pre>\n\n<p>The train data is imported from a JSON file, and Astro's <code>APIRoute<\/code> is responsible for setting the appropriate response headers.<\/p>\n\n<p>For server-side rendered applications, you can also have endpoints for <code>post<\/code>, <code>del<\/code> and <code>all<\/code>, though for this example, I only needed to support GET requests.<\/p>\n\n<p>This is something that I've used a db-json library for previously, but being able to do this in Astro seemed like a good fit as I can easily manage lists of stations as well as a single station from one JSON file but I can just take the static HTML that Astro generates and upload it to a static hosting solution which simplifies the hosting side of things a lot.<\/p>\n\n<p>And, as the example application that consumes the data is also written with Astro, having them both using the same solution has advantages too.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As well as <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2023\/02\/08\/fetching-api-data-with-astro\">fetching API data<\/a>, you can also use Astro to generate your own API endpoints.<\/p>\n\n<p>This is an example of an endpoint that I recently created as part of a demo application:<\/p>\n\n<pre><code class=\"javascript\">\/\/ trains.json.ts\n\nimport data from \"@\/data.json\";\nimport type { APIRoute } from \"astro\";\nimport type { Train } from \"@\/types\";\n\nexport const get: APIRoute = () => {\n return {\n body: JSON.stringify(data.trains as Train[]),\n };\n};\n<\/code><\/pre>\n\n<p>The train data is imported from a JSON file, and Astro's <code>APIRoute<\/code> is responsible for setting the appropriate response headers.<\/p>\n\n<p>For server-side rendered applications, you can also have endpoints for <code>post<\/code>, <code>del<\/code> and <code>all<\/code>, though for this example, I only needed to support GET requests.<\/p>\n\n<p>This is something that I've used a db-json library for previously, but being able to do this in Astro seemed like a good fit as I can easily manage lists of stations as well as a single station from one JSON file but I can just take the static HTML that Astro generates and upload it to a static hosting solution which simplifies the hosting side of things a lot.<\/p>\n\n<p>And, as the example application that consumes the data is also written with Astro, having them both using the same solution has advantages too.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "c6a3315ecb8173fc096250981c691fbe",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1c87442a-8a8b-4134-b692-48a8191c0e00.json
Normal file
100
content/node.1c87442a-8a8b-4134-b692-48a8191c0e00.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1c87442a-8a8b-4134-b692-48a8191c0e00"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "With utility styles, your CSS stops growing\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-03-22T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/03\/22\/with-utility-styles-your-css-stops-growing",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>When working with traditional CSS, the first thing you do when you need to style a new page or component is to open a stylesheet and start writing new CSS.<\/p>\n\n<p>Also when editing existing styles, sometimes you'll write new styles to avoid breaking the existing pages in unexpected ways in other parts of the page. This is why I've not seen many projects where the styling is maintained or refactored over time - only added to.<\/p>\n\n<p>By writing new CSS for every new page or component, the size of your stylesheets will continue to grow and be less performant and harder to maintain over time.<\/p>\n\n<p>With utility styles and frameworks like Tailwind CSS, this happens a lot less or sometimes not at all.<\/p>\n\n<p>If you need to use a class like <code>flex<\/code> or <code>grid<\/code> and you already use that in your project, there's no new CSS to add and the stylesheet doesn't grow. Because these type of classes are so specific, they're much more reusable which means less duplication of CSS rules and less CSS in total.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>When working with traditional CSS, the first thing you do when you need to style a new page or component is to open a stylesheet and start writing new CSS.<\/p>\n\n<p>Also when editing existing styles, sometimes you'll write new styles to avoid breaking the existing pages in unexpected ways in other parts of the page. This is why I've not seen many projects where the styling is maintained or refactored over time - only added to.<\/p>\n\n<p>By writing new CSS for every new page or component, the size of your stylesheets will continue to grow and be less performant and harder to maintain over time.<\/p>\n\n<p>With utility styles and frameworks like Tailwind CSS, this happens a lot less or sometimes not at all.<\/p>\n\n<p>If you need to use a class like <code>flex<\/code> or <code>grid<\/code> and you already use that in your project, there's no new CSS to add and the stylesheet doesn't grow. Because these type of classes are so specific, they're much more reusable which means less duplication of CSS rules and less CSS in total.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "92a7979f45a6c8ae09c876e6d4bd42ce",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1c8bc894-7d3a-441a-ae86-4e38805e8299.json
Normal file
100
content/node.1c8bc894-7d3a-441a-ae86-4e38805e8299.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1c8bc894-7d3a-441a-ae86-4e38805e8299"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Running automated checks in a CI pipeline"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-07-07T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/07\/07\/running-automated-checks-in-a-ci-pipeline",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>As well as <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/07\/03\/committing-ci-artifacts\">committing build artifacts<\/a>, another common use for CI pipelines is for running automated checks.<\/p>\n\n<p>This could include code linting, static analysis, automated tests, checking for security vulnerabilities, and more.<\/p>\n\n<p>Instead of relying on Developers running these checks manually, running them automatically in a CI pipeline ensures they're run regularly and that each commit is deployable.<\/p>\n\n<p>If all the checks pass, a commit can be promoted and released.<\/p>\n\n<p>If not, the commit should not be deployed and it should be fixed.<\/p>\n\n<p>This makes a CI pipeline and automated checks vital to ensure the quality of your software, to identify regressions, and to avoid promoting and releasing broken code.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>As well as <a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/07\/03\/committing-ci-artifacts\">committing build artifacts<\/a>, another common use for CI pipelines is for running automated checks.<\/p>\n\n<p>This could include code linting, static analysis, automated tests, checking for security vulnerabilities, and more.<\/p>\n\n<p>Instead of relying on Developers running these checks manually, running them automatically in a CI pipeline ensures they're run regularly and that each commit is deployable.<\/p>\n\n<p>If all the checks pass, a commit can be promoted and released.<\/p>\n\n<p>If not, the commit should not be deployed and it should be fixed.<\/p>\n\n<p>This makes a CI pipeline and automated checks vital to ensure the quality of your software, to identify regressions, and to avoid promoting and releasing broken code.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "45fc5e3725cf16ecee4a27e40566329d",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1c991221-611b-446d-a1d4-17be4edd9025.json
Normal file
100
content/node.1c991221-611b-446d-a1d4-17be4edd9025.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1c991221-611b-446d-a1d4-17be4edd9025"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Test, then refactor"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-10-20T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/10\/20\/test-then-refactor",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p><a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/10\/19\/phpunit-or-pest\">Whether you prefer PHPUnit or Pest PHP<\/a>, or if you're coding in a different language, it's important to have automated tests - especially before you refactor any code.<\/p>\n\n<p>Before you refactor, you want to have passing tests that you're confident cover all the required functionality.<\/p>\n\n<p>When you finish refactoring, the tests should still pass.<\/p>\n\n<p>Then you know the functionality is the same and the code still works after it's been refactored.<\/p>\n\n<p>If you don't have tests, how do you know everything still works, or how likely are you to do the refactor at all?<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p><a href=\"https:\/\/www.oliverdavies.uk\/daily\/2024\/10\/19\/phpunit-or-pest\">Whether you prefer PHPUnit or Pest PHP<\/a>, or if you're coding in a different language, it's important to have automated tests - especially before you refactor any code.<\/p>\n\n<p>Before you refactor, you want to have passing tests that you're confident cover all the required functionality.<\/p>\n\n<p>When you finish refactoring, the tests should still pass.<\/p>\n\n<p>Then you know the functionality is the same and the code still works after it's been refactored.<\/p>\n\n<p>If you don't have tests, how do you know everything still works, or how likely are you to do the refactor at all?<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "fb957020708c21d55d5d99c008e1797b",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1d13247c-a420-4133-9720-4018b060f801.json
Normal file
100
content/node.1d13247c-a420-4133-9720-4018b060f801.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1d13247c-a420-4133-9720-4018b060f801"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Test-driven development makes you more productive\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-07-15T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/07\/15\/test-driven-development-makes-you-more-productive",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I think that test-driven development (TDD) makes you productive.<\/p>\n\n<p>Firstly, you save time by not needing to switch from your code to a terminal or browser to test it.<\/p>\n\n<p>But, just as importantly, TDD reduces procrastination. It's much clearer to see what the next steps are.<\/p>\n\n<p>You're either thinking and designing your code when writing a failing test or fixing the test failures in the implementation code to get the test to pass. You can focus on each failure and message separately and get them to pass instead of thinking about the whole feature or the rest of the application.<\/p>\n\n<p>Once you have a working test, you can focus on refactoring any code or moving on to writing the next assertion or the next test.<\/p>\n\n<p>I think that achieving small tasks with short feedback loops using test-driven development makes it much easier to remain productive and focussed.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I think that test-driven development (TDD) makes you productive.<\/p>\n\n<p>Firstly, you save time by not needing to switch from your code to a terminal or browser to test it.<\/p>\n\n<p>But, just as importantly, TDD reduces procrastination. It's much clearer to see what the next steps are.<\/p>\n\n<p>You're either thinking and designing your code when writing a failing test or fixing the test failures in the implementation code to get the test to pass. You can focus on each failure and message separately and get them to pass instead of thinking about the whole feature or the rest of the application.<\/p>\n\n<p>Once you have a working test, you can focus on refactoring any code or moving on to writing the next assertion or the next test.<\/p>\n\n<p>I think that achieving small tasks with short feedback loops using test-driven development makes it much easier to remain productive and focussed.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d8c18f8667771c2497ae722e5849f6fc",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1d7263d8-f2ee-4af5-aea1-7171b9f84135.json
Normal file
100
content/node.1d7263d8-f2ee-4af5-aea1-7171b9f84135.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1d7263d8-f2ee-4af5-aea1-7171b9f84135"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "How I started programming"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2022-08-28T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2022-08-28\/how-started-programming",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>In 2007, I was working in the IT sector in a Desktop Support role but hadn't done any coding professionally.<\/p>\n\n<p>In my spare time, I was a black belt in Tae Kwon-Do and enjoyed training at a few different schools. Because of my IT experience, I was asked if I could create a website for one of the schools - somewhere that we could post information and class times for new starters, as well as news articles and competition results.<\/p>\n\n<p>This would be my introduction to programming.<\/p>\n\n<p>I started learning what I needed to know, starting with HTML and CSS - experimenting with a template that I found online and was able to tweak to match the school's colours.<\/p>\n\n<p>I was able to complete the first version of the website with static HTML pages and CSS but had to manually create a new HTML page for every new news article and edit existing pages manually.<\/p>\n\n<p>I wanted to make it more dynamic, and started to learn about PHP and MySQL from video courses and online forums.<\/p>\n\n<p>After posting a question about some PHP code that I'd written, someone suggested that I look at content management systems - namely Drupal, which was used for that forum (I have <a href=\"https:\/\/twitter.com\/opdavies\/status\/1185456825103241216\">a screenshot of the reply<\/a>). This was a new concept to me as until that point, I'd written everything so far myself whilst learning it.<\/p>\n\n<p>I remember evaluating Drupal alongside some others - rebuilding the same website a few different times, but stuck with Drupal and relaunched it on Drupal 6 and a custom theme that I'd created from the original templates.<\/p>\n\n<p>I signed up for a Drupal.org account, started to do some freelance work for a local web design agency, and built a new website for a local cattery.<\/p>\n\n<p>I started blogging, attending meetups, and when an opportunity to switch careers to software development came along, I applied for and got the job.<\/p>\n\n<p>That job was also using Drupal and, in another email, I'll write more about why I still like and use Drupal years later.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>In 2007, I was working in the IT sector in a Desktop Support role but hadn't done any coding professionally.<\/p>\n\n<p>In my spare time, I was a black belt in Tae Kwon-Do and enjoyed training at a few different schools. Because of my IT experience, I was asked if I could create a website for one of the schools - somewhere that we could post information and class times for new starters, as well as news articles and competition results.<\/p>\n\n<p>This would be my introduction to programming.<\/p>\n\n<p>I started learning what I needed to know, starting with HTML and CSS - experimenting with a template that I found online and was able to tweak to match the school's colours.<\/p>\n\n<p>I was able to complete the first version of the website with static HTML pages and CSS but had to manually create a new HTML page for every new news article and edit existing pages manually.<\/p>\n\n<p>I wanted to make it more dynamic, and started to learn about PHP and MySQL from video courses and online forums.<\/p>\n\n<p>After posting a question about some PHP code that I'd written, someone suggested that I look at content management systems - namely Drupal, which was used for that forum (I have <a href=\"https:\/\/twitter.com\/opdavies\/status\/1185456825103241216\">a screenshot of the reply<\/a>). This was a new concept to me as until that point, I'd written everything so far myself whilst learning it.<\/p>\n\n<p>I remember evaluating Drupal alongside some others - rebuilding the same website a few different times, but stuck with Drupal and relaunched it on Drupal 6 and a custom theme that I'd created from the original templates.<\/p>\n\n<p>I signed up for a Drupal.org account, started to do some freelance work for a local web design agency, and built a new website for a local cattery.<\/p>\n\n<p>I started blogging, attending meetups, and when an opportunity to switch careers to software development came along, I applied for and got the job.<\/p>\n\n<p>That job was also using Drupal and, in another email, I'll write more about why I still like and use Drupal years later.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "f97cc46c7cd91b966de8bd195077270d",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1d77c4bf-9687-461b-8f9b-73f46507e7d8.json
Normal file
100
content/node.1d77c4bf-9687-461b-8f9b-73f46507e7d8.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1d77c4bf-9687-461b-8f9b-73f46507e7d8"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Making my Drupal module template Drupal 10 compatible\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-04-21T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/04\/21\/making-my-drupal-module-template-drupal-10-compatible",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Today, I made my <a href=\"https:\/\/github.com\/opdavies\/drupal-module-template\">Drupal module template<\/a> compatible with Drupal 10.<\/p>\n\n<p>Because Drupal 10 is developed from Drupal 9, the changes between the two and the changes required are minimal.<\/p>\n\n<p>In this case, I only needed to change the <code>core_version_requirement<\/code> in <code>drupal_module_template.info.yml<\/code> from <code>^9<\/code> to <code>^9 || ^10<\/code> - meaning the template works for both Drupal 9 and 10, so there's no need for different versions.<\/p>\n\n<p>If it used any deprecated code that was removed before Drupal 10, I'd have needed to update it to use the Drupal 10-compliant code.<\/p>\n\n<p>Updating to new major Drupal versions is much easier than it used to be!<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Today, I made my <a href=\"https:\/\/github.com\/opdavies\/drupal-module-template\">Drupal module template<\/a> compatible with Drupal 10.<\/p>\n\n<p>Because Drupal 10 is developed from Drupal 9, the changes between the two and the changes required are minimal.<\/p>\n\n<p>In this case, I only needed to change the <code>core_version_requirement<\/code> in <code>drupal_module_template.info.yml<\/code> from <code>^9<\/code> to <code>^9 || ^10<\/code> - meaning the template works for both Drupal 9 and 10, so there's no need for different versions.<\/p>\n\n<p>If it used any deprecated code that was removed before Drupal 10, I'd have needed to update it to use the Drupal 10-compliant code.<\/p>\n\n<p>Updating to new major Drupal versions is much easier than it used to be!<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d9902d3f03d57f8eef7e67d29133f05f",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1d9a9868-b734-44b3-b050-cfe3d675d30c.json
Normal file
100
content/node.1d9a9868-b734-44b3-b050-cfe3d675d30c.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1d9a9868-b734-44b3-b050-cfe3d675d30c"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't use aliases"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-06-21T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/06\/21\/dont-use-aliases",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Shell aliases are a good way to increase productivity by shortening long commands, adding additional options to existing ones or creating new ones that even combine multiple commands.<\/p>\n\n<p>Common aliases are <code>g<\/code> for <code>git<\/code>, <code>gs<\/code> for <code>git status<\/code> and <code>dr<\/code> for <code>drush<\/code>, but they will be different for each person depending on what tools they use and what commands they type often.<\/p>\n\n<p>Whilst aliases are great for personal productivity, there are times I'd suggest not using them.<\/p>\n\n<p>If you're giving a demo as part of a presentation or working in a pair or mob, either use the full commands or explain what custom aliases or functions you're running, what they do, and how they differ from the default functionality.<\/p>\n\n<p>I recently watched a video where someone was using a <code>gc<\/code> command.<\/p>\n\n<p>It could have been an alias for <code>git clone<\/code>, <code>git checkout<\/code>, <code>git commit<\/code> or <code>git cherry-pick<\/code> - just to name a few options.<\/p>\n\n<p>It could have been something else altogether.<\/p>\n\n<p>Another approach I use is to have aliases auto-expand and show the full command. This makes it possible for others to see the commands being executed and reminds you, too.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Shell aliases are a good way to increase productivity by shortening long commands, adding additional options to existing ones or creating new ones that even combine multiple commands.<\/p>\n\n<p>Common aliases are <code>g<\/code> for <code>git<\/code>, <code>gs<\/code> for <code>git status<\/code> and <code>dr<\/code> for <code>drush<\/code>, but they will be different for each person depending on what tools they use and what commands they type often.<\/p>\n\n<p>Whilst aliases are great for personal productivity, there are times I'd suggest not using them.<\/p>\n\n<p>If you're giving a demo as part of a presentation or working in a pair or mob, either use the full commands or explain what custom aliases or functions you're running, what they do, and how they differ from the default functionality.<\/p>\n\n<p>I recently watched a video where someone was using a <code>gc<\/code> command.<\/p>\n\n<p>It could have been an alias for <code>git clone<\/code>, <code>git checkout<\/code>, <code>git commit<\/code> or <code>git cherry-pick<\/code> - just to name a few options.<\/p>\n\n<p>It could have been something else altogether.<\/p>\n\n<p>Another approach I use is to have aliases auto-expand and show the full command. This makes it possible for others to see the commands being executed and reminds you, too.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "d77f4c3aa58ffc20e26976b05b6332a5",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1daba854-384d-4edd-8095-052ace0d073e.json
Normal file
100
content/node.1daba854-384d-4edd-8095-052ace0d073e.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1daba854-384d-4edd-8095-052ace0d073e"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Git hooks - yay or nay?"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2024-03-21T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2024\/03\/21\/git-hooks---yay-or-nay",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Many people are very for or against Git hooks - scripts that run automatically on events such as pre-commit and pre-push.<\/p>\n\n<p>Commonly, they are used for running tasks such as altering a commit message or running before committing automated tests and static analysis before pushing a commit.<\/p>\n\n<p>I'm on the fence.<\/p>\n\n<p>I've used them and added support for them to Build Configs, but I don't feel strongly about them.<\/p>\n\n<p>They are awkward to set up (you need to edit the configuration for them to work) and can be easily disabled or bypassed.<\/p>\n\n<p>Some people think it's the Developer's responsibility to run the tasks before pushing changes or that they'll be run in a CI pipeline, so why would they need to be run locally?<\/p>\n\n<p>As I write many small commits and push changes regularly, I can find hooks irritating and prefer to use watchers instead with tools like <code>watchexec<\/code> and <code>entr<\/code>.<\/p>\n\n<p>There are also tools like Captain Hook that are built to manage Git hooks. Maybe, I should investigate it more.<\/p>\n\n<p>What do you think? Are you yay or nay for Git hooks?<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Many people are very for or against Git hooks - scripts that run automatically on events such as pre-commit and pre-push.<\/p>\n\n<p>Commonly, they are used for running tasks such as altering a commit message or running before committing automated tests and static analysis before pushing a commit.<\/p>\n\n<p>I'm on the fence.<\/p>\n\n<p>I've used them and added support for them to Build Configs, but I don't feel strongly about them.<\/p>\n\n<p>They are awkward to set up (you need to edit the configuration for them to work) and can be easily disabled or bypassed.<\/p>\n\n<p>Some people think it's the Developer's responsibility to run the tasks before pushing changes or that they'll be run in a CI pipeline, so why would they need to be run locally?<\/p>\n\n<p>As I write many small commits and push changes regularly, I can find hooks irritating and prefer to use watchers instead with tools like <code>watchexec<\/code> and <code>entr<\/code>.<\/p>\n\n<p>There are also tools like Captain Hook that are built to manage Git hooks. Maybe, I should investigate it more.<\/p>\n\n<p>What do you think? Are you yay or nay for Git hooks?<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "8740e9029c98140ce8609709977e5145",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1dff55c7-8b6d-4877-90d0-93fdb371ef6a.json
Normal file
100
content/node.1dff55c7-8b6d-4877-90d0-93fdb371ef6a.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1dff55c7-8b6d-4877-90d0-93fdb371ef6a"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Are conventional commits worth it?\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-11-24T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/11\/24\/are-conventional-commits-worth-it",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>For some time, I've written commit messages following the Conventional Commits specification, where you start the subject with the type of commit - such as <code>feat<\/code>, <code>fix<\/code>, <code>chore<\/code>, <code>docs<\/code>, etc - and provide an optional scope before completing the subject line (the first line in the message).<\/p>\n\n<p>Then, it is encouraged to add a longer body to the message and provide any links and task IDs that the change relates to.<\/p>\n\n<p>Now I've been using it for a while, I'm deciding whether it adds value for me and whether it's worth me using it.<\/p>\n\n<p>I don't create automatic CHANGELOG files from the commit types.<\/p>\n\n<p>The scopes are usually arbitrary, it's unclear which scope (or scopes) should be added, or it repeats the module name I'm working on (which I could see from the Git diff).<\/p>\n\n<p>While I see value in writing descriptive commit messages, I'm unsure if I do to format the subject line in this way.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>I like to use an iterative approach to my workflow. I like to try things and see if they work for me. If not, I can stop or continue iterating.<\/p>\n\n<p>If working with others, should you focus on writing commits that categorise commit messages within their subject or writing descriptive commit messages that capture why the change is needed?<\/p>\n\n<p>Which provides the most value when looking back at the Git log in the future?<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>For some time, I've written commit messages following the Conventional Commits specification, where you start the subject with the type of commit - such as <code>feat<\/code>, <code>fix<\/code>, <code>chore<\/code>, <code>docs<\/code>, etc - and provide an optional scope before completing the subject line (the first line in the message).<\/p>\n\n<p>Then, it is encouraged to add a longer body to the message and provide any links and task IDs that the change relates to.<\/p>\n\n<p>Now I've been using it for a while, I'm deciding whether it adds value for me and whether it's worth me using it.<\/p>\n\n<p>I don't create automatic CHANGELOG files from the commit types.<\/p>\n\n<p>The scopes are usually arbitrary, it's unclear which scope (or scopes) should be added, or it repeats the module name I'm working on (which I could see from the Git diff).<\/p>\n\n<p>While I see value in writing descriptive commit messages, I'm unsure if I do to format the subject line in this way.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>I like to use an iterative approach to my workflow. I like to try things and see if they work for me. If not, I can stop or continue iterating.<\/p>\n\n<p>If working with others, should you focus on writing commits that categorise commit messages within their subject or writing descriptive commit messages that capture why the change is needed?<\/p>\n\n<p>Which provides the most value when looking back at the Git log in the future?<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "e3dc97eea5cca21de24880789f8cf5fd",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1e65d528-0dac-4def-bc3e-8c019baa5e1e.json
Normal file
100
content/node.1e65d528-0dac-4def-bc3e-8c019baa5e1e.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1e65d528-0dac-4def-bc3e-8c019baa5e1e"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Writing custom assertions in your tests\n"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2023-08-17T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2023\/08\/17\/writing-custom-assertions-in-your-tests",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>Writing custom assertions is a great way to clean up your test code.<\/p>\n\n<p>Here's an example from one of my client Drupal projects:<\/p>\n\n<pre><code class=\"language-php\">private static function assertProductVariationHasPrice(ProductVariationInterface $productVariation, string $expectedPrice): void {\n self::assertSame(\n actual: $productVariation->getPrice()->getNumber(),\n expected: $expectedPrice,\n );\n}\n<\/code><\/pre>\n\n<p>This one wraps a single assertion, but they could also include multiple assertions or additional steps.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>A custom assertion is a simple function but it makes the test code more readable and less repetitive.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>Writing custom assertions is a great way to clean up your test code.<\/p>\n\n<p>Here's an example from one of my client Drupal projects:<\/p>\n\n<pre><code class=\"language-php\">private static function assertProductVariationHasPrice(ProductVariationInterface $productVariation, string $expectedPrice): void {\n self::assertSame(\n actual: $productVariation->getPrice()->getNumber(),\n expected: $expectedPrice,\n );\n}\n<\/code><\/pre>\n\n<p>This one wraps a single assertion, but they could also include multiple assertions or additional steps.<\/p>\n\n<h2 id=\"here%27s-the-thing\">Here's the thing<\/h2>\n\n<p>A custom assertion is a simple function but it makes the test code more readable and less repetitive.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "a7a933ef1250a866505ee7da5f99d039",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
100
content/node.1ed0ad0e-6247-4dd7-a796-2635b3f50616.json
Normal file
100
content/node.1ed0ad0e-6247-4dd7-a796-2635b3f50616.json
Normal file
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"uuid": [
|
||||
{
|
||||
"value": "1ed0ad0e-6247-4dd7-a796-2635b3f50616"
|
||||
}
|
||||
],
|
||||
"langcode": [
|
||||
{
|
||||
"value": "en"
|
||||
}
|
||||
],
|
||||
"type": [
|
||||
{
|
||||
"target_id": "daily_email",
|
||||
"target_type": "node_type",
|
||||
"target_uuid": "8bde1f2f-eef9-4f2d-ae9c-96921f8193d7"
|
||||
}
|
||||
],
|
||||
"revision_timestamp": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"revision_uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"revision_log": [],
|
||||
"status": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"uid": [
|
||||
{
|
||||
"target_type": "user",
|
||||
"target_uuid": "b8966985-d4b2-42a7-a319-2e94ccfbb849"
|
||||
}
|
||||
],
|
||||
"title": [
|
||||
{
|
||||
"value": "Don't over rely on AI"
|
||||
}
|
||||
],
|
||||
"created": [
|
||||
{
|
||||
"value": "2025-01-12T00:00:00+00:00"
|
||||
}
|
||||
],
|
||||
"changed": [
|
||||
{
|
||||
"value": "2025-05-11T06:09:49+00:00"
|
||||
}
|
||||
],
|
||||
"promote": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"sticky": [
|
||||
{
|
||||
"value": false
|
||||
}
|
||||
],
|
||||
"default_langcode": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"revision_translation_affected": [
|
||||
{
|
||||
"value": true
|
||||
}
|
||||
],
|
||||
"path": [
|
||||
{
|
||||
"alias": "\/daily\/2025\/01\/12\/reliance",
|
||||
"langcode": "en"
|
||||
}
|
||||
],
|
||||
"body": [
|
||||
{
|
||||
"value": "\n <p>I've occasionally been experimenting with AI whilst programming.<\/p>\n\n<p>Not in my editor, but asking it questions if I'm unsure how to do something or something isn't working.<\/p>\n\n<p>As a pair programming partner of sorts.<\/p>\n\n<p>Its results and suggestions are still mixed.<\/p>\n\n<p>But I've noticed I've started to ask AI for answers to simple questions I can find or figure out myself.<\/p>\n\n<p>Things like how to show more verbose output for a command, which I can find from the command's help text or manual.<\/p>\n\n<p>This was part of a larger issue which, instead of asking AI, I would usually investigate by reading the available documentation or source code.<\/p>\n\n<p>I don't want to lose my problem solving skills.<\/p>\n\n<p>I like reading documentation and code to learn more about the tools I'm using and to solve issues I encounter.<\/p>\n\n<p>I like to read articles others have written on their websites about the same or similar issues.<\/p>\n\n<p>Whilst AI can be a useful tool, I don't want to become over reliant on it.<\/p>\n\n<p>I still want to be able to investigate, solve and learn things for myself and enjoy the process.<\/p>\n\n ",
|
||||
"format": "full_html",
|
||||
"processed": "\n <p>I've occasionally been experimenting with AI whilst programming.<\/p>\n\n<p>Not in my editor, but asking it questions if I'm unsure how to do something or something isn't working.<\/p>\n\n<p>As a pair programming partner of sorts.<\/p>\n\n<p>Its results and suggestions are still mixed.<\/p>\n\n<p>But I've noticed I've started to ask AI for answers to simple questions I can find or figure out myself.<\/p>\n\n<p>Things like how to show more verbose output for a command, which I can find from the command's help text or manual.<\/p>\n\n<p>This was part of a larger issue which, instead of asking AI, I would usually investigate by reading the available documentation or source code.<\/p>\n\n<p>I don't want to lose my problem solving skills.<\/p>\n\n<p>I like reading documentation and code to learn more about the tools I'm using and to solve issues I encounter.<\/p>\n\n<p>I like to read articles others have written on their websites about the same or similar issues.<\/p>\n\n<p>Whilst AI can be a useful tool, I don't want to become over reliant on it.<\/p>\n\n<p>I still want to be able to investigate, solve and learn things for myself and enjoy the process.<\/p>\n\n ",
|
||||
"summary": null
|
||||
}
|
||||
],
|
||||
"feeds_item": [
|
||||
{
|
||||
"imported": "2025-05-11T06:09:49+00:00",
|
||||
"guid": null,
|
||||
"hash": "6e42e4070398b24d913cecbd7fa25945",
|
||||
"target_type": "feeds_feed",
|
||||
"target_uuid": "90c85284-7ca8-4074-9178-97ff8384fe76"
|
||||
}
|
||||
]
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue