<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-GB" xmlns="http://www.w3.org/2005/Atom">
  <id>tag:www.markhesketh.com,2005:/feed</id>
  <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog"/>
  <link rel="self" type="application/atom+xml" href="https://www.markhesketh.com/feed.atom"/>
  <title>Mark Hesketh</title>
  <updated>2025-03-10T09:42:22Z</updated>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/15</id>
    <published>2025-03-10T09:40:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/write-good-obsidian-plugin"/>
    <title>Introducing: Write Good, an Obsidian plugin</title>
    <content type="html">&lt;p&gt;Last week, I built '&lt;a href="https://github.com/markahesketh/write-good-obsidian/"&gt;Write Good&lt;/a&gt;', an Obsidian plugin to help improve writing style, built on top of a package of the same name,  &lt;a href="https://github.com/btford/write-good"&gt;Write Good by Brian Ford&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This week, it got approved by the Obsidian team and is now &lt;a href="https://obsidian.md/plugins?search=write%20good"&gt;listed as a community plugin&lt;/a&gt;. You can also install it from within Obsidian itself.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzM4P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--a5f4a9fd552a5ffefbd000edb0198b09ab80b868" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzgsInB1ciI6ImJsb2JfaWQifX0=--8ebe6a7dfaa1d2ae990a2ef69701bdb38a578f97/write-good-obsidian-installer.png" filename="write-good-obsidian-installer.png" filesize="368982" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzgsInB1ciI6ImJsb2JfaWQifX0=--8ebe6a7dfaa1d2ae990a2ef69701bdb38a578f97/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/write-good-obsidian-installer.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;It highlights issues and suggests improvements as you type, such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Passive voice&lt;/li&gt;
&lt;li&gt;Complex phrases&lt;/li&gt;
&lt;li&gt;weasel' words&lt;/li&gt;
&lt;li&gt;etc &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I built it for myself as while a VS Code extension already exists, I use Obsidian for my note-taking and wanted to port these features across.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzM3P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--a2ef2114f35a68345c2766373df3d0fe174ceee1" content-type="image/gif" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcsInB1ciI6ImJsb2JfaWQifX0=--8881a571beec96682ed7ce068b0bce560a7b7506/write-good-obsidian-2.gif" filename="write-good-obsidian-2.gif" filesize="34795" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--gif"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzcsInB1ciI6ImJsb2JfaWQifX0=--8881a571beec96682ed7ce068b0bce560a7b7506/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJnaWYiLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--f10c96938b2eb90b26bf9400b408be14565a47ba/write-good-obsidian-2.gif"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;From a technical standpoint, I built it using TypeScript while leaning heavily on GitHub Copilot's new agent mode to figure out the gritty details of piecing together an Obsidian plugin.&lt;/p&gt;

&lt;p&gt;You can install it today by searching for 'Write Good' within Obsidian's community plugins or via &lt;a href="https://obsidian.md/plugins?id=write-good"&gt;Obsidian's plugin website&lt;/a&gt;. Its also &lt;a href="https://github.com/markahesketh/write-good-obsidian/"&gt;open source&lt;/a&gt;, of course.&lt;/p&gt;

&lt;h2&gt;Links:&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/markahesketh/write-good-obsidian/"&gt;GitHub repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://obsidian.md/plugins?search=write%20good"&gt;Plugin on the Obsidian plugin directory&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/btford/write-good"&gt;Write Good by Brian Ford&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


---

Originally published at [Introducing: Write Good, an Obsidian plugin](https://www.markhesketh.com/blog/write-good-obsidian-plugin) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/14</id>
    <published>2025-03-07T21:18:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/git-tips-and-tricks-i-use-every-day"/>
    <title>Git tips and tricks I use every day</title>
    <content type="html">&lt;p&gt;I am by no means an expert, but I've been using Git for years at this point. I've picked up some tips and tricks I use daily that I think could help you too.&lt;/p&gt;

&lt;h2&gt;1. Switching back to the previous branch&lt;/h2&gt;

&lt;p&gt;I swap between main/master, my feature branch and back to main/master constantly. Rather than typing out the name of branch you want to switch to, Git provides a nice alias to switch back to your previous branch:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;git switch -
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This might look familiar as it mirrors &lt;code&gt;cd -&lt;/code&gt; which navigates to your previous directory in the terminal in the same way.&lt;/p&gt;

&lt;p&gt;I use this all the time to ping pong between main/master and whatever feature branch I'm working on. For example:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git branch
* main

$ git checkout -b feature-branch
Switched to branch 'feature-branch'

$ git switch -
Switched to branch 'main'

$ git switch -
Switched to branch 'feature-branch'

$ git switch -
Switched to branch 'main'
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;2. Pushing to a remote branch of the same name&lt;/h2&gt;

&lt;p&gt;When working on a feature branch you'll often need to push your changes to a new remote branch before creating a PR.&lt;/p&gt;

&lt;p&gt;Typically, the remote branch has the same name as your local. Its tedious having to copy/paste (or god forbid type out) your branch name. What if there was a better way?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git push origin HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It doesn't matter how long or tedious your branch name is. It pushes and creates a branch on the remote using the same name as your local branch.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ git checkout -b feature-branch
Switched to a new branch 'feature-branch'

$ git push origin HEAD
...
To github.com:company-name/project-name.git
&amp;nbsp;* [new branch]&amp;nbsp; &amp;nbsp; &amp;nbsp; HEAD -&amp;gt; feature-branch
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I find this useful as at work we have conventions for branch names. They're often long and include ticket numbers, for example &lt;code&gt;feature/123456/great-new-feature-that-will-triple-revenue&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;HEAD&lt;/code&gt; I never have to care about the branch name. It works every time. In fact, I use an alias of &lt;code&gt;git poh&lt;/code&gt; on all my feature branches when pushing.&lt;/p&gt;

&lt;p&gt;Speaking of aliases...&lt;/p&gt;

&lt;h2&gt;3. Git aliases&lt;/h2&gt;

&lt;p&gt;Git allows you to specify aliases to effectively create your own Git commands.&lt;/p&gt;

&lt;p&gt;You probably have some shell aliases set up already, you might even have some aliases specific to Git. I prefer to use git aliases rather than shell aliases as they're scoped to Git and feel like real Git commands.&lt;/p&gt;

&lt;p&gt;To create one open up &lt;code&gt;~/.gitconfig&lt;/code&gt; and add your commands under the &lt;code&gt;[alias]&lt;/code&gt; section like so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;...
[alias]
    deploy = push production master
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a new command &lt;code&gt;git deploy&lt;/code&gt; which is as if you wrote &lt;code&gt;git push production master&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I have a bunch of these and I've &lt;a href="https://gist.github.com/markahesketh/f340af3f8dd87ec12c460e3f2c050ca4"&gt;published my .gitconfig to as a gist&lt;/a&gt; if you're looking for some inspiration. Some of my favourites are:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Cleans your working copy, resetting everything to the previous commit creating a blank slate. Stolen from Jeffrey Way 
nah = "!f() { git clean -d -f; git reset --hard; }; f"

# git status, but shorter
st = status -s

# Removes the last commit, but keeps the changes so you can make any changes or deletions
undo = reset HEAD~1 --mixed

# Unstages any changes
unstage = restore --staged
&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;4. Open the current project in GitHub&lt;/h2&gt;

&lt;p&gt;A couple of shell aliases (not git aliases) I like are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;gh&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ghu&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These open up the current directory's project in GitHub in the browser. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;gh&lt;/code&gt; opens the &lt;em&gt;origin&lt;/em&gt; remote and &lt;code&gt;ghu&lt;/code&gt; opens the &lt;em&gt;upstream&lt;/em&gt; remote, depending on whether I'm working on a fork or not.&lt;/p&gt;

&lt;p&gt;I find these useful when I'm working on a project and want to take a look at the GitHub issues or PRs.&lt;/p&gt;

&lt;p&gt;If you'd like to use them too, open up your shell's config or alias file (&lt;code&gt;~/.zshrc&lt;/code&gt;/&lt;code&gt;~/.bashrc/etc)&lt;/code&gt; and add the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function gh() {
&amp;nbsp; &amp;nbsp; local repo_url=`git remote get-url origin | sed -e 's/git@//' -e 's/.git//' -e 's/:/\//'`
    open "https://$repo_url"
}

function ghu() {
    local repo_url=`git remote get-url upstream | sed -e 's/git@//' -e 's/.git//' -e 's/:/\//'`
    open "https://$repo_url"
}
&lt;/code&gt;&lt;/pre&gt;


---

Originally published at [Git tips and tricks I use every day](https://www.markhesketh.com/blog/git-tips-and-tricks-i-use-every-day) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/13</id>
    <published>2025-02-03T23:02:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/introducing-rustywind-ruby"/>
    <title>Introducing: rustywind-ruby</title>
    <content type="html">&lt;p&gt;I'm thrilled to share my first published Ruby gem: &lt;a href="https://rubygems.org/gems/rustywind-ruby"&gt;rustywind-ruby&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Its a wrapper for &lt;a href="https://github.com/avencera/rustywind"&gt;RustyWind&lt;/a&gt;, a rust-based CLI utility for sorting Tailwind CSS classes. This makes it easier to use in Ruby and Rails #nobuild projects.&lt;/p&gt;

&lt;h2&gt;Why I built it&lt;/h2&gt;

&lt;p&gt;I've been using Tailwind CSS for a while and RustyWind keeps my utility classes predictable.&lt;/p&gt;

&lt;p&gt;Unfortunately, RustyWind is not available through RubyGems or bundler. Tailwind CSS itself recommends Prettier, an npm package, to sort CSS classes. Since I've been embracing importmaps and #nobuild recently this was a problem.&lt;/p&gt;

&lt;p&gt;As RustyWind is a small standalone binary, I used the &lt;code&gt;bin/setup&lt;/code&gt; script to import it. This worked, but it didn't feel great having a dependency outside of my Gemfile.&lt;/p&gt;

&lt;p&gt;I decided to follow the lead of the &lt;a href="https://github.com/flavorjones/tailwindcss-ruby"&gt;tailwind-ruby&lt;/a&gt; project,  building a small wrapper around the RustyWind binaries. This allows bundler and your Gemfile to manage it like any other dependency.&lt;/p&gt;

&lt;p&gt;It was also the perfect scope for my first gem.&lt;/p&gt;

&lt;h2&gt;How to use it&lt;/h2&gt;

&lt;p&gt;via bundler:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle add rustywind-ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;or without:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;gem install rustywind-ruby
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then use RustyWind via &lt;code&gt;bundler exec&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;bundle exec rustywind
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Personally, I run RustyWind as part of a &lt;code&gt;bin/check&lt;/code&gt; script alongside other actions such as tests, linters, and audits.&lt;/p&gt;

&lt;h2&gt;Future plans&lt;/h2&gt;

&lt;p&gt;A future update will be to have GitHub Actions sync with the RustyWind upstream repo to keep versions up to date automatically.&lt;/p&gt;

&lt;p&gt;For now though, it works as expected.&lt;/p&gt;

&lt;p&gt;If it doesn't for you, let me know in the &lt;a href="https://github.com/markahesketh/rustywind-ruby/issues"&gt;GitHub Issues&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Links&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/markahesketh/rustywind-ruby"&gt;GitHub Repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://rubygems.org/gems/rustywind-ruby"&gt;Ruby Gems&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/avencera/rustywind"&gt;RustyWind&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


---

Originally published at [Introducing: rustywind-ruby](https://www.markhesketh.com/blog/introducing-rustywind-ruby) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/1</id>
    <published>2020-02-09T00:00:00Z</published>
    <updated>2025-09-10T20:49:48Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/switching-multiple-php-versions-on-macos"/>
    <title>Switching between multiple PHP versions on macOS</title>
    <content type="html">&lt;p&gt;I recently needed to switch between PHP versions on my macOS environment to work on a legacy project.&lt;/p&gt;

&lt;p&gt;As usual, I’d forgotten how to do this, so I’ve decided to publish the steps for my own and other’s reference.&lt;/p&gt;

&lt;p&gt;The instructions below are for use with macOS 10.15 Catalina, and allow installation of PHP 5.6, 7.0, 7.1, 7.2, 7.3 &amp;amp; 7.4.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzM5P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--68f4f0217d921d15e76f29e73b872b708eebf983" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzksInB1ciI6ImJsb2JfaWQifX0=--520061ca3e40d6021945c6608e85bd1e77a21e35/image.png" filename="image.png" filesize="379146" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzksInB1ciI6ImJsb2JfaWQifX0=--520061ca3e40d6021945c6608e85bd1e77a21e35/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;h2&gt;1. Prerequisites&lt;/h2&gt;

&lt;p&gt;You’ll need both Xcode Command Line Tools and &lt;a href="https://brew.sh"&gt;Homebrew&lt;/a&gt; installed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.1 Install XCode Command Line Tools&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;xcode-select --install
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;1.2 Install Homebrew&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://brew.sh"&gt;Homebrew&lt;/a&gt; is a package manager for macOS. It’s like &lt;code&gt;apt&lt;/code&gt; on Ubuntu.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Check that brew has installed:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ brew --version
Homebrew 2.2.5
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can also run &lt;code&gt;brew doctor&lt;/code&gt; to check everything is good to go.&lt;/p&gt;

&lt;h2&gt;2. Install Multiple PHP Versions&lt;/h2&gt;

&lt;p&gt;As of writing, &lt;strong&gt;only PHP 7.2, 7.3 and 7.4 are maintained&lt;/strong&gt; and supported by Homebrew.&lt;/p&gt;

&lt;p&gt;To &lt;strong&gt;install PHP 5.6, 7.0 &amp;amp; 7.1&lt;/strong&gt; we’ll need to ‘tap’ a repository for deprecated packages:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;brew tap exolnet/homebrew-deprecated
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now, we can install all the available PHP versions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;brew install php@5.6
brew install php@7.0
brew install php@7.1
brew install php@7.2
brew install php@7.3
brew install php@7.4
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This may take a little time to install. Go make yourself a brew ☕️.&lt;/p&gt;

&lt;h2&gt;3. Switching between PHP versions&lt;/h2&gt;

&lt;p&gt;Once installed, you can switch between PHP versions by ‘linking’ and ‘unlinking’ in brew:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Switch from 7.4 to 5.6
brew unlink php@7.4
brew link php@5.6 --force
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;lt;!-- IMAGE&lt;em&gt;PLACEHOLDER&lt;/em&gt;1 --&amp;gt;.png)&lt;/p&gt;

&lt;p&gt;You can combine &lt;code&gt;brew unlink&lt;/code&gt; and &lt;code&gt;brew link&lt;/code&gt; to swap between any installed version.&lt;/p&gt;

&lt;h2&gt;Open Source Alternatives&lt;/h2&gt;

&lt;p&gt;There are a few open source projects that aim to automate this for you, if you prefer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://phpbrew.github.io/phpbrew/"&gt;phpbrew/phpbrew&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/philcook/brew-php-switcher"&gt;philcook/brew-php-switcher&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


---

Originally published at [Switching between multiple PHP versions on macOS](https://www.markhesketh.com/blog/switching-multiple-php-versions-on-macos) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/2</id>
    <published>2020-02-04T00:00:00Z</published>
    <updated>2025-09-10T20:49:48Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/bin-scripts"/>
    <title>Embrace bin scripts</title>
    <content type="html">&lt;p&gt;I recently watched Matt Stauffer’s talk “&lt;a href="https://www.youtube.com/watch?v=enTb2E4vEos"&gt;Patterns That Pay Off&lt;/a&gt;” from Laracon 2018. It’s packed with great advice that I’ve been bringing into my own projects.&lt;/p&gt;

&lt;p&gt;One piece of advice I’d like to highlight is the use of project-based bin scripts.&lt;/p&gt;

&lt;h2&gt;Whats the problem?&lt;/h2&gt;

&lt;p&gt;Have you ever had a project that hasn’t seen active development in years but now needs a small update.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Where do I get Bower from these days?”&lt;/li&gt;
&lt;li&gt;“What is a PEAR package?”&lt;/li&gt;
&lt;li&gt;“How do I deploy to Rackspace?”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That quick CSS fix has become a much bigger headache.&lt;/p&gt;

&lt;p&gt;Or, a typical PHP Laravel project a local setup might involve these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Switch to PHP 7.4&lt;/li&gt;
&lt;li&gt;Install PHP dependencies via Composer&lt;/li&gt;
&lt;li&gt;Switch to Node v12.7&lt;/li&gt;
&lt;li&gt;Install frontend dependencies via NPM&lt;/li&gt;
&lt;li&gt;Start local PHP web server&lt;/li&gt;
&lt;li&gt;Start webpack build system&lt;/li&gt;
&lt;li&gt;Start a MySQL service&lt;/li&gt;
&lt;li&gt;Copy &lt;code&gt;.env&lt;/code&gt; variables&lt;/li&gt;
&lt;li&gt;Run database migrations and seeders&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Thats a lot of steps to remember or fit into your readme, and thats assuming the developer reads the readme at all!&lt;/p&gt;

&lt;h2&gt;Whats the solution?&lt;/h2&gt;

&lt;p&gt;What if &lt;em&gt;all&lt;/em&gt; your projects had these steps encapsulated in a single &lt;code&gt;bin/install.sh&lt;/code&gt; script.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzQxP2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--a7656169c0beeb6098d5141503517c6362fa8ee8" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDEsInB1ciI6ImJsb2JfaWQifX0=--ecdc0761767425de9efd80c81c162a3270f06ded/bin-scripts.png" filename="bin-scripts.png" filesize="625596" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDEsInB1ciI6ImJsb2JfaWQifX0=--ecdc0761767425de9efd80c81c162a3270f06ded/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/bin-scripts.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;This script could perform the installation steps and check for project requirements. It could also handle the nuances between macOS, Linux or Windows dev environments.&lt;/p&gt;

&lt;p&gt;It doesn’t matter if you are working on a PHP, Node or static web app – you &lt;code&gt;cd&lt;/code&gt; into the project and run &lt;code&gt;./bin/install.sh&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once you’re ready to commit, run &lt;code&gt;./bin/precommit.sh&lt;/code&gt; to run your tests, static analysis, and formatting.&lt;/p&gt;

&lt;p&gt;Finally, run &lt;code&gt;./bin/deploy.sh&lt;/code&gt; to build production assets, update release notes and deploy. How you deploy that particular project doesn’t matter. Docker? Digital Ocean? Heroku? Who cares!&lt;/p&gt;

&lt;h2&gt;What are the alternatives? Docker? Composer?&lt;/h2&gt;

&lt;p&gt;You might be thinking &lt;em&gt;“this is the sort of thing Docker and CI solves!”&lt;/em&gt; or &lt;em&gt;“can I not just use composer/npm scripts?”&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Docker can standardise your build steps – but not every project needs Docker. I have several projects where Docker would be overkill. For example, sites built using static site generators.&lt;/p&gt;

&lt;p&gt;A Docker-based app can still make use of bin scripts. If only to wrap &lt;code&gt;docker-compose up&lt;/code&gt; in the familiar &lt;code&gt;bin/run.sh&lt;/code&gt; script.&lt;/p&gt;

&lt;p&gt;Similarly, a PHP project may not even use Composer – such as a typical WordPress website.&lt;/p&gt;

&lt;p&gt;By embracing bin scripts, it doesn’t matter what an individual project’s tech stack is. The interface to install, run and deploy is the same across all your projects.&lt;/p&gt;

&lt;p&gt;Most importantly, shell scripts will run out of the box on macOS, Linux and Windows in almost all cases.&lt;/p&gt;

&lt;h2&gt;Show me the code!&lt;/h2&gt;

&lt;p&gt;I have a &lt;code&gt;bin&lt;/code&gt; directory in my project root which contains my bin scripts. It looks something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$ tree bin
bin
├── install
├── run
└── precommit
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each script is self-contained and includes everything it needs to run. Because of this, they’ll can work in many years from the first &lt;code&gt;git clone&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, one of my PHP Laravel apps has the following &lt;code&gt;bin/install.sh&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash

# bin/install
# Install the application

command_exists() {
    command -v "$@" &amp;gt; /dev/null 2&amp;gt;&amp;amp;1
}

if ! command_exists fnm; then
    echo "fnm is not installed"
    echo "Visit https://github.com/Schniz/fnm to install"
    exit
fi

if ! command_exists composer; then
    echo "composer is not installed"
    echo "Visit https://getcomposer.org/download/ to install"
    exit
fi

if ! command_exists yarn; then
    echo "yarn is not installed"
    echo "Visit https://yarnpkg.com/lang/en/docs/install/ to install"
    exit
fi

echo "Removing existing ./node_modules folder"
rm -rf ./node_modules
echo "Removing existing ./vendor folder"
rm -rf ./vendor

fnm use
composer install
yarn install

cp .env.example .env
php artisan key:generate
php artisan migrate:fresh --seed
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;bin/run.sh&lt;/code&gt; script as as follows:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash

# bin/run
# Run the local development environment

if [[ "$OSTYPE" == "linux"* ]]; then
    sudo service mysql start
fi

php -S 0.0.0.0:8000 -t public/ &amp;amp; yarn run watch
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and finally, this is the &lt;code&gt;bin/precommit.sh&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash

# bin/precommit
# Tasks to run pre-comment

php ./vendor/bin/phpunit
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The scripts do not need overcomplicating, and can simply be a list of commands. The &lt;code&gt;bin/precommit.sh&lt;/code&gt; script only runs my test suite and nothing more.&lt;/p&gt;

&lt;p&gt;Crucially, it holds up across all my projects spanning years the tech stacks of their time.&lt;/p&gt;

&lt;p&gt;Laravel? WordPress? Static? No problem.&lt;/p&gt;

&lt;p&gt;Nice!&lt;/p&gt;

&lt;h2&gt;Creating your own&lt;/h2&gt;

&lt;p&gt;I can offer some final words of encouragement, if you’re interested in creating your own.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Start small&lt;/strong&gt;. Don’t worry about adding support for Windows environments if you only ever use macOS. Add as you need.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Not everything needs scripting&lt;/strong&gt;. A printed message to direct the user could be enough.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep it simple&lt;/strong&gt;. There’s a temptation to create abstractions from your scripts. Resist adding complexity, duplication is not always a bad thing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create aliases.&lt;/strong&gt; &lt;a href="https://github.com/markahesketh/dotfiles/blob/master/home/.aliases"&gt;I’m a big fan of aliases&lt;/a&gt; and saving a keystroke. Once you’ve settled on your script names, you can alias them for even more convenience.&lt;/li&gt;
&lt;/ul&gt;


---

Originally published at [Embrace bin scripts](https://www.markhesketh.com/blog/bin-scripts) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/3</id>
    <published>2020-01-08T00:00:00Z</published>
    <updated>2025-09-10T20:49:48Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/2020-plans-goals"/>
    <title>2020: Plans &amp; goals</title>
    <content type="html">&lt;p&gt;Last week I &lt;a href="https://www.markhesketh.com/2019-year-in-review/"&gt;wrote a retrospective on how I felt 2019 went&lt;/a&gt;. Today, the Christmas tree came down, the country went back at work and I’m looking ahead to my plans for 2020.&lt;/p&gt;

&lt;h2&gt;Writing&lt;/h2&gt;

&lt;p&gt;One of my main takeaways from 2019 was that I simply didn’t write enough even though &lt;a href="https://www.markhesketh.com/writing-about-thinking-about-writing/"&gt;I’d planned to&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Over the past 5 years I’ve got into an infinite loop with my blog, which goes something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Decide I want to start blogging again&lt;/li&gt;
&lt;li&gt;Make a Trello board&lt;/li&gt;
&lt;li&gt;Scribble down some topic ideas&lt;/li&gt;
&lt;li&gt;Redesign and redeploy blog onto a new platform, infrastructure etc&lt;/li&gt;
&lt;li&gt;Become dissatisfied before writing a single post and move onto something else&lt;/li&gt;
&lt;li&gt;Repeat 18 months later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’m taking a pragmatic approach and sticking with WordPress, the theme, the hosting – the lot, and writing some bloody posts.&lt;/p&gt;

&lt;p&gt;I’ve got some big projects planned for 2020, and I want to share everything I learn, both here and on &lt;a href="https://twitter.com/markahesketh"&gt;Twitter&lt;/a&gt;. I may also cross-post to communities such as &lt;a href="https://dev.to"&gt;dev.to&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Projects 👨‍💻&lt;/h2&gt;

&lt;p&gt;As mentioned, I’ve got a few personal projects lined up for this year, alongside my day job.&lt;/p&gt;

&lt;h3&gt;Laravel E-commerce Applications&lt;/h3&gt;

&lt;p&gt;I’ve embarked on an overly ambitious journey to build a couple of e-commerce applications.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzQyP2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--d31f1b9a6ee875ebb0fc4c6af6dee6faeab7fc42" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDIsInB1ciI6ImJsb2JfaWQifX0=--0b5c68a302908c63ac7f6d15481dd6d9cadd3d09/laravel.png" filename="laravel.png" filesize="13690" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDIsInB1ciI6ImJsb2JfaWQifX0=--0b5c68a302908c63ac7f6d15481dd6d9cadd3d09/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/laravel.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Rather than picking up an off-the-shelf e-commerce platform, I’ll be building them from scratch using Laravel. This has drawn some chuckles and skepticism from some of my colleagues, but I am undeterred! I have quite a few reasons for this which I’ll attempt to justify in a series of posts.&lt;/p&gt;

&lt;p&gt;The e-commerce stores are for my girlfriend’s business, selling hand-made jewellery.&lt;/p&gt;

&lt;p&gt;I built the original store in 2011 using PrestaShop, a PHP-based e-commerce platform, followed by a 2015 redesign. Now its time for refresh and at least one additional store, armed with everything we’ve learnt since.&lt;/p&gt;

&lt;p&gt;This is a nights and weekends project, and for now is built for purpose to minimise the scope – but there’s definitely potential to extract some open-source packages along the way. As mentioned, I will also write about its progress, decisions made and lessons learnt.&lt;/p&gt;

&lt;h3&gt;Proudly Powered&lt;/h3&gt;

&lt;p&gt;I registered &lt;a href="https://www.proudlypowered.com"&gt;proudlypowered.com&lt;/a&gt; in 2012 while freelancing and primarily building on WordPress.&lt;/p&gt;

&lt;p&gt;The name is a reference to &lt;em&gt;“Proudly powered by WordPress”&lt;/em&gt; seen in the footers of WordPress-based websites, and I’ve always liked it. However, I moved away from WordPress soon after registering the domain and never did much with it.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzQzP2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--cd732c2f0ad97a015f262d5faa01f55a01cadcd8" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDMsInB1ciI6ImJsb2JfaWQifX0=--c5525ce3cc4bfe8e43bd74916e98924537bb8f40/wordpress.png" filename="wordpress.png" filesize="39043" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDMsInB1ciI6ImJsb2JfaWQifX0=--c5525ce3cc4bfe8e43bd74916e98924537bb8f40/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/wordpress.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;I’m not planning a return to WordPress professionally but I am actively using it for this website. In doing so, I expect to open-source any custom themes, plugins and tools that I build under the Proudly Powered name.&lt;/p&gt;

&lt;p&gt;In addition to my own work, it may also recommend plugins, themes and techniques by other developers that are of high quality should be highlighted.&lt;/p&gt;

&lt;p&gt;It could be a single page website, it may be more. I haven’t decided. Regardless, I’d like it to be a legitimate reference for developers who take pride in their work, have an eye for quality and choose to build on WordPress.&lt;/p&gt;

&lt;h2&gt;Guitar 🎸&lt;/h2&gt;

&lt;p&gt;I’d like to adopt more hobbies outside of programming and computers, revisiting some of the things I enjoyed before getting deep into web development.&lt;/p&gt;

&lt;p&gt;I played guitar through my teens, barely above beginner level, but I really enjoyed playing along to bands in my bedroom. Much to my brother’s discomfort.&lt;/p&gt;

&lt;p&gt;Before Christmas I dusted off my Epiphone Les Paul that I bought in 2004 with money saved working in a local pub kitchen, and set myself a challenge to learn a full album.&lt;/p&gt;

&lt;p&gt;Not a single song, riff or solo, as I’m prone to do – but the full album.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzQ0P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--c65dd73dad0779bf1baa44e1d9d992e25644877a" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDQsInB1ciI6ImJsb2JfaWQifX0=--6ce487a93103b2d75912f252952b275f2c0585ed/the-killers.png" filename="the-killers.png" filesize="207666" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDQsInB1ciI6ImJsb2JfaWQifX0=--6ce487a93103b2d75912f252952b275f2c0585ed/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/the-killers.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;The album I’ve picked is Killers – Hot Fuss, for a few reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I like every song on the album&lt;/li&gt;
&lt;li&gt;It seems achievable at my skill level, with a few tricky ones thrown in to make it a challenge&lt;/li&gt;
&lt;li&gt;It gives me an excuse to learn &lt;a href="https://www.youtube.com/watch?v=gGdGFtwCNBE"&gt;the anthem of my generation&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;And the rest&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Complete ‘Dry January’. Christmas was heavily indulged. 🍻&lt;/li&gt;
&lt;li&gt;Make 2020 the year we buy our first home&lt;/li&gt;
&lt;li&gt;Attend at least one PHP / Laravel conference or local meetup&lt;/li&gt;
&lt;li&gt;Record a screencast&lt;/li&gt;
&lt;li&gt;Watch Burnley FC maintain their Premier League status 😬&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s to a great 2020!&lt;/p&gt;


---

Originally published at [2020: Plans &amp; goals](https://www.markhesketh.com/blog/2020-plans-goals) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/4</id>
    <published>2019-12-31T00:00:00Z</published>
    <updated>2025-09-10T20:49:48Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/2019-year-in-review"/>
    <title>2019: Year in review</title>
    <content type="html">&lt;p&gt;I wasn’t planning to do any sort of recap of the year, but at the time of writing its New Years Eve and the end of a decade no less – so I thought I’d give this a whirl.&lt;/p&gt;

&lt;h2&gt;Projects&lt;/h2&gt;

&lt;p&gt;I &lt;a href="https://www.markhesketh.com/writing-about-thinking-about-writing/"&gt;wrote in 2018&lt;/a&gt; about an ‘ambitious’ Laravel-based e-commerce platform I was planning to build. Unfortunately, thats been a bust so far. I submitted to analysis paralysis and have tried every e-commerce platform under the sun, only to land right back where I began – creating my own with Laravel.&lt;/p&gt;

&lt;p&gt;This project was born out of the need for a new e-commerce store for my better half, who sells hand-crafted jewellery online through a PrestaShop store I built for her in 2014.&lt;/p&gt;

&lt;p&gt;Its become a little bit of an on running joke at work, but I’ve learnt a lot along the way and am now convinced its the right approach. I expect this project to be a significant part of my 2020, and launch at least a couple of stores off the back of it.&lt;/p&gt;

&lt;h2&gt;Work&lt;/h2&gt;

&lt;p&gt;I’ve not written about my job on this blog before, but as a quick catch-up I joined &lt;a href="https://www.venditan.com"&gt;Venditan&lt;/a&gt; in 2015 as a mid-level developer, became a senior developer in 2017 and have been a team lead since 2018. I lead a small team working exclusively for a single client.&lt;/p&gt;

&lt;p&gt;In 2019 my role has shifted a little more towards team management, mentoring and client-facing responsibilities, with a slightly less emphasis on actual development than previous years. Its a role I generally enjoy, although I’ll be looking to get back more involved with the technical direction of the team next year.&lt;/p&gt;

&lt;p&gt;Our team has launched a number of e-commerce stores, large projects and integrations within our closed-source e-commerce platform for my client. While I can’t go into detail, I’m very proud of the work we’ve achieved and the roadmap we have for 2020.&lt;/p&gt;

&lt;p&gt;I’ve also taken on a bit of personal project to jumpstart our internal documentation using an open-source Laravel project called &lt;a href="https://www.bookstackapp.com/"&gt;BookStack&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Learning&lt;/h2&gt;

&lt;p&gt;I’ve spent a significant amount of time learning new technologies, but not writing about them 🧐.&lt;/p&gt;

&lt;p&gt;My day job mostly involves PHP development on a large legacy (read: profitable) Zend 1 application, although our infrastructure is very ‘2019’ with multiple Kubernetes clusters and a few React Native apps, so there is a lot to keep on top of.&lt;/p&gt;

&lt;p&gt;Outside of my day job though I’ve been dabbling with the Laravel ecosystem to create the e-commerce platform mentioned earlier. In doing so, I’ve discovered:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://laravel.com/"&gt;Laravel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tailwindcss.com/"&gt;Tailwind CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://laravel-livewire.com/"&gt;Livewire&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/alpinejs"&gt;AlpineJS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tailwind in particular has been a surprising discovery, and goes against almost everything CSS Zen Garden and .NET magazine taught me when I was getting into web development – but its been a lightbulb moment for me.&lt;/p&gt;

&lt;p&gt;I could write at length about each of the above, but it feels like I can achieve just about anything with these 4 tools, and I’m excited to double down on them in 2020.&lt;/p&gt;

&lt;h2&gt;Writing&lt;/h2&gt;

&lt;p&gt;F. Must try harder. See me after class.&lt;/p&gt;

&lt;p&gt;This is literally the only blog post I’ve written in 2019. Ironically my last post is a post about how I’m going to write more. I aim to fix this in 2020 and beyond, which &lt;a href="https://www.markhesketh.com/2020-plans-goals/"&gt;I’ve talked about in a follow-up post.&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;And the rest&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I discovered &lt;a href="https://www.youtube.com/watch?v=AXAGF7L9wP8"&gt;Retrowave&lt;/a&gt; playlists on YouTube and Spotify. They’ve been ideal tracks to have on in my headphones as I work.&lt;/li&gt;
&lt;li&gt;My &lt;a href="http://robhesketh.co.uk/"&gt;older brother&lt;/a&gt; bought me a &lt;a href="https://dnd.wizards.com/products/tabletop-games/rpg-products/rpg_starterset"&gt;DND: Starter Edition&lt;/a&gt; set last christmas, and the family (including my mum) have been getting together fairly regularly to play. Its been a surprising amount of fun and a good way to spend a Friday evening!&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/markahesketh/status/1208526693725622274"&gt;I’ve toyed with WSL2 to re-create my MacOS development environment on Windows&lt;/a&gt;. Its suprisingly close and I’ll blog about it in the future.&lt;/li&gt;
&lt;li&gt;I’m a fair weather runner but beat a number of personal bests from previous years.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://worldofwarcraft.com/en-us/wowclassic"&gt;World of Warcraft: Classic&lt;/a&gt; was released, which made up a decent part of my teens – but it quickly became apparent you can never ‘go back’ and I’m okay with it.&lt;/li&gt;
&lt;li&gt;I’ve been &lt;a href="https://imgur.com/a/B8EU7kH"&gt;tinkering with game development in Unreal Engine 4&lt;/a&gt;. Its been a nice creative outlet, and has opened up doors to 3D modelling in Blender and texture painting with Sustance Painter.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;More?&lt;/h2&gt;

&lt;p&gt;You should read some other ‘2019 review’ posts by these smarter and more handsome people:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://bobbybouwmann.nl/blog/year-in-review-2019"&gt;Bobby Bouwwmann – Year in review: 2019&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sebastiandedeyne.com/newsletter/happy-holidays-looking-back-at-2019/"&gt;Sebastian De Deyne – Happy Holidays! Looking back at 2019&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://davidllop.com/posts/year-retrospective-2019"&gt;David Llop – My Year’s Retrospective 2019&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://adamwathan.me/journal/2019/12/06/2019-year-in-review/"&gt;Adam Wathan – 2019 Year in Review&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


---

Originally published at [2019: Year in review](https://www.markhesketh.com/blog/2019-year-in-review) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/5</id>
    <published>2018-03-05T00:00:00Z</published>
    <updated>2025-09-10T20:49:48Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/writing-about-thinking-about-writing"/>
    <title>Writing about thinking about writing</title>
    <content type="html">&lt;p&gt;Over the weekend I had a realisation. For years I’ve had the best intentions of keeping a blog, but I never actually wrote it.&lt;/p&gt;

&lt;p&gt;Since this website went live several years back, its been rebuilt half a dozen times, from WordPress, to Symphony CMS, to Jekyll, back to WordPress and so on. I’ve been a freelancer, a contractor, and now a full-time employee. I’ve switched disciplines from designer, to front-end developer, to back-end developer. My workflow has progressed from MAMP to Docker, Dreamweaver to PhpStorm, WordPress to Laravel and jQuery to React.&lt;/p&gt;

&lt;p&gt;In all that time I’ve written very little. Plenty of drafts but rarely published. I look back at the techniques, tools and technologies I’ve learnt and wish I’d posted more. Rather than write, I’d start a new project, re-build this website, learn a new tool.&lt;/p&gt;

&lt;p&gt;I meant to write about it, I just didn’t.&lt;/p&gt;

&lt;p&gt;Posts published in 2017: 1 (one). Good stuff.&lt;/p&gt;

&lt;p&gt;I’m changing that. No, really this time! Honest. I’m going to start writing without pressure or expectation. I’m going to blog like its 2005.&lt;/p&gt;

&lt;p&gt;Adam Wathan, a developer I follow in the PHP community, &lt;a href="https://twitter.com/adamwathan/status/962873265139011584"&gt;recently tweeted&lt;/a&gt;&lt;br&gt;
that he has been using Basecamp’s ‘Automatic Check-in’ feature to keep a work journal and keep himself focused. Its a technique&lt;a href="https://medium.com/let-me-repost-that-for-you-zeldman/automatic-check-ins-and-the-old-personal-web-11eab7f5588d"&gt; Jeffrey Zeldman has also written about&lt;/a&gt;. I plan to do this too, but in public on this blog.&lt;/p&gt;

&lt;p&gt;Future projects I’m working on, such as the ambitious Laravel-based e-commerce store I’m planning, I will write about. Any techniques I come across along the way, I’ll write about them too. I’ll write as much as possible for my own benefit and if others find these posts helpful then even better!&lt;/p&gt;

&lt;p&gt;In the mean time, this is me writing about writing, but I’m happy to actually be doing it.&lt;/p&gt;


---

Originally published at [Writing about thinking about writing](https://www.markhesketh.com/blog/writing-about-thinking-about-writing) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/6</id>
    <published>2017-09-20T00:00:00Z</published>
    <updated>2025-09-10T20:49:48Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/your-readme-is-important"/>
    <title>Your README is important</title>
    <content type="html">&lt;p&gt;Good documentation is very important and expected of open-source projects.&lt;/p&gt;

&lt;p&gt;We should hold our private projects to the same standard. The &lt;code&gt;README&lt;/code&gt; is not a &lt;code&gt;@todo&lt;/code&gt;. It should be available and up to date, even if only for our own benefit.&lt;/p&gt;

&lt;h2&gt;But why?&lt;/h2&gt;

&lt;p&gt;It might sound like a waste of time to document something you’ve made for yourself but you’d be mistaken.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The faintest ink is more powerful than the strongest memory.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve lost count of the number of times I’ve picked up an old client’s project and been thankful I’d included a &lt;code&gt;README.md&lt;/code&gt;. I’d taken the 5 minutes to document the setup steps, and can now onboard myself even several years later. Instead of trying to remember my workflow of years gone by, the instructions are right there.&lt;/p&gt;

&lt;p&gt;What seems obvious now, may not be later.&lt;/p&gt;

&lt;h3&gt;Practice makes perfect&lt;/h3&gt;

&lt;p&gt;Writing concise documentation is a worthwhile skill and you should practice whenever possible. Using the documentation on your personal projects is the perfect opportunity.&lt;/p&gt;

&lt;p&gt;This practice will benefit you and others when documenting public or team projects.&lt;/p&gt;

&lt;p&gt;Good documentation can be the difference between a project succeeding or not. Personally, I’ll skip any project that does not have clear and concise documentation.&lt;/p&gt;

&lt;p&gt;Hone your documentation skills and give personal projects their best chance to succeed.&lt;/p&gt;

&lt;h2&gt;Where to start?&lt;/h2&gt;

&lt;p&gt;Dig into your projects folder, find a project that is missing a &lt;code&gt;README.md&lt;/code&gt; and get to work. Your future-self will thank you.&lt;/p&gt;

&lt;p&gt;For tips on writing your README, refer to Eric Barnes’ great article on &lt;a href="https://m.dotdev.co/how-to-write-a-readme-that-rocks-bc29f279611a"&gt;how to write a README that rocks&lt;/a&gt;.&lt;/p&gt;


---

Originally published at [Your README is important](https://www.markhesketh.com/blog/your-readme-is-important) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/7</id>
    <published>2012-04-12T00:00:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/portfolio-1-1"/>
    <title>Portfolio 1.1</title>
    <content type="html">&lt;p&gt;At the tail end of January this year I &lt;a href="http://www.markhesketh.co.uk/blog/portfolio-goes-live/"&gt;finally launched this website&lt;/a&gt; as my portfolio.&lt;/p&gt;

&lt;p&gt;The original launch was a personal milestone, not only because I’d had this domain for 4 years prior to putting anything worthwhile online, but mostly because I learnt a lot.&lt;/p&gt;

&lt;p&gt;I’d learnt to &lt;a href="http://www.markhesketh.co.uk/blog/linode"&gt;configured my own VPS with Linode&lt;/a&gt;, picked up &lt;a href="http://www.markhesketh.co.uk/blog/symphony-cms-nginx-rewrite-rules"&gt;nginx rather than Apache&lt;/a&gt;, discovered &lt;a href="http://www.markhesketh.co.uk/blog/symphony-cms"&gt;Symphony CMS&lt;/a&gt; over &lt;a href="http://www.markhesketh.co.uk/blog/replacing-wordpress"&gt;WordPress&lt;/a&gt; (for this project at least), tried my hand at responsive web design, and experimented with &lt;a href="http://lesscss.org/"&gt;LESS&lt;/a&gt; on a live website.&lt;/p&gt;

&lt;p&gt;Since then, I’ve found there were little details I just wasn’t happy with.&lt;/p&gt;

&lt;h2&gt;Version 1.1&lt;/h2&gt;

&lt;p&gt;Bits of the previous design were simply too loose with occasional artifacts of ideas I’d had and later rejected. The typography in blog posts was difficult to read at times too, which was worrying.&lt;/p&gt;

&lt;p&gt;Additionally the CSS was, quite frankly, terrible. As I mentioned I was getting to grips with reponsive design as well as LESS, and this could all be done better.&lt;/p&gt;

&lt;p&gt;Early evening on Friday I decided to start again.&lt;/p&gt;

&lt;p&gt;I’d designed the January layout using in Fireworks. I had the ‘basic look’ of my design already, so this time I did everything in browser.&lt;/p&gt;

&lt;p&gt;I’m now much more familiar with LESS. Built my own grid.less loosely based on &lt;a href="http://semantic.gs/"&gt;semantic.gs&lt;/a&gt;, various LESS mixins for typography and structure, and it was all very painless.&lt;/p&gt;

&lt;p&gt;I was able to redesign the entire website in an evening. The markup was already in place (with a few changes here and there), and I’ve become quite fond of &lt;a href="http://www.markhesketh.co.uk/blog/symphony-cms"&gt;Symphony CMS&lt;/a&gt; so no need to rebuild the CMS.&lt;/p&gt;

&lt;p&gt;The final result in my opinion is much better.&lt;/p&gt;

&lt;h2&gt;What next?&lt;/h2&gt;

&lt;p&gt;I intend on writing some posts on what I’ve learnt over the last 3 months which led to the redesign, such as my better understand of LESS and responsive web design.&lt;/p&gt;

&lt;p&gt;As before, there’s still stuff to do here. The responsiveness of the website is by no means perfect, in fact, its not finished.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The best time to start was last year. Failing that, today will do.&lt;br&gt;
&lt;a href="http://chrisguillebeau.com/"&gt;Chris Guillebeau&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I’ve become a big believer of &lt;a href="http://ma.tt/2010/11/one-point-oh/"&gt;getting it shipped&lt;/a&gt;. Thats what I did in January, so this redesign was probably inevitable.&lt;/p&gt;

&lt;p&gt;But this has meant at least I’ve had a portfolio online for 4 months, and it hasn’t been sat in my Dropbox unpublished as I’m too busy working on client projects.&lt;/p&gt;

&lt;p&gt;Looking forward to the next re-design in August.&lt;/p&gt;


---

Originally published at [Portfolio 1.1](https://www.markhesketh.com/blog/portfolio-1-1) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/8</id>
    <published>2012-02-24T00:00:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/proudly-powered"/>
    <title>Proudly Powered</title>
    <content type="html">&lt;p&gt;I recently wrote about how I was &lt;a href="http://www.markhesketh.co.uk/blog/replacing-wordpress/"&gt;replacing WordPress&lt;/a&gt; when it came to my personal projects, depending on the project.&lt;/p&gt;

&lt;p&gt;I also last month made the switch from WordPress to &lt;a href="http://www.markhesketh.co.uk/blog/symphony-cms"&gt;Symphony CMS&lt;/a&gt;, while &lt;a href="http://www.markhesketh.co.uk/blog/portfolio-goes-live"&gt;rebuilding my portfolio&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I have tonight launched my latest ‘project’, &lt;a href="http://proudlypowered.com/"&gt;Proudly Powered&lt;/a&gt;, another WordPress resource for writers and developers.&lt;/p&gt;

&lt;h2&gt;Just another WordPress site&lt;/h2&gt;

&lt;p&gt;The website, as you’d expect, will focus on regular blog posts related to WordPress such as news, tutorials and snippets.&lt;/p&gt;

&lt;p&gt;While I mentioned that I would be dropping WordPress as my ‘go to CMS’ I haven’t completely turned my back on it. It is of course a very nice tool.&lt;/p&gt;

&lt;h3&gt;Staying up to date&lt;/h3&gt;

&lt;p&gt;By regularly maintaining a WordPress site, which i no longer do as my portfolio is now using Symphony CMS, I’m able to stay in the loop regarding WordPress developments.&lt;/p&gt;

&lt;p&gt;This is of course very hand for my client work, in which WordPress driven websites are a common request, and so it’s good to be able to rely on first hand experience.&lt;/p&gt;

&lt;h3&gt;Shameless Plugging&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.twitter.com/#!/boagworld"&gt;Paul Boag&lt;/a&gt; makes no excuses about taking full advantage of his &lt;a href="http://boagworld.com/"&gt;popular web design blog&lt;/a&gt; to drive potential clients to &lt;a href="http://www.headscape.co.uk/"&gt;his business&lt;/a&gt;, this is no different.&lt;/p&gt;

&lt;p&gt;I hope that writing about WordPress will not only improve my knowledge and my content writing skills, but also potential generate interest in my &lt;a href="http://www.markhesketh.co.uk"&gt;web design work&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I’m not saying I will spamming the hell out of blog posts by any means, but getting some recognition is no ad thing.&lt;/p&gt;

&lt;h3&gt;Running websites, not building them&lt;/h3&gt;

&lt;p&gt;The simple fact is that it’s nice to actually be running a website of my own rather than building someone else’s. Running fan sites in my teens is what actually got me into Web Design.&lt;/p&gt;

&lt;p&gt;Using the many ‘best practice’ theories, from schemas to the latest and greatest CSS3 techniques on a production website I own is a real pleasure.&lt;/p&gt;

&lt;h2&gt;Lots to do&lt;/h2&gt;

&lt;p&gt;For now, the website is using the default Twenty Eleven theme… lazy I know.&lt;/p&gt;

&lt;p&gt;But as far as I’m concerned it’s a fully functioning, responsive WordPress theme that is not an eyesore (some may disagree, of course).&lt;/p&gt;

&lt;p&gt;By not fixating on the design or ‘brand’ I intend to jump write in with the content, and get things rolling and work on a design over time as the website grows into something.&lt;/p&gt;


---

Originally published at [Proudly Powered](https://www.markhesketh.com/blog/proudly-powered) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/9</id>
    <published>2012-02-09T00:00:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/symphony-cms"/>
    <title>Symphony CMS</title>
    <content type="html">&lt;p&gt;Following up on the new tools and techniques I’ve picked up recently while &lt;a href="http://www.markhesketh.co.uk/blog/portfolio-goes-live"&gt;putting my portfolio and blog live&lt;/a&gt; such as &lt;a href="http://www.markhesketh.co.uk/blog/linode"&gt;moving my hosting to Linode VPS&lt;/a&gt; and &lt;a href="http://www.markhesketh.co.uk/blog/replacing-wordpress"&gt;exploring alternative CMS systems&lt;/a&gt;, I’d like to introduce &lt;a href="http://www.symphony-cms.com/"&gt;Symphony CMS&lt;/a&gt;.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzE0P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--9947945219df2db52d2d56399756a77629f5f6d3" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTQsInB1ciI6ImJsb2JfaWQifX0=--4662624c250780cb8e29a9325c11c6c404049c0d/image.png" filename="image.png" filesize="32213" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTQsInB1ciI6ImJsb2JfaWQifX0=--4662624c250780cb8e29a9325c11c6c404049c0d/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Symphony CMS, as the name suggests, is an XLST powered open-source content management system that goes beyond allowing you to create and manage websites, but complete web applications.&lt;/p&gt;

&lt;p&gt;You could create a simple blog such as this to a bustling community website. You could even use it to power the data of an iOS app, or Flash website &lt;em&gt;(if you’re that way inclined)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As you might have guessed, this website is built upon Symphony, however this is a relatively basic implementation of what it is capable of.&lt;/p&gt;

&lt;p&gt;You can see more &lt;a href="http://symphony-cms.com/explore/showcase/"&gt;examples on the showcase&lt;/a&gt;, but I’d hastily remind you that you’re only limited by your own skills (design and coding) when it comes to developing with Symphony.&lt;/p&gt;

&lt;h2&gt;What is Symphony CMS?&lt;/h2&gt;

&lt;p&gt;Symphony is a CMS much like &lt;a href="http://wordpress.org/"&gt;WordPress&lt;/a&gt; and &lt;a href="http://expressionengine.com/"&gt;ExpressionEngine&lt;/a&gt;, but it wouldn’t be foolish to see similarities to frameworks such as &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; and &lt;a href="http://cakephp.org/"&gt;CakePHP&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There’s not many projects I could think of that Symphony wouldn’t be suitable for.&lt;/p&gt;

&lt;h3&gt;Symphony is open-source&lt;/h3&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzE1P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--4972ccf505d11f2e376610138f52aa331bd3af33" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTUsInB1ciI6ImJsb2JfaWQifX0=--8043eebaf396282846c0f15b8a341dd86d779cf3/image.png" filename="image.png" filesize="106518" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTUsInB1ciI6ImJsb2JfaWQifX0=--8043eebaf396282846c0f15b8a341dd86d779cf3/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Symphony is open-source. It is &lt;a href="http://symphony-cms.com/download/"&gt;freely available for you to download&lt;/a&gt;, and anything you build is entirely yours to distribute, sell or hide away as you see fit.&lt;/p&gt;

&lt;p&gt;You could create a ‘white label’ CMS for your agency built upon Symphony, tailored to your exact needs ready to use on client websites.&lt;/p&gt;

&lt;h3&gt;Lightweight&lt;/h3&gt;

&lt;p&gt;Being open-source also means that there is a large community drive in improving the software from core fixes and updates, to extending the software through &lt;a href="http://symphonyextensions.com/"&gt;Symphony extensions&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If it’s not essential, it’s an extension. This keeps the system small, lean, and precise. Swiss Army knives are nice, but a surgeon wouldn’t operate with one. With Symphony, you craft exactly the tool you need.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;‘Out of the box’ Symphony comes with just some basic features. The Symphony team take the view of ‘if it’s not essential, it’s an extension’. This is a real strength in my opinion, and is something thats been &lt;a href="http://www.markhesketh.co.uk/blog/replacing-wordpress"&gt;driving me away from WordPress&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This means that if you need a WYSIWYG Editor, its an extension. If you prefer to use &lt;a href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt;, thats an extension too. Neither? Don’t install any, keeping your website as agile as possible and not burdened by features you don’t need.&lt;/p&gt;

&lt;h3&gt;XSLT and XML driven&lt;/h3&gt;

&lt;p&gt;Symphony driven websites are built upon XLST and XML, an open-standard templating language &lt;a href="http://www.w3.org/TR/xslt"&gt;developed by the W3C&lt;/a&gt; that includes everything you need such as conditionals, parameters and functions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;XSLT (Extensible Stylesheet Language Transformations) is a declarative, XML-based language used for the transformation of XML documents.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is great news as you needn’t learn &lt;strong&gt;&lt;em&gt;even more&lt;/em&gt;&lt;/strong&gt; custom template tags from a new CMS, instead you learn a &lt;strong&gt;transferrable skill&lt;/strong&gt; in XSLT.&lt;/p&gt;

&lt;p&gt;Using XSLT you can output your XML content to any format you wish, be it standard (x)HTML, HTML5, RSS/Atom feeds to PDF documents and SVG spreadsheets. Symphony is capable of driving the content behind near limitless types of formats and applications.&lt;/p&gt;

&lt;p&gt;There’s a wealth of information regarding XSLT, but I’d recommend &lt;a href="http://symphony-cms.com/learn/tutorials/beginners/"&gt;Symphony’s Tutorials&lt;/a&gt; or &lt;a href="http://designprojectx.com/"&gt;Stephen Bau’s DesignProjectX&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;Symphony CMS Features&lt;/h2&gt;

&lt;h3&gt;No assumptions&lt;/h3&gt;

&lt;p&gt;Symphony is built on ‘&lt;a href="http://symphony-cms.com/explore/open-architecture/"&gt;Open Architecture&lt;/a&gt;‘ and doesn’t dictate what kind of content it’ll manage.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Symphony doesn’t tell you what kind of content to manage, or how. It doesn’t lock you into a rigid structure or dictate some silly URL schema. It just gives you the tools and stays out of your way. Trust us, you’ll like it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Symphony is not ‘page based’ like a lot of CMS’s you may be used to. It makes no assumptions about your content. It doesn’t insist on there being a title, nor does it expect to it to have it’s own ‘page’ or even appear on the ‘front’ of your website at all.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzE2P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--7cc4dfac1409aa292fb3529c4f5ed16afe6055f3" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTYsInB1ciI6ImJsb2JfaWQifX0=--3eab625c75c066f70c49a6f8327cadaf7b035e97/image.png" filename="image.png" filesize="62936" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTYsInB1ciI6ImJsb2JfaWQifX0=--3eab625c75c066f70c49a6f8327cadaf7b035e97/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;You’re free to model your content, building one input at a time, allowing you incredible control over your project. As Symphony says ‘create what you need, and only what you need.&lt;/p&gt;

&lt;h3&gt;Custom Fields&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;There are no custom fields when every field is custom.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Symphony provides some &lt;a href="http://symphony-cms.com/learn/concepts/view/field-types/"&gt;basic fields&lt;/a&gt; for you to work with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Author&lt;/li&gt;
&lt;li&gt;Checkbox&lt;/li&gt;
&lt;li&gt;Date&lt;/li&gt;
&lt;li&gt;File upload&lt;/li&gt;
&lt;li&gt;Select Box&lt;/li&gt;
&lt;li&gt;Select Box Link&lt;/li&gt;
&lt;li&gt;Tag List&lt;/li&gt;
&lt;li&gt;Textarea&lt;/li&gt;
&lt;li&gt;Text Input&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don’t see what you need? &lt;a href="http://symphony-cms.com/download/extensions/field-types/"&gt;There’s probably an extension for that&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With planning and experimentation, you can build bespoke content models with appropriate selection of field types to &lt;a href="http://symphony-cms.com/learn/concepts/view/sections/"&gt;create a ‘sections’&lt;/a&gt; such as ‘Blog Post’, ‘Recipe’, ‘Employee’, ‘Product’ etc.&lt;/p&gt;

&lt;h3&gt;Tailored Admin&lt;/h3&gt;

&lt;p&gt;Just as you tailor your content model through &lt;a href="http://symphony-cms.com/learn/concepts/view/sections/"&gt;Sections&lt;/a&gt; and &lt;a href="http://symphony-cms.com/learn/concepts/view/field-types/"&gt;Field Types&lt;/a&gt;, you’re also able to tailor your admin interface, grouping sections such as ‘Post’ and ‘Categories’ into a ‘&lt;a href="http://symphony-cms.com/learn/concepts/view/navigation-groups/"&gt;Navigation Group&lt;/a&gt;‘ of ‘Blog’.&lt;/p&gt;

&lt;p&gt;In addition you can pick and choose what sections are actually visible to your authors. For example you may have a &lt;a href="http://symphony-cms.com/learn/concepts/view/sections/"&gt;Section&lt;/a&gt; of ‘Threads’ and ‘Posts’ for a forum, but wish to hide this from your authors as all forum moderation is done in the ‘front-end’.&lt;/p&gt;

&lt;p&gt;Symphony’s settings, &lt;a href="http://symphony-cms.com/learn/concepts/view/sections/"&gt;Sections&lt;/a&gt;, &lt;a href="http://symphony-cms.com/learn/concepts/data-sources/"&gt;Data Sources&lt;/a&gt;, &lt;a href="http://symphony-cms.com/learn/concepts/view/pages/"&gt;Pages&lt;/a&gt;, &lt;a href="http://symphony-cms.com/learn/concepts/view/utilities/"&gt;Utilities&lt;/a&gt; and &lt;a href="http://symphony-cms.com/learn/concepts/view/events/"&gt;Events&lt;/a&gt; are all managed through the ‘&lt;a href="http://symphony-cms.com/learn/concepts/view/blueprints/"&gt;Blueprint&lt;/a&gt;‘ menu in the Symphony Admin. This menu is only shown to authors with the permission of ‘Administrator’ so you can have peace of mind that an adventurous client won’t dismantle their website’s vitals.&lt;/p&gt;

&lt;h3&gt;Extensions&lt;/h3&gt;

&lt;p&gt;Extensions work a little like WordPress plugins in that they ‘extend’ the core functionality. Extensions can take many forms such as additional field types, enhancements to the admin panel, XML sitemap integration and more.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzE3P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--9a8810cc8d757bafd6d7fd95fb1009fe234060fc" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTcsInB1ciI6ImJsb2JfaWQifX0=--3f525e12806376c2adfe50560178abd5a0be51fa/image.png" filename="image.png" filesize="94148" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTcsInB1ciI6ImJsb2JfaWQifX0=--3f525e12806376c2adfe50560178abd5a0be51fa/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Unlike WordPress plugins however they often solve a problem rather than add a feature. For instance, they would enable a way to embed &lt;code&gt;&amp;lt;object&amp;gt;&lt;/code&gt;s into your content rather than target YouTube videos specifically.&lt;/p&gt;

&lt;p&gt;This allows you retain fine control over your project’s development rather than relying on an extension developer. It’s left to you exactly how a new feature is implemented.&lt;/p&gt;

&lt;h3&gt;Aggregate XML&lt;/h3&gt;

&lt;p&gt;As Symphony uses XSLT, and XSLT uses XML, you’re able to aggregate feeds and content from other sources with ease.&lt;/p&gt;

&lt;p&gt;A classic example of this would be displaying your latest Tweets from &lt;a href="https://twitter.com/statuses/user_timeline.xml?screen_name=markyhesketh&amp;amp;count=10"&gt;an XML response&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You could tie this external XML to a &lt;a href="http://symphony-cms.com/learn/concepts/view/data-sources/"&gt;data source&lt;/a&gt; in Symphony, and output it in just the same way you would any of your content. No plugins or mess required.&lt;/p&gt;

&lt;h3&gt;Debugging console&lt;/h3&gt;

&lt;p&gt;Symphony comes with a useful debugging utility available by adding &lt;code&gt;?debug&lt;/code&gt; to the end of your ‘front-end’ URL.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzE4P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--c569d061d4040791475fd28ec2e8462600ae5720" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTgsInB1ciI6ImJsb2JfaWQifX0=--e432361bfad0f0ab5436e3371b3518ca09d6a6f2/image.png" filename="image.png" filesize="66321" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTgsInB1ciI6ImJsb2JfaWQifX0=--e432361bfad0f0ab5436e3371b3518ca09d6a6f2/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Using this screen you’re able to see exactly what XML is being output to your pages based on your custom set of rules (date, URL parameters etc).&lt;/p&gt;

&lt;p&gt;You can also see other useful information such as performance, allowing you to fine-tune your datasources and make sure they’re not firing needlessly and wasting resources.&lt;/p&gt;

&lt;h3&gt;Markdown&lt;/h3&gt;

&lt;p&gt;Not necessarily a feature of Symphony, but by default your textarea fields can format content using &lt;a href="http://daringfireball.net/projects/markdown/"&gt;Markdown&lt;/a&gt;. I’ve found this feature useful combined with &lt;a href="http://mouapp.com/"&gt;Mou&lt;/a&gt; &lt;em&gt;(OSX)&lt;/em&gt;, &lt;a href="http://markdownpad.com/"&gt;MarkdownPad&lt;/a&gt; &lt;em&gt;(Win)&lt;/em&gt; and &lt;a href="http://getwritingkit.com/"&gt;Writing Kit&lt;/a&gt; &lt;em&gt;(iPad)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I’m able to write freely without worrying about misplaced and invalid HTML markup such as rogue spans and open tags.&lt;/p&gt;

&lt;h2&gt;Using Symphony CMS&lt;/h2&gt;

&lt;p&gt;The &lt;a href="http://symphony-cms.com/learn/tutorials/beginners/"&gt;Symphony CMS Tutorials&lt;/a&gt; are a great starting point to get up and running. Once completed, you can use the &lt;a href="http://symphony-cms.com/learn/concepts/"&gt;Concepts&lt;/a&gt; and &lt;a href="http://symphony-cms.com/learn/api/2.2.5/"&gt;API&lt;/a&gt; sections as a regular reference point while developing.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://designprojectx.com/tutorials/"&gt;Stephen Bau’s Symphony-related XSLT tutorials&lt;/a&gt; have also been incredibly useful.&lt;/p&gt;

&lt;h3&gt;Symphony’s Community&lt;/h3&gt;

&lt;p&gt;As you’re working with open software there are many people around if you get stuck. &lt;a href="http://symphony-cms.com/discuss/"&gt;The community forums&lt;/a&gt; are &lt;em&gt;relatively&lt;/em&gt; small compared to say WordPress, but the members are very active, helpful and skilled.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzE5P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--4425cf9b21066776b61d135a7cdaf3d2e9fe7813" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTksInB1ciI6ImJsb2JfaWQifX0=--99884ef71e5f917ff1505532a3951a2317981e6f/image.png" filename="image.png" filesize="81624" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTksInB1ciI6ImJsb2JfaWQifX0=--99884ef71e5f917ff1505532a3951a2317981e6f/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;h3&gt;GitHub Development&lt;/h3&gt;

&lt;p&gt;If you’re a GitHub user you’ll be happy to know that Symphony is actively developed on a &lt;a href="https://github.com/symphonycms/symphony-2"&gt;GitHub repository&lt;/a&gt;, while community extensions being encouraged to be developed as &lt;a href="http://speirs.org/blog/2009/5/11/understanding-git-submodules.html"&gt;submodules&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This means you can very quickly ‘fork’ your own copy of the software and begin developing your latest project.&lt;/p&gt;

&lt;p&gt;You can also then merge your local repositary, automatically staying up to date with all developments and ensuring you’re running the latest version.&lt;/p&gt;

&lt;p&gt;Not into GitHub? You can &lt;a href="http://symphony-cms.com/download/"&gt;download the zip package&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;A marathon, not a sprint&lt;/h2&gt;

&lt;p&gt;As I mentioned, this website is running Symphony. It’s a simple blog / portfolio with&lt;a href="http://www.markhesketh.co.uk/about"&gt; an about me page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I could have created this website quite comfortably with WordPress, and probably &lt;strong&gt;much quicker&lt;/strong&gt; due to my familiarity with WordPress and the nature of this website’s content.&lt;/p&gt;

&lt;p&gt;However, I’m glad I didn’t. Besides the fact that this has been a great learning exercise, if I’d decided to resist change and use WordPress I would have had to make a number of compromises.&lt;/p&gt;

&lt;p&gt;The markup for this website site is all my own doing, good or bad, its mine. I’ve been able to tailor it exactly to my needs. I haven’t had to remove unneeded features as they were never there to begin with, everything has been built from the ground up with a purpose.&lt;/p&gt;

&lt;p&gt;I’ve been able to build myself a platform, something truly customised, with the ability to expand on it in the future. If I decide I want a custom ‘client login’ section to my portfolio, handled by the same CMS as my blog, I can do that quite easily.&lt;/p&gt;

&lt;h2&gt;Try Symphony CMS&lt;/h2&gt;

&lt;p&gt;You should give it a go. &lt;a href="http://symphony-cms.com/"&gt;Visit the official Symphony CMS website&lt;/a&gt; for much more &lt;em&gt;(better written)&lt;/em&gt; information.&lt;/p&gt;

&lt;p&gt;If you try it, &lt;a href="http://www.twitter.com/markyhesketh/"&gt;let me know how it goes&lt;/a&gt;. If you get stuck, take a look at the &lt;a href="http://symphony-cms.com/discuss/"&gt;Symphony CMS forums&lt;/a&gt; as I’ve yet to have a problem that they haven’t covered and solved.&lt;/p&gt;


---

Originally published at [Symphony CMS](https://www.markhesketh.com/blog/symphony-cms) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/10</id>
    <published>2012-02-08T00:00:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/replacing-wordpress"/>
    <title>Replacing WordPress</title>
    <content type="html">&lt;p&gt;Following up on the new tools and techniques I’ve picked up recently while &lt;a href="http://www.markhesketh.co.uk/blog/portfolio-goes-live"&gt;putting my portfolio and blog live&lt;/a&gt; such as &lt;a href="http://www.markhesketh.co.uk/blog/linode"&gt;moving my hosting to Linode VPS&lt;/a&gt;, I’m just writing to outline my decision to stop using WordPress as my ‘go to’ CMS.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzI1P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--923b5dadddd2c183156c95373587a99219750088" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjUsInB1ciI6ImJsb2JfaWQifX0=--981c3b2abd58c34cbee4c59aa2d13fb6fd89a917/image.png" filename="image.png" filesize="46223" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjUsInB1ciI6ImJsb2JfaWQifX0=--981c3b2abd58c34cbee4c59aa2d13fb6fd89a917/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;I’ve been using WordPress almost exclusively for client brochure websites for nearly 3 years, and will continue to do so as its a great piece of software, but I’m now learning it’s not always the right tool for the job.&lt;/p&gt;

&lt;p&gt;This website was recently built using &lt;a href="http://www.symphony-cms.com"&gt;Symphony CMS&lt;/a&gt;. I could have quite easily used WordPress, in fact it probably would had been much faster, but I wouldn’t have had as much freedom to really tailor everything how I wanted it, and I really do mean &lt;strong&gt;everything&lt;/strong&gt;. It’s also been a nice learning activity, but that’s all for another post.&lt;/p&gt;

&lt;h2&gt;WordPress Pros&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.wordpress.org/"&gt;WordPress&lt;/a&gt; is a fantastic CMS there’s no doubt about it, and if figures are to be believed &lt;a href="http://techcrunch.com/2011/08/19/wordpress-now-powers-22-percent-of-new-active-websites-in-the-us/"&gt;it now powers 22% of websites in the US&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Quick setup&lt;/h3&gt;

&lt;p&gt;Getting a WordPress website up and running, with a custom design and a few additional features is very fast. This is partly down to my own familiarity with the software, but mostly due to WordPress being very feature rich ‘out the box’.&lt;/p&gt;

&lt;p&gt;For example, I recently set up a client’s blog, based on their current websites design in about an hour using &lt;a href="http://clean-start-theme.com/"&gt;a freely available WordPress starter theme&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Pretty admin&lt;/h3&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzI2P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--b31e75aa331f9652709257d720413676c63e837c" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjYsInB1ciI6ImJsb2JfaWQifX0=--f41a98588aa424836b23d1412c2f835b2ac66df1/image.png" filename="image.png" filesize="90841" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjYsInB1ciI6ImJsb2JfaWQifX0=--f41a98588aa424836b23d1412c2f835b2ac66df1/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;I’ve developed many client websites with WordPress, and never really had a problem with the client not understanding the admin panel. Sure, there is an initial learning curve, but this is often very small.&lt;/p&gt;

&lt;p&gt;I also do a lot of e-commerce work using &lt;a href="http://www.prestashop.com/"&gt;Prestashop&lt;/a&gt;, and find client’s have more problems with the Prestashop admin panel, than they do with WordPress’.&lt;/p&gt;

&lt;h3&gt;Large plugin / theme repository&lt;/h3&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzI3P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--6c97a50beae090ec4c440b8103566c388844468c" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjcsInB1ciI6ImJsb2JfaWQifX0=--dbbc435e6b9fa189c07e4083fd802b8400c7e024/image.png" filename="image.png" filesize="91996" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjcsInB1ciI6ImJsb2JfaWQifX0=--dbbc435e6b9fa189c07e4083fd802b8400c7e024/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;If you’re not too bothered about your website design being unique premium theme sellers such as &lt;a href="http://premiumpixels.com/"&gt;Orman Clark&lt;/a&gt; do great work selling great looking themes on websites such as &lt;a href="http://themeforest.net/"&gt;Theme Forest&lt;/a&gt;. You really could have a great looking website online in a morning.&lt;/p&gt;

&lt;p&gt;There is also a &lt;a href="http://www.google.co.uk/search?sourceid=chrome&amp;amp;ie=UTF-8&amp;amp;q=wordpress+plugins"&gt;mass of plugins available&lt;/a&gt; to enhance your website from great authors such as &lt;a href="http://yoast.com/"&gt;Yoast&lt;/a&gt; and &lt;a href="http://www.elliotcondon.com/"&gt;Elliot Condon&lt;/a&gt;, who create two of my favourite plugins, &lt;a href="http://yoast.com/wordpress/seo/"&gt;WordPress SEO&lt;/a&gt; and &lt;a href="http://www.advancedcustomfields.com/"&gt;Advanced Custom Fields&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;WordPress cons&lt;/h2&gt;

&lt;p&gt;WordPress &lt;strong&gt;makes a lot of assumptions&lt;/strong&gt; about what you would like to do. This is prevalent throughout creating a WordPress website.&lt;/p&gt;

&lt;p&gt;While this is one of the huge reasons WordPress websites can be deployed so quickly, it can soon become a hinderance if you need something even &lt;em&gt;slightly&lt;/em&gt; more bespoke. I’m not talking a Ruby on Rales or PHP framework app here.&lt;/p&gt;

&lt;h3&gt;Content&lt;/h3&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzI4P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--b91568009f52fabe52cad7be34194a7149f15ebb" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjgsInB1ciI6ImJsb2JfaWQifX0=--5b4b281ca854360b4909082b5ed864ee9395e055/image.png" filename="image.png" filesize="41435" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjgsInB1ciI6ImJsb2JfaWQifX0=--5b4b281ca854360b4909082b5ed864ee9395e055/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;WordPress is a ‘page-based’ CMS, and if the content goes beyond a simple Title+Content structure things start to get a little messy.&lt;/p&gt;

&lt;p&gt;Yes, with &lt;a href="http://codex.wordpress.org/Custom_Fields"&gt;custom fields&lt;/a&gt; you can do some pretty neat things, eventually, but ultimately you’re bending WordPress to near breaking point and it’s never felt intuitive to me.&lt;/p&gt;

&lt;p&gt;I recently built a car importer’s website in WordPress, which including their car listings categorised by manufacturer, pricing, image galleries etc. It was doable, but wasn’t a whole lot of fun working with WordPress custom fields and could have been much better.&lt;/p&gt;

&lt;h3&gt;Admin&lt;/h3&gt;

&lt;p&gt;The admin is pretty and intuitive, thats in the ‘pro’ column, but a lot of it is often needless.&lt;/p&gt;

&lt;p&gt;If I have a brochure website that doesn’t include a blog, the ‘Posts’, ‘Comments’ and ‘Links’ menus then all become a little redundant.&lt;/p&gt;

&lt;p&gt;I can hide them in the &lt;code&gt;functions.php&lt;/code&gt; or using a plugin, but its this sort of thing that makes me starting thinking ‘is this the right tool for the job?’.&lt;/p&gt;

&lt;p&gt;There’s more examples of this, such as editors being able to change themes, and it all means I spend a decent chunk of development time bending the WordPress defaults rather than improving or optimising the project.&lt;/p&gt;

&lt;h3&gt;Markup&lt;/h3&gt;

&lt;p&gt;WordPress adds a whole bunch of functions into your &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;, often the first thing I do is remove them all in the &lt;code&gt;functions.php&lt;/code&gt; using one of the many reusable WordPress function snippets I have saved.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://en.wordpress.com/windows-live-writer/"&gt;Windows Live Writer&lt;/a&gt; shouldn’t be made available by default in my opinion, and should instead be an optional plugin. Its this sort of thinking Symphony does very well.&lt;/p&gt;

&lt;h2&gt;WordPress projects in the future&lt;/h2&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzI5P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--ce77dff7b4989fdf2a916f958c36df85af61df85" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjksInB1ciI6ImJsb2JfaWQifX0=--1c8520df2ac4ff2388fd3589eb9adf8b899e8c02/image.png" filename="image.png" filesize="56252" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MjksInB1ciI6ImJsb2JfaWQifX0=--1c8520df2ac4ff2388fd3589eb9adf8b899e8c02/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;I run a modest &lt;a href="http://www.prestadb.com/"&gt;Prestashop tutorial and news website&lt;/a&gt;, and while WordPress has been superb controlling the news/posts side of things, I’ve hit a brick wall when trying to tie in a Wiki and Community portion to the website.&lt;/p&gt;

&lt;p&gt;I’d rather not use &lt;a href="http://buddypress.org/"&gt;BuddyPress&lt;/a&gt;, or continually worry about bridging something like &lt;a href="http://vanillaforums.org/"&gt;Vanilla Forums&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are &lt;a href="http://nenuno.co.uk/creative/design/15-wordpress-wiki-plugins/"&gt;Wiki plugins available,&lt;/a&gt; but then you’re tied to what the plugin developer defines as a Wiki, and what features it should include.&lt;/p&gt;

&lt;p&gt;It has quickly become apparent that WordPress isn’t the horse for this particular course, and I am underway redesigning/redeveloping the website using &lt;a href="http://www.symphony-cms.com"&gt;Symphony CMS&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;A decision&lt;/h2&gt;

&lt;p&gt;As I say, I am not dropping my use of WordPress, and much like how I recently started designing in Fireworks rather than Photoshop, merely recognising when it is and isn’t the right tool for the job.&lt;/p&gt;

&lt;p&gt;I’ll be using WordPress exclusively for quick brochure websites, and client’s who specifically ask for WordPress as their CMS (unless its definitely the wrong option!), but for more bespoke jobs I’ll turn to &lt;a href="http://www.symphony-cms.com"&gt;Symphony CMS&lt;/a&gt;, or finally get round to &lt;a href="http://railsforzombies.org/"&gt;learning some damned Ruby on Rails&lt;/a&gt;.&lt;/p&gt;


---

Originally published at [Replacing WordPress](https://www.markhesketh.com/blog/replacing-wordpress) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/11</id>
    <published>2012-02-06T00:00:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/linode"/>
    <title>Linode</title>
    <content type="html">&lt;p&gt;I recently &lt;a href="http://www.markhesketh.co.uk/blog/portfolio-goes-live"&gt;put my portfolio live&lt;/a&gt; and along the way embraced a lot of change and new tools and one of these changes was my recent decision to move my hosting from &lt;a href="http://www.mediatemple.net"&gt;MediaTemple&lt;/a&gt; to &lt;a href="http://www.linode.com/?r=374e1313f69ae277bb749ec13b9665876d906c16"&gt;Linode&lt;/a&gt;. &lt;em&gt;(that’s my referral, please consider using it if this post is useful to you!)&lt;/em&gt;&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzMwP2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--3e9c496db6c756126d819b5ee75af4f9fba159c0" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzAsInB1ciI6ImJsb2JfaWQifX0=--36f34a997be02d1328f0cb4554d33b6f070ee120/image.png" filename="image.png" filesize="17958" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzAsInB1ciI6ImJsb2JfaWQifX0=--36f34a997be02d1328f0cb4554d33b6f070ee120/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Linode, if you’ve not heard, offer VPS hosting at varying levels, from 512mb to a staggering 20gb RAM. I won’t go into too much detail as you can find out more on their &lt;a href="http://www.linode.com/features.cfm"&gt;Features&lt;/a&gt; and &lt;a href="http://www.linode.com/why.cfm"&gt;Why Linode?&lt;/a&gt; pages.&lt;/p&gt;

&lt;h2&gt;Why move?&lt;/h2&gt;

&lt;p&gt;I’ve been a MediaTemple customer for a couple of years, they’re a great service and I personally found the customer support helpful and very quick to respond (via Twitter at least).&lt;/p&gt;

&lt;p&gt;It’s pretty obvious they have a great brand. I’d seen developers proudly proclaiming their website was hosted by MediaTemple in footer. It was like designer label hosting.&lt;/p&gt;

&lt;p&gt;I soon outgrew my previous host, &lt;a href="http://krystal.co.uk/"&gt;Krystal&lt;/a&gt;, and their basic packages and at the time couldn’t offer anything quite like the bells and whistles of MediaTemple.&lt;/p&gt;

&lt;p&gt;Its come to a point however where I was again re-evaluating my hosting needs. Rather than outgrowing MediaTemple, I felt I didn’t need the handholding and wanted something a bit more surgical than swiss-army.&lt;/p&gt;

&lt;h3&gt;Reviews and recommendations&lt;/h3&gt;

&lt;p&gt;Late last year I’d read a &lt;a href="http://mattgemmell.com/2009/11/15/linode/"&gt;post on Linode by Matt Gemmell&lt;/a&gt;. His post was from a few years ago so &lt;a href="https://twitter.com/#!/mattgemmell/status/143707480214601730"&gt;I asked Matt over Twitter if he’d still recommend Linode&lt;/a&gt;, he would.&lt;/p&gt;

&lt;p&gt;I googled around a little to find popular opinion for &lt;a href="http://www.linode.com/?r=374e1313f69ae277bb749ec13b9665876d906c16"&gt;Linode&lt;/a&gt;‘s service, and it was a universal thumbs up from seemingly everyone.&lt;/p&gt;

&lt;p&gt;This was a good sign as even with MediaTemple, a host I had been very happy with, for every good review there was also someone keen to share their displeasure with downtime or poor customer service.&lt;/p&gt;

&lt;h3&gt;Price&lt;/h3&gt;

&lt;p&gt;Linode’s basic &lt;a href="https://manager.linode.com/signup/#plans"&gt;512mb VPS comes in at $19.95/mo&lt;/a&gt;. This to me is an absolute bargain.&lt;/p&gt;

&lt;p&gt;I currently have &lt;a href="http://mediatemple.net/webhosting/dv/"&gt;(dv) hosting at $50/mo&lt;/a&gt; and &lt;a href="http://mediatemple.net/webhosting/gs/"&gt;(gs) at $20/mo&lt;/a&gt; with MediaTemple, and while these are not the same services, the equivalent &lt;a href="http://mediatemple.net/webhosting/ve/pricing.php"&gt;(ve) service is $30/mo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You get nearly double the bandwidth with the (ve) (350gb vs 200gb), but with Linode this is an optional extra , so you only pay if you require it.&lt;/p&gt;

&lt;h3&gt;London, UK data centre&lt;/h3&gt;

&lt;p&gt;Over the last year or so I’ve become quite obsessed with page speed. Its good for your users, and its good for Google.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzMxP2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--6f4ce4b6406a954796a672876a7506716d85efa9" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzEsInB1ciI6ImJsb2JfaWQifX0=--9e9ddbf7756a2c8a8b385a356c6b2de79eeed6d7/image.png" filename="image.png" filesize="224192" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzEsInB1ciI6ImJsb2JfaWQifX0=--9e9ddbf7756a2c8a8b385a356c6b2de79eeed6d7/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Linode allow you to choose from &lt;a href="http://www.linode.com/avail/"&gt;6 different data centres&lt;/a&gt;, and the option to &lt;a href="http://www.linode.com/speedtest/"&gt;test the speed of each centre with a basic download trial&lt;/a&gt;. Naturally, I chose London&lt;/p&gt;

&lt;p&gt;I try to pay attention to best practices regarding Page Speed in my websites, GZipping, CSS sprites, combined and minified scripts, optimised images etc, but the response time from the US data centres on my MediaTemple websites always felt like a let down.&lt;/p&gt;

&lt;h3&gt;VPS Freedom&lt;/h3&gt;

&lt;p&gt;I realise MediaTemple offer the (ve) service, but due to the 3 points above this wasn’t really an option.&lt;/p&gt;

&lt;p&gt;I loathe Plesk, it feels like unnecessary bloat and made tasks more difficult as you were wrestling with the software, bending it to do &lt;em&gt;what you actually wanted&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;I felt I’d outgrown the control panels and pre-written software of the (dv) server, and the shared hosting of (gs). Although in fairness MediaTemple’s control panel is excellent.&lt;/p&gt;

&lt;h3&gt;Too much to mention&lt;/h3&gt;

&lt;p&gt;I could go over everything but instead I’d recommend you take a close look at &lt;a href="http://www.linode.com/features.cfm"&gt;Linode’s features&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;My Linode setup&lt;/h2&gt;

&lt;p&gt;I opted for the basic 512mb VPS to begin with as Linode make it very easy to upgrade via your Dashboard as your requirements change.&lt;/p&gt;

&lt;p&gt;Following the straight forward &lt;a href="http://library.linode.com/getting-started"&gt;Getting started&lt;/a&gt; and &lt;a href="http://library.linode.com/lemp-guides/ubuntu-10.04-lucid"&gt;Set up a LEMP Server on Ubuntu 10.04&lt;/a&gt; guides in the &lt;a href="http://library.linode.com/"&gt;Linode Library&lt;/a&gt; I was quickly up and running.&lt;/p&gt;

&lt;p&gt;My setup is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 10.04&lt;/li&gt;
&lt;li&gt;&lt;a href="http://nginx.org/"&gt;Nginx web server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;&lt;a href="http://php-fpm.org/"&gt;PHP-FPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;E-mail hosted by &lt;a href="http://www.google.com/apps/intl/en-GB/business/index.html"&gt;Google Apps&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Ubuntu 10.04&lt;/h3&gt;

&lt;p&gt;Being new to all this I chose to use the widely recommended Ubuntu 10.04 as my OS, which was as easy as selecting it from a drop down menu in Linode’s dashboard.&lt;/p&gt;

&lt;p&gt;I have no preference to any particular Linux distro, I know very little about the differences, but Linode offer many different flavours in many different versions and your server is ready to use almost instantly after selection.&lt;/p&gt;

&lt;h3&gt;Nginx&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://wiki.nginx.org/WhyUseIt"&gt;Nginx is a lightweight web server&lt;/a&gt;. I’d had memory problems using Apache in the past, even having just a handful of visitors on a site at any one time and my web server would become cumbersome.&lt;/p&gt;

&lt;p&gt;I’d done various optimisations but things still weren’t ideal, and I couldn’t justify the large jump in price to a more hefty (dv).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Apache is like Microsoft Word, it has a million options but you only need six. Nginx does those six things, and it does five of them 50 times faster than Apache.”&lt;br&gt;
&lt;a href="http://maisonbisson.com/blog/post/12249/chris-lea-on-nginx-and-wordpress/"&gt;Chris Lea&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As Chris describes, I’ve found this to be the case. The memory footprint is &lt;strong&gt;much&lt;/strong&gt; lower with the same traffic, and I’ve been able to do everything in Nginx that’d previously needed from Apache.&lt;/p&gt;

&lt;p&gt;I’ve had to make a few modifications to the &lt;a href="http://www.symphony-cms.com"&gt;Symphony CMS&lt;/a&gt; rewrite rules, translating them from Apache to Nginx, but this was the only change that was needed. As a personal side note, I’ve also found the Nginx configuration to be much more intuitive.&lt;/p&gt;

&lt;p&gt;As my Linode server is only 512mb, Nginx seemed a logical choice.&lt;/p&gt;

&lt;h3&gt;MySQL&lt;/h3&gt;

&lt;p&gt;Obvious choice really. I’d like to look into areas such as &lt;a href="http://www.mongodb.org/"&gt;MongoDB&lt;/a&gt; in the future, but as a lot of my work uses open-source CMS systems and frameworks supporting MySQL only, I’ll stick with what I know.&lt;/p&gt;

&lt;h3&gt;PHP-FPM&lt;/h3&gt;

&lt;p&gt;PHP-FPM is a FastCGI implementation of PHP that cleverly adapts its processes based on traffic load. You can &lt;a href="http://php-fpm.org/"&gt;find out more on their website&lt;/a&gt;, and there’s various guides around for installing this as a package.&lt;/p&gt;

&lt;h3&gt;E-mail hosted by Google Apps&lt;/h3&gt;

&lt;p&gt;This was a bit of a no-brainer, and I’ve been meaning to do it for a while now.&lt;/p&gt;

&lt;p&gt;Rather than hosting your own memory hungry mail server, spam filter, IMAP processes etc, &lt;a href="http://www.google.com/apps/intl/en/group/index.html"&gt;Google will do this for you for free&lt;/a&gt;.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzMyP2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--900c7616b7f201667fbf2e1f8e13d25577dc7f3b" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzIsInB1ciI6ImJsb2JfaWQifX0=--a2ded95abfcd9772192c4be47120e3f8919e2bfc/image.png" filename="image.png" filesize="112921" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzIsInB1ciI6ImJsb2JfaWQifX0=--a2ded95abfcd9772192c4be47120e3f8919e2bfc/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;They allow you to have up to 10 e-mail accounts, all integrated with Google calendars and Google docs. You can Sync your contacts too, making them accessible from all your devices.&lt;/p&gt;

&lt;p&gt;Connect to your e-mail using traditional POP3/IMAP clients such as Apple Mail/Outlook/Thunderbird, or use the webmail service (the slick Gmail interface). You can even setup a custom domain such as &lt;a href="http://mail.example.com/"&gt;http://mail.example.com/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Simply point your MX records in your DNS to their servers and they’ll take care of everything. All for free, I honestly can’t see many reasons why you wouldn’t want to do this.&lt;/p&gt;

&lt;h2&gt;Try Linode&lt;/h2&gt;

&lt;p&gt;In summary, I’m only a few days in and I’d &lt;a href="http://www.linode.com/?r=374e1313f69ae277bb749ec13b9665876d906c16"&gt;highly recommend trying Linode&lt;/a&gt;. Setup was quick, migration was painless, and my website appears to be &lt;em&gt;stupidly&lt;/em&gt; fast.&lt;/p&gt;


---

Originally published at [Linode](https://www.markhesketh.com/blog/linode) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
  <entry>
    <id>tag:www.markhesketh.com,2005:Post/12</id>
    <published>2012-02-01T00:00:00Z</published>
    <updated>2025-09-10T20:49:49Z</updated>
    <link rel="alternate" type="text/html" href="https://www.markhesketh.com/blog/prestashop-starter-theme-boilerplate"/>
    <title>Prestashop Starter Theme / Boilerplate</title>
    <content type="html">&lt;p&gt;I do a lot of work using both &lt;a href="http://www.prestashop.com"&gt;PrestaShop&lt;/a&gt; and &lt;a href="http://www.wordpress.org"&gt;WordPress &lt;/a&gt;and a big difference I find between the two is support for developers.&lt;/p&gt;

&lt;p&gt;As it stands, Prestashop Theme developers have to hack away at the default theme each time they begin a new project. In contrast WordPress Theme developers have a choice of &lt;a href="http://wordpress.org/extend/themes/boilerplate"&gt;several&lt;/a&gt; &lt;a href="http://wordpress.org/extend/themes/toolbox"&gt;starter&lt;/a&gt; &lt;a href="http://clean-start-theme.com/"&gt;themes&lt;/a&gt; &lt;a href="http://themble.com/bones/"&gt;available&lt;/a&gt; if they’d prefer to not work on TwentyEleven &lt;em&gt;yet again&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;Developing a Prestashop Theme&lt;/h2&gt;

&lt;p&gt;This got me thinking about a starter theme or ‘boilerplate’ for Prestashop, a starting point for theme development featuring reusable code and best practice methods related to Prestashop theming.&lt;/p&gt;

&lt;h3&gt;Using the default theme&lt;/h3&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzMzP2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--eeb1c212d43a8cf885523a40dc4bc88eaab219c2" content-type="image/png" url="https://www.markhesketh.com/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzMsInB1ciI6ImJsb2JfaWQifX0=--41cd64b24b1d896712d407b44f98b780b4ea17bc/image.png" filename="image.png" filesize="212488" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzMsInB1ciI6ImJsb2JfaWQifX0=--41cd64b24b1d896712d407b44f98b780b4ea17bc/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Though the default theme demonstrates the functionality of Prestashop very well, I’ve never liked it as a theme.&lt;/p&gt;

&lt;p&gt;There’s many parts of it that I think are a complete mess. Using this as a baseline for a new theme hinders creativity, and this can be seen on the &lt;a href="http://addons.prestashop.com/"&gt;Prestashop Addons store&lt;/a&gt; where so many themes have stuck to the default blueprint.&lt;/p&gt;

&lt;h3&gt;Prestashop’s proposed ‘Skeleton Theme’&lt;/h3&gt;

&lt;p&gt;Last summer Prestashop wrote on their blog that they were to include a &lt;a href="http://www.prestashop.com/blog/article/prestashop_v15_revealeddiscover_the_skeleton_theme_by_vincent_augagneur/"&gt;‘Skeleton Theme’&lt;/a&gt; alongside the upcoming &lt;a href="http://www.prestadb.com/prestashop-1-5-new-features/"&gt;Prestashop 1.5&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is great news and a step in the right direction, and while there’s some nice looking features such as multiple template layouts (think Templates in WordPress) and configuration variables, there was a couple of things I wasn’t so thrilled about.&lt;/p&gt;

&lt;h4&gt;Unnecessary bloat&lt;/h4&gt;

&lt;p&gt;Vincent Augagneur mentions that the theme would include the &lt;a href="http://960.gs/"&gt;960gs&lt;/a&gt; and &lt;a href="http://jqueryui.com/"&gt;jQuery UI&lt;/a&gt;. Both are great tools, but in my opinion this makes an assumption about what the designer/developer will be creating and working with.&lt;/p&gt;

&lt;p&gt;The theme developer may wish to use a grid they’re familiar with, something custom built as I did for this website, or no grid at all. The 960gs then becomes bloat, and something extra to remove.&lt;/p&gt;

&lt;p&gt;The same is true if you don’t actually use jQuery UI’s features, it’s just slowing down your theme and another thing to remove.&lt;/p&gt;

&lt;p&gt;At a certain point you may find yourself removing features of the ‘starter’ theme, as you would have done with the default theme.&lt;/p&gt;

&lt;h4&gt;HTML5 Support&lt;/h4&gt;

&lt;p&gt;I’m making an assumption here as the Skeleton Theme has yet to be released, but based on the &lt;a href="http://www.prestadb.com/prestashop-releases-new-default-store-theme/"&gt;new default Prestashop theme&lt;/a&gt; there’s a good chance that it won’t be utilising HTML5.&lt;/p&gt;

&lt;p&gt;This isn’t a huge deal, just a personal preference, as I have been using HTML5 on production websites for some time now, including Prestashop stores.&lt;/p&gt;

&lt;action-text-attachment sgid="eyJfcmFpbHMiOnsiZGF0YSI6ImdpZDovL21hcmstaGVza2V0aC9BY3RpdmVTdG9yYWdlOjpCbG9iLzM0P2V4cGlyZXNfaW4iLCJwdXIiOiJhdHRhY2hhYmxlIn19--25583bbb510d35788ba280840490bfd9d59218b7" content-type="image/png" url="/files/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzQsInB1ciI6ImJsb2JfaWQifX0=--ca86bac9416da53e9e31781dec233d74f7d9bc7d/image.png" filename="image.png" filesize="46395" previewable="true"&gt;&lt;figure class="attachment attachment--preview attachment--png"&gt;
    &lt;img src="https://www.markhesketh.com/files/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzQsInB1ciI6ImJsb2JfaWQifX0=--ca86bac9416da53e9e31781dec233d74f7d9bc7d/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fbGltaXQiOlsxMDI0LDc2OF19LCJwdXIiOiJ2YXJpYXRpb24ifX0=--b7f740f91be10a02219d1539611ddbe7146720ae/image.png"&gt;

&lt;/figure&gt;&lt;/action-text-attachment&gt;

&lt;p&gt;Ideally I’d like to see a starter theme that utilises all the HTML5 goodness that is ready to use right away, and get people off on the right foot, just as &lt;a href="http://www.html5boilerplate.com"&gt;HTML5 Boilerplate&lt;/a&gt; does.&lt;/p&gt;

&lt;h2&gt;A Prestashop Starter Theme / Boilerplate&lt;/h2&gt;

&lt;p&gt;In response to this I’ve &lt;a href="https://github.com/heskethm/Prestashop-Theme-Boilerplate"&gt;set up a GitHub repository&lt;/a&gt;, to build a (re)usable starting point for developing Prestashop Themes.&lt;/p&gt;

&lt;h4&gt;Some key points &amp;amp; ideas&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Semantic and valid HTML5 markup.&lt;/li&gt;
&lt;li&gt;Stripped of any &lt;em&gt;optional&lt;/em&gt; CSS / Javascript so the developer is free to use the tools they are comfortable with.&lt;/li&gt;
&lt;li&gt;Encourage ‘best practices’ for speed/performance.&lt;/li&gt;
&lt;li&gt;Complete documentation on each template file, and default variables available to each.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Currently I’m focusing on Prestashop 1.4 as a release date for Prestashop 1.5 has yet to be officially announced.&lt;/p&gt;

&lt;p&gt;I’d previously asked Prestashop about a 1.5 released date and they said they were aiming for November 2011. As that’s now long been and gone, I thought it best to get started rather than wait for what might be on the horizon. When Prestashop 1.5 becomes available I will adapt the theme as appropriate.&lt;/p&gt;

&lt;p&gt;You can follow the progress and download the theme on GitHub: &lt;a href="https://github.com/heskethm/Prestashop-Theme-Boilerplate"&gt;https://github.com/heskethm/Prestashop-Theme-Boilerplate&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I’m at very early stages at the moment, but I hope to get things underway and push out a working version over the next month.&lt;/p&gt;

&lt;h3&gt;Get involved&lt;/h3&gt;

&lt;p&gt;If you create Prestashop Themes I’d love to hear any ideas you may have regarding what should be implemented or removed.&lt;/p&gt;

&lt;p&gt;Additionally, I’d like to encourage you to get involved, if you’re a Git/GitHub user fork the Repository and you can contribute to the project.&lt;/p&gt;

&lt;h3&gt;Get in touch&lt;/h3&gt;

&lt;p&gt;If you have any thoughts the Starter Theme, get in touch with me either via my e-mail listed address below, &lt;a href="http://www.twitter.com/markahesketh/"&gt;Twitter&lt;/a&gt;, or &lt;a href="https://github.com/markahesketh"&gt;message me via GitHub&lt;/a&gt;.&lt;/p&gt;


---

Originally published at [Prestashop Starter Theme / Boilerplate](https://www.markhesketh.com/blog/prestashop-starter-theme-boilerplate) by [Mark Hesketh](https://www.markhesketh.com). Thank you for subscribing!</content>
    <author>
      <name>Mark Hesketh</name>
    </author>
  </entry>
</feed>
