Home

Topics

AI

  1. Make it right
  2. The thing that brought me joy
  3. Move slowly and make things

Announcements

  1. Interviewed by Snipcart
  2. The Definitive Guide to Craft Validation for Plugin Developers (the book)
  3. Introducing Glossary for Craft
  4. Introducing Craft Cookbook
  5. Git push your universe
  6. Testee 2.2
  7. Introducing Template OmniLogger
  8. Hull Digital Live 2012
  9. Introducing add-on RSS feeds
  10. SL Developer Info for ExpressionEngine 2
  11. Interviewed at Meta Q
  12. Introducing SmartDown 1.2
  13. So long to ExpressionEngine 1
  14. Introducing Usher
  15. Introducing OmniLog: System-wide message logging for ExpressionEngine add-on developers
  16. Speaking at EEUK 2011
  17. Introducing Crumbly: Custom ExpressionEngine breadcrumbs made easy
  18. Introducing DropDate for ExpressionEngine 2
  19. Introducing Testee: Unit testing for ExpressionEngine add-ons
  20. Introducing Campaigner 4
  21. Introducing Campaigner for ExpressionEngine 2
  22. Announcing MailChimp Subscribe for ExpressionEngine 2
  23. Speaking at EECI 2010
  24. Hull Digital Live 2010
  25. Hull Digital Question Time
  26. Introducing Campaigner
  27. Introducing SmartDown: Markdown Extra and SmartyPants for ExpressionEngine
  28. It speaks!
  29. Introducing DropDate: Better date selection in ExpressionEngine
  30. Introducing BucketList 1.1
  31. New ExpressionEngine module: SL Developer Info
  32. Introducing Speakeasy, the ExpressionEngine anti-spambot
  33. Iconic Interiors shortlisted for Top 10 Sites of 2008
  34. Labgruppen.com bags an “Outstanding Achievement” Interactive Media Award
  35. In the club
  36. Sitting pretty at the Interactive Media Awards

Bash

  1. Verify a checksum
  2. Execute a command with another user’s environment

CMS

  1. Custom Decap CMS previews in Gatsby
  2. “Module not found” error with Gatsby, Netlify CMS, and PostCSS

Craft CMS

  1. Start with the API: A better approach to developing Craft plugins
  2. How to handle Composer dependency conflicts in your Craft plugins
  3. The hidden perils of Craft plugin service classes
  4. How and when to use PSR-4 autoloading in your Craft plugins
  5. The Definitive Guide to Craft Validation for Plugin Developers (the book)
  6. Introducing Glossary for Craft
  7. Craft quick tip: Add CTRL-S support to your plugin forms
  8. The definitive guide to validation in Craft, part 5: Custom validators
  9. The definitive guide to validation in Craft, part 4: Hidden validator settings
  10. The definitive guide to validation in Craft, part 3: Attribute rules
  11. The definitive guide to validation in Craft, part 2: AttributeTypes
  12. The definitive guide to validation in Craft, part 1: Foundations
  13. A guide for Craft Cookbook recipe authors
  14. Clean up your Craft templates with site-specific plugins
  15. Introducing Craft Cookbook
  16. Craft your content with Markdown and Matrix
  17. Introducing SmartDown for Craft

CSS

  1. Specify a default line-height for each font-size in Tailwind CSS
  2. CSS-only highlighter effect

Django

  1. A pedant’s guide to working with Django ModelForm fields

Elixir

  1. PhoenixTest foot guns
  2. Organising Ecto schemas
  3. Naming Phoenix context functions

ExpressionEngine

  1. Git push your universe
  2. EllisLab bemoans paltry 900% ROI
  3. A brief introduction to ExpressionEngine ACTions
  4. Updates and oddments: August 2012
  5. Testee 2.2
  6. Introducing Template OmniLogger
  7. EE gotchas: Nested “no results” tags (redux)
  8. The ExpressionEngine Friday roundup
  9. EE’s bugs are not my problem (or yours)
  10. EE gotchas: Nested “no results” tags
  11. Introducing add-on RSS feeds
  12. The missing ExpressionEngine multi-language lingua franca
  13. How to implement a custom ExpressionEngine extension hook
  14. The add-on developer’s guide to abdicating responsibility
  15. SL Developer Info for ExpressionEngine 2
  16. Introducing SmartDown 1.2
  17. So long to ExpressionEngine 1
  18. Updates and oddments
  19. Introducing Usher
  20. Integrating ExpressionEngine with third-party APIs (part 4 of 4)
  21. Integrating ExpressionEngine with third-party APIs (part 3 of 4)
  22. Introducing OmniLog: System-wide message logging for ExpressionEngine add-on developers
  23. Integrating ExpressionEngine with third-party APIs (part 2 of 4)
  24. Speaking at EEUK 2011
  25. Integrating ExpressionEngine with third-party APIs (part 1 of 4)
  26. Introducing Crumbly: Custom ExpressionEngine breadcrumbs made easy
  27. Introducing DropDate for ExpressionEngine 2
  28. ExpressionEngine add-on development: An update
  29. Introducing Testee: Unit testing for ExpressionEngine add-ons
  30. Introducing Campaigner 4
  31. Introducing Campaigner for ExpressionEngine 2
  32. ExpressionEngine add-on development: Designing the user interface
  33. Announcing MailChimp Subscribe for ExpressionEngine 2
  34. ExpressionEngine add-on development: User interface design principles
  35. ExpressionEngine add-on development: Introducing Tweedee
  36. ExpressionEngine add-on development: Survey results
  37. Speaking at EECI 2010
  38. ExpressionEngine add-on development
  39. ExpressionEngine 2 add-on plans
  40. Introducing Campaigner
  41. Introducing SmartDown: Markdown Extra and SmartyPants for ExpressionEngine
  42. Introducing DropDate: Better date selection in ExpressionEngine
  43. Introducing BucketList 1.1
  44. New ExpressionEngine module: SL Developer Info
  45. The ExpressionEngine 2.0 add-on dilemma
  46. Introducing Speakeasy, the ExpressionEngine anti-spambot
  47. Using Git to manage an ExpressionEngine website (part 4 of 4)
  48. Using Git to manage an ExpressionEngine website (part 3 of 4)
  49. Using Git to manage an ExpressionEngine website (part 2 of 4)
  50. Using Git to manage an ExpressionEngine website (part 1 of 4)
  51. In the club

Git

  1. How to bypass the Git pre-push hook
  2. Sort the output of git status
  3. How to use a private GitLab repository as a Composer dependency
  4. GitLab CI and YAML booleans

Happy Stack

  1. Building Happy Stack: naming things
  2. Building Happy Stack: notifications

JavaScript

  1. Simplify imports with path mapping
  2. Check a date with Chai
  3. Using TypeScript with Gatsby
  4. Nested optional chaining in JavaScript
  5. Custom Decap CMS previews in Gatsby
  6. Rounding errors in JSON Schema validation
  7. “Module not found” error with Gatsby, Netlify CMS, and PostCSS
  8. Chai assert error
  9. Selectively disable ESLint
  10. The right way to compare arrays with Chai
  11. Numeric environment variables and TypeScript
  12. Compute the difference between two JavaScript arrays
  13. JavaScript logical operators
  14. Avoid Array.prototype.push
  15. Log nested objects in Node
  16. Generate an array of random data
  17. Split a JavaScript array into chunks
  18. Generate a pseudo-random boolean
  19. Modelling API requests with Statecharts
  20. Keep JavaScript form validation simple

Laravel

  1. Using Eloquent subqueries to randomise grouped results
  2. Building Happy Stack: naming things
  3. Building Happy Stack: notifications
  4. Authorising Laravel Nova actions
  5. Conditional validation rules in Laravel
  6. How to change the URL slug of a Laravel Nova resource
  7. Understanding Laravel’s Macroable trait
  8. Laravel route collection binding
  9. A nicer way of overriding Eloquent global scopes
  10. Laravel’s mysteriously macroable paginators
  11. Eager loading Eloquent properties
  12. Cleaner code with Eloquent events
  13. Eloquent attributes and database defaults
  14. How to implement a custom Laravel zip code validation rule
  15. How to build a fluent Laravel repository API
  16. Laravel quick tip: Find by username or fail

MongoDB

  1. MongoDB ObjectId timestamp
  2. Query MongoDB by array field size

Node.js

  1. Undocumented Node Migrate options
  2. Numeric environment variables and TypeScript
  3. Transform objects in a Node stream
  4. Log nested objects in Node
  5. Node -r
  6. Node type definitions

Opinion

  1. Make it right
  2. The thing that brought me joy
  3. Move slowly and make things
  4. The complexity halo
  5. Design principles
  6. Gender in tech, and the right not to be offended
  7. EllisLab bemoans paltry 900% ROI
  8. EE’s bugs are not my problem (or yours)
  9. The missing ExpressionEngine multi-language lingua franca
  10. Ready to serve
  11. The myth of company morality
  12. Got dissatisfaction
  13. The ExpressionEngine 2.0 add-on dilemma
  14. The Lack of Enterprise Show
  15. Atebits' common-sense approach to licensing
  16. Kicking the business book habit
  17. How to write a quotation request that saves you money
  18. A guide to choosing the best DOCTYPE for your website
  19. If you can't fix it, it's not a problem
  20. Show them what you're made of
  21. The right way to buy on price during a recession
  22. Show me the money
  23. In praise of the Email Standards Project
  24. The agile developer's guide to building a cathedral
  25. Working for the greater good
  26. Stop Planning, Start Doing
  27. HTML vs. plain text emails: Get your priorities straight
  28. Marketing the Mormons
  29. Not making the most of now
  30. Never forget the big picture
  31. The stupidity of the opt-out checkbox
  32. Delivering a reliable service through business processes
  33. The USP of me
  34. The worst productivity killer

Phoenix

  1. PhoenixTest foot guns
  2. Organising Ecto schemas
  3. Naming Phoenix context functions

PHP

  1. JavaScript logical operators
  2. Generate a pseudo-random boolean
  3. How to write version-agnostic bash scripts for PHP
  4. How to use a private GitLab repository as a Composer dependency
  5. Randomise your tests

Testing

  1. PhoenixTest foot guns
  2. Check a date with Chai
  3. Chai assert error
  4. The right way to compare arrays with Chai
  5. Randomise your tests
  6. Testee 2.2
  7. Introducing Testee: Unit testing for ExpressionEngine add-ons

Tools

  1. Visual Studio Code “actions” shortcut
  2. Clear the terminal in macOS
  3. Search the file explorer in Visual Studio Code

TypeScript

  1. Simplify imports with path mapping
  2. Using TypeScript with Gatsby
  3. Custom TypeScript type guards
  4. Numeric environment variables and TypeScript
  5. Transform objects in a Node stream
  6. Generate an array of random data
  7. TypeScript object bracket notation
  8. Node -r
  9. Node type definitions
  10. TypeScript generics

Validation

  1. Rounding errors in JSON Schema validation
  2. Sane URL validation in JSON Schema
  3. Keep JavaScript form validation simple

Weeknotes

  1. Weeknotes: Claude
  2. Weeknotes: Covid, mostly
  3. Weeknotes: Working on Hap, and working on working