How To Improve The Deployment Of WordPress Websites

Advertisement

As WordPress matures into a full-fledged CMS and more and more large online publishers come to rely on the platform, the practice of developing and deploying websites becomes increasingly important. High-profile members of the WordPress community, such as core developer Mark Jaquith and Cristi Burca, have spoken on the topic1 and built tools such as WP-CLI72 and WP Stack63 to improve the professionalism of our administration and deployment.

But what I’m really interested in is the current state of WordPress deployment: how an average developer manages the deployment of their websites, and how can we improve as a community?

In late July 2012, I conducted a short survey to help me answer these questions. The survey was open for three months and drew a modest but not insignificant 327 respondents. This article documents the results of the survey and draws some conclusions about where education is needed and how we can help each other become more professional when deploying our WordPress websites.

The Demographic

In my survey, I asked a few questions to establish the demographic that’s working with WordPress; this was obviously already done in far greater detail with the WordPress user and developer survey4, but I felt that getting a sense of who was responding to this survey was important. Of the 327 respondents, 43% self-identified as developers, 10% as designers, 40% as both designers and developers and 7% other.

The vast majority were located in the North America (50%) and Europe (38%), with the following continents also registering: Asia (6%), Australia (4%), Africa (3%) and South America (1%). I also asked respondents how they would categorize the businesses they work for. Here’s how they responded:

biz-type

The results were overwhelmingly in favor of freelancing (46%), with small businesses (19%) and small agencies (17%) taking a close second and third place, respectively. These figures back up accepted knowledge that WordPress is largely used by small internal Web teams, regional Web agencies and freelancers. Finally, as with the WordPress user and developer survey, I asked respondents whether they made their living from WordPress. This was relatively evenly split, with a small majority of 59% saying yes.

That said, of those who identified themselves as developers, 67% said they earn their living from WordPress, which suggests that WordPress developers are generally more inclined to stick with one platform than designers, who are perhaps more agonistic.

Deployment Practices

Now we get to the meat of the survey, how respondents actually deploy their WordPress websites. Combined, the 327 respondents maintain 6,378.5 WordPress websites — yes, someone maintains half a WordPress website. The majority of respondents manage a fairly small number of websites, with 46% looking after fewer than 10. That said, an impressive 8% manage between 30 and 40 websites, and, incredibly, one person is responsible for 700. Below is a breakdown of the numbers.

Websites Maintained by Survey Respondents

Number of websites Number of respondents
Fewer than 10 149
10 – 20 109
20 – 30 26
50 – 100 7
100 – 200 4
200 – 500 1
500 – 1000 1

Version Control

I asked all respondents whether they use version control and, if so, which software they favor. Astonishingly (at least to me), 45% of respondents said they do not use version-control software at all as part of their workflow. Of the remaining 55%, Git was by far the most popular, taking 41% of the vote, and Subversion surprisingly accounted for only 9%. Drilling down a little deeper, 28% of those who identify themselves as a developer stated that they do not use version control, and 48% of those who are both developers and designers said the same. Here’s a breakdown of overall responses on version-control software:

version-control

Next, I asked respondents what method of deploying websites they favor. These I broke down into FTP, SFTP, SCP, SSH + version control, SSH + version control + Capistrano, and other. Again, somewhat shocking for me was to find that FTP took 49% of the vote, followed by SFTP (20%) and SSH + version control (17%). My preferred method, SSH + version control + Capistrano, got only 3% of the vote; but even with so low a number, I was pretty encouraged to hear that people out there take the time to work in this manner.

Environments

I asked respondents whether they maintain different environments for their WordPress websites — that is, whether they set up local, test, staging and live environments. Answering yes didn’t require that they run all of these environments, but simply that they differentiate between the website they develop on, the website on which they show changes to a client and the live website. The vast majority of respondents (75%) indeed do this, which is great news.

An important facet and constant pain point of running multiple environments is the need to alter URLs in the WordPress database when migrating the database from one environment to another. I asked respondents how they typically deal with this problem and gave them an open field to type their answer. Here are some answers that came up repeatedly. These aren’t actual responses, but rather my representation of groups of similar replies.

“I don’t migrate between staging and live databases.”

“I don’t touch the database. I just export and import posts out of and into WordPress.”

“I use Dave Coveney’s PHP script for finding and replacing URLs in the database, including those in serialized data.”

“I do a find-and-replace on the SQL dump and the website’s files.”

“It’s a massive pain in the arse, and I steer clear of it.”

“I dunno. What is the best practice on this?”

Cowboy Coding

Finally, to gauge how strictly people adhere to general best practices, I asked respondents whether they ever cheekily edit code on the live server. Let’s be honest: this question is only ever going to yield one outcome. As expected, a whopping 76% owned up to having tweaked some WordPress production code in their time.

What We’ve Learned

In reviewing the lessons learned, it’s important to say up front that I am not criticizing the development and deployment practices of the survey’s respondents. The goal was to identify the areas where we, as a community, can become more professional and to draw some conclusions on how we might achieve that. You’ll find no finger-wagging or hyper-critical feedback for developers — just broad conclusions drawn from the responses.

Version Control

First, clearly not enough of us are using version control in our everyday workflow. This is a fundamental tool for any developer, and for 61% of those who self-identify as a developer or as both a designer and developer to say that they don’t use version control indicates that effort is needed in the WordPress community to educate developers on the importance of source-control management.

Still, while not enough WordPress developers use version control, that so many who do use Git is very positive. I prefer the decentralized approach of Git, and while WordPress’ core team still uses (and will likely continue to use) Subversion, Git brings many benefits. Suppose a few teams are working on a project. Each team could write to its own repository, and then a senior member of the quality-assurance team or an administrator could merge changes from all of those repositories into a protected repository before deploying the website. This approach makes a lot of sense if the website you’re working on is large and members of your team are dispersed, and it’s why I favor Git.

Environments

While a lot has been done to grapple with the issues arising from WordPress storing URLs in the database, the problem goes beyond WordPress’ core and extends to plugins and even to the pesky URLs ending up in serialized data. This is a pain in the arse at best, and a complete time-suck at worst. There are many options for overcoming this, but the most common choice is either not to migrate data from environment to environment at all or to use Dave Coveney’s PHP script. Both have their problems. For me, the first just isn’t viable, and the second, while perfectly acceptable, isn’t automated enough and is pretty time-consuming. There has to be a better option.

Free and premium tools and plugins offer solutions to this problem. One that came up a lot in the survey’s results was BackupBuddy and its migration feature. I’ve played around with its functionality, and, while it works perfectly well, it does not (as yet) work with Multisite, and I actually found the process more arduous than using a find-and-replace script. One project of mine that has emerged from this survey is to automate the find-and-replace process with a tool for Capistrano.

Conclusion

The survey’s results have shown the need for more education on professional deployment practices. Mark Jaquith’s talk “Scaling, Servers, and Deploys, Oh My!5” is a must-watch for anyone deploying WordPress websites. And the WP Stack63 project on Github and WP-CLI72 are also worth checking out if you’re interested in breaking free of the browser and speeding up your administration of WordPress websites.

For my part, I plan to start blogging more about professional WordPress deployment practices and to release more Capistrano tools on Github. Finally, I would love to hear in the comments section about the kinds of issues that you’d like to see covered in future posts and of any other projects that are moving this issue forward.

(al)

↑ Back to topShare on Twitter

Kieran Masterton is a technologist, consultant and writer working where the web meets film. He owns and operates 88MPH, a technology company focused on helping filmmakers and film-centric businesses build products and overcome digital challenges. Kieran has been coding professionally since 1998 and has worked extensively with Perl, PHP, Ruby, and WordPress.

  1. 1

    For migration I simply fire up PhpMyAdmin, hit up the wp_options table, and there is two entries where the URL is stored, its a 1 min change (including logging into PhpMyAdmin) and it’s done. Surprised many don’t do or know of this, granted you can balls stuff up, it’s a somewhat familiar interface (PhpMyAdmin) for many developers.

    6
    • 2

      Just so everyone understands the problem, that table only saves the main site URL. Any time you insert an image or link using WordPress’ editor—which is usually your testing server—it will actually use the full URL including the testing hostname. Unless you have a very simple site and are diligent about only inserting relative links and assets you’ll want to run a more detailed find and replace on the database.

      10
      • 3

        I have done several wp domain migrations in the past by updating both tables with a bit of mySQL

        Something like this :
        UPDATE wp_options SET option_value = REPLACE(option_value, ‘http://devdomain.local‘, ‘http://livedomain.com‘) WHERE option_value NOT LIKE ‘%{%’;
        UPDATE wp_postmeta SET meta_value = REPLACE(meta_value, ‘http://devdomain.local‘, ‘http://livedomain.com‘) WHERE meta_value NOT LIKE ‘%{%’;

        0
      • 4

        Thanks for the great article Kieran, deployment has always been the element I’ve felt my professional practice is at it’s weakest.

        For any new WordPress project I install Roots Plug and Root Relative URLS before I start:

        http://wordpress.org/extend/plugins/roots-plug/
        http://wordpress.org/extend/plugins/root-relative-urls/

        Then changing environments is as simple as Mark Scott mentions above without having to worry about the URLS of media inserted in posts.

        This is fine if you have control of the first setup before any content is added, of course on client projects you often have to deal with an existing WordPress installations. The plugin that Łukasz mentions later in the thread seems ideal for content migration.

        1
    • 5

      If your URLs are stored in a wp_options field as serialized data, then rawly changing the URL like this could screw it up if your development URL and production URLs are different lengths. This is because a serialized data stores an integer indicating the length of the text stored in a field.

      We tend to circumvent this by making out development URLs be http://www.whatever.dev, to match our live ones which naturally end in .com. Not a perfect solution, but a workaround.

      1
      • 6

        You could also just override the wp_options table and set the domain manually in wp-config.php.

        That’s what I do, and it’s a lot less painful than firing up a MySQL browser.

        1
        • 7

          Gabe Shaughnessy

          April 30, 2013 11:15 am

          Evan is spot on – override the options table and use a local-config.php and you won’t need to touch the wp_options table. Combining this with a relative url plugin and you shouldn’t need to replace any URLs.
          On one enterprise site I work on we use RAMP – from crowdfavorite – it is a great tool for deployment and allows a bunch of our content creators to work on a staging site while at the same time our development team is deploying new features and major site updates.

          0
          • 8

            Hi Even & Gabe! =O)
            I have found this to be a challenge with not only URL but plug in serial numbers… Especially if the license number has to be unique for each instance… and you are running several instances at once for failover scenarios.

            It would be cool to see some changes to the DB schema… split wp-options into 2 tables…. one for instance specific configurations like license numbers, domain name, etc and another for plug in configurations that can be easily deployed and replicated across nodes….

            This way when I replicate the DB I just copy over the one table and the other table can remain unique to the instance… If that makes sense… =O)

            0
    • 9

      Kieran Masterton

      April 15, 2013 11:30 am

      Hi Mark,
      As both Dave and Phil your approach is fine as long as you have no posts or 3rd party plugins that might store the site URL in serialised data. The few tools I mentioned help a lot when migrating databases with lots of posts etc.

      1
  2. 13

    I still haven’t found the need for using version control on my WP developments. Maybe it’s because I’m a one-man-band so there’s nobody who will overwrite my code. Maybe it’s because I make regular, organised backups of my work both locally and online. Maybe the sites I create just aren’t complicated enough to deserve it (I disagree).

    Windows isn’t the best platform for git and the few times i have used it (or subversion) when working in dev teams we’ve spent ages trying to get it all to work. And then when you go back to make an edit in a month’s time all the keys seem to have changed so that 2 second job turns into 3 hour job just so you can get access.

    So for me I can totally see the importance of versioning when building big coding projects, or even with a multi-user-developed plugin, but most WP jobs I just don’t get it. There’s not many WP sites that require more than one dev in the wp-contents folder.

    10
    • 14

      Version control for me is a must on every single project and 90% of the time I am a “one man band” as well. There are many reason to use a version control system (I use GIT and dev on Win8 of all platforms ha ha) and it’s stupid simple to setup. The largest hurdles are making sure your editor saves unix line endings on files and just learning how to use the version control

      It keeps a backup of my code, and not just a backup at 1 point in time, but a backup of versions of my changes with comments. So when a client says, wait, I liked it the way it was before….. it’s much faster for me to switch back. I tag regularly and can typically either pull down a zip from a “version” of the code and just swap or I can find the commit hash and roll back the file. I’m sure clients never change their mind on you though ha ha! (this is the same reason I use LESS or SASS as well)

      There’s a backup offline and it’s quick and easy to make those backups. I can assure you that git commit -A -m “Making some changes”; git push origin develop is much faster than making a 3mb+ zip file and uploading it via ftp to some remote server.

      GIT and Capistrano work wonders together. I pay a lot for a fast internet connection at my home office but I will never be able to beat out a 10gbps pipe from a GIT repo server to a development or production server. Plus with 78% of people admitting to changing code on a production server what happens when you make large changes in the future and forget about that 1 change months ago and overwrite it because you FTP the whole site back up! cap production deploy…. makes pulling git onto the remote server a breeze so you never make your changes on the server. It takes longer for me to ssh in, find the file, edit in vim and test a change on production than it does to make it locally, commit, push, deploy

      AND finally it’s more secure because I have no ftp connections to make and everything is using private/public keys.

      I also use my own servers and have everything setup as I need it 99% of the time anyway but I have done work where I’m not in control of the server and I just require an ssh connection and that GIT is installed; which it is becoming more common for it to be on the server than not.

      6
      • 15

        Kieran Masterton

        April 15, 2013 11:32 am

        Couldn’t agree more Michael, your workflow is very similar to mine.

        0
      • 16

        To me, both of your standpoints have merit.

        Most of my projects “don’t warrant” version control, but in a ways, I wish they did. I find myself one foot in towards proper versioning because as I come back to old projects (and I do mean *old*, as I’ve been working in webdesign for almost 10 years) I sometimes don’t recall what I did, especially when it’s about a small tweak to the core of a CMS (beit WordPress, Drupal, or whatever other CMS). This can become an issue when security updates come around and I don’t know how to get my site running properly again.

        Of course, this also stems from my background in UI/UX, as opposed to a background in programming, which leaves me with a lesser understanding of software structure, and significally hampers my powers of deduction in this area.

        I think, writing this, that I might give GitHub a go, since that’s what we use at work.

        Cheers for commenting to the both of ya.

        1
    • 17

      “There’s not many WP sites that require more than one dev in the wp-contents folder.”

      While this may be true, the beauty of git (arguably over other version control systems) is the ability to easily create feature branches.

      Let me sketch out a scenario, and you can decide if this would be useful to you…

      You finish a site and launch it. The client is happy.

      Some time later, they ask for a bunch of new features. An online store, say.

      You get cracking on the store and change a bunch of files. Suddenly the client wants to make some fairly minor changes to the current site: a phone number here, an email there, a few tweaks to the stylesheet, etc.

      Without version control, you’re going to work on a backup, and upload the changes to the live site. Now you’re going to have to port all those changes into your new online-store version.

      With git, you create a new branch based on the live site’s code. Let’s call it ‘tweaks’. You make the minor changes to this branch and push it to your test server (don’t worry about blowing away what’s on the test server: git will restore this later). The client approves the changes, so you merge the ‘tweaks’ branch into the live branch, and also your new ‘online-store’ branch. It’s merged in less than a second.

      Now you can push the ‘live’ branch to the live server, and push the ‘online-store’ branch back onto the test server. Happy days.

      I always work alone, and since I embraced git, I’ve found development more relaxed, more organised, and — this is the kicker — it’s more fun! You don’t need to be working in a team to get a lot of benefit from git.

      Git is also great for deployment, even if you’re stuck on FTP-only hosting (google git-ftp).

      I’d never go back to CVS or — God forbid — no version control.

      2
      • 18

        +1 Vote

        I’m glad someone pointed this out. I don’t know how many times I’ve had to use SVN in that manner. Run a parallel branch for future enhancements while maintaining the trunk for day to day maintenance and emergency fixes.

        Not to mention the ability to “back out” changes that may have unforeseen impacts on the production site or that occasional *whoops*.

        I feel many don’t want to bother with repositories because they typically see them as a multi-developer tool. I think for many it comes down to a lack of knowledge about repositories and the trouble it would be for them to set one up trumps their perceived benefits.

        0
      • 19

        Where would someone start if they want to learn to use Git in this way?

        Thanks!

        1
    • 20

      I agree – I see no reason whatsoever for version control. There’s just no need that I can even think of, no problem it would solve. I’m a freelancer working full-time with WordPress for about 5 years, and I talk regularly with a lot of other small-time freelancers.

      0
  3. 21

    The main hangup I have when developing sites using WordPress is how to easily setup a local development environment. When using Rails or Django, it is super easy to get going. However, all my experiences with developing with PHP and WordPress locally is painful. Are there any solid solutions out there to aid that part of it?

    0
    • 22

      I’m just getting started with WP and – if I understand this comment correctly – then I couldn’t agree more. I cannot find a straightForward method for developing locally then pushing to a live server. HELP!

      0
    • 23

      you could just run an install of LAMP or MAMP or WAMP. It would only take a few minutes to setup and run on your machine

      2
      • 24

        Wampserver or Xampp, I don’t recommend Mamp because Macs are unix already so setting up mysql and apache is simple. If you like Rails then try CakePHP instead of WordPress. Those two are apples to oranges but Cake is just like Rails, only for PHP. Otherwise, definitely install one of the prebuilt lamp stacks (minus the L) and WordPress is a breeze from there.

        0
    • 25

      Or, heck, even Microsoft WebMatrix; it’s really easy to set up a local environment.

      0
    • 27

      Use a virtual machine running CentOS (or your preferred distro) to run not just one local WordPress install but all your development projects.

      0
    • 28

      XAMPP + Bitnami. Donezo.

      0
  4. 29

    Yep, the switching between environments is terribly handled in WordPress. I mainly work with WordPress and Drupal, so, I know the difference between them: with Drupal you don’t need to do nothing when changing the environment.
    Usually, with WP, I adopt a find-and-replace on the database and it’s enough to accomplish the switching… but is a real no-sense seeing one thousand (or more) repetitions of the same string when it would be enough to set just one time (into wp-config for example).
    That’s should be the primary feature to be considered for future releases of WordPress.

    3
    • 30

      Kieran Masterton

      April 15, 2013 11:37 am

      The WP core team are very cautious about making big changes that could break legacy code. I think it unlikely that they’ll consider removing the site URL from the database. I think our best bet is to streamline our workflow by encouraging and contributing to tools like WP-CLI and tasks for Capistrano to make our lives easier.

      0
  5. 31

    CowboysTedCowboys

    April 15, 2013 4:28 am

    On migrating between development and live databases:- “It’s a massive pain in the arse, and I steer clear of it.” and “I dunno. What is the best practice on this?” shows EXACTLY why more than half of my clients that come to me for WordPress sites/fixes are INCREDIBLY cagey about pretty much everything. I’m a reliable, fair, and honest developer – and I get masses and masses of clients who question my every move, want updates every four seconds on everything, want to wait until a site has been live for a month (“just in case”) before paying me, and who point a finger directly in my face and shout “THIS IS YOUR FAULT!” any time they do anything wrong.

    There are too many people out there claiming to be professionals, who charge ridiculous money, but who can’t even migrate a development database to a live server.

    It’s the main reason I’d ever consider getting out of the industry, if I’m honest. My portfolio doesn’t matter to anyone any more. All that matters is that they paid somebody from a far-off land $4,000 to build them a WordPress site, and ended up with a site that didn’t do what they wanted it to, and now they’re having to pay me to fix it, and somehow…that’s MY fault.

    4
    • 32

      TBH, these are actually one of my favorite kinds of clients. They got burned so they really need someone to clean up the mess—and you can usually charge accordingly. If they balk at your price, it’s because you haven’t sold yourself as more valuable than the designers who just burned them.

      Never blame your clients. For one, they weren’t born on how to select a good provider. Just work on selling your services better. The big fat lie is good design/service sells itself.

      8
    • 33

      Uhm if you could point out some links on how to “migrate a development database to a live server” I’d really appreciated it. :)

      0
  6. 34

    I use GIT: Github for VC and their app: http://windows.github.com/

    0
  7. 35

    ‘Cowboy Coding’??
    I do it all the time. Thought everyone did
    That’s part of the fun!
    Didn’t realize I was a cowboy though.
    ;)
    Alan

    0
  8. 37

    As a front-end developer at a small agency who is just dipping his toes into Capistrano, the promise of it being able to automate the wordpress content migration (changing URLs) is awesome. Really looking forward to seeing that hit the scene, it would be a major contribution to the community.

    One cool Idea I heard recently for keeping your staging area up to date and your uploads out of your source control, was to put an .htaccess file in your wp uploads directoy that looked on the production server for any files it could not find on the localhost: http://stevegrunwell.com/blog/keeping-wordpress-under-version-control-with-git

    .htaccess part is the last code snippet near the end of the article.

    0
  9. 39

    Regarding Dave Coveney’s PHP script and that it’s not “automated enough and pretty time-consuming”: This sounds like the GUI version of the script. Since about two months there’s also a CLI script available: https://github.com/interconnectit/Search-Replace-DB. Maybe this helps a bit.

    3
  10. 40

    On this website is a nice article about moving a WordPress site to a new location:

    http://wp.smashingmagazine.com/2013/04/08/moving-wordpress-website/

    There I discovered this nice script (Serialize-aware search-replace-DB): http://interconnectit.com/products/search-and-replace-for-wordpress-databases/

    I tested it and so far it works fine.

    Version control: I am a one man show and therefore I don’t have the feeling I need it. I tried it once but I decided my time is spend better on learning other things (better jQuery skills :)

    3
  11. 43

    Ujamshi Khandla

    April 15, 2013 6:43 am

    an awesome article.

    0
  12. 44

    I’ve been working with WordPress as a freelancer for a while, but recently as part of a larger team. The way they do things really opened my eyes, they have test, staging and live servers, an automated deploy process, and of course use git/github.

    I would love to offer this level of service to my smaller clients but much of it just seems overkill for their purpose. A simple change can sometimes take weeks to go live.

    Most of the smaller guys come to me with existing sites and/or hosting accounts where I have zero control over the environment. My local machine IS the testing server and if I want them to see something “on dev” I usually use a separate live hosting account of my own behind a password. If I’m lucky they have CPanel and PHPmyadmin but sometimes FTP and WP backup/restore plugins are the only way in.

    I do offer hosting as a service package (includes WP/plugin upgrades etc.) but most small businesses / solopreneurs I work with are just starting out, want to save their money and buy a hosting account at GoDaddy, and can’t yet understand the pain of not upgrading.

    What I would love is to have all these smaller sites on a multi-site install that pulls from github and manage everything myself. But I think that might be too much to ask for…

    1
  13. 45

    Interesting read.
    I fall into the freelancing designer/developer category. I recently started using Git. Took a few days or so to set it up and getting to know it but now I am used to it and find it indispensible
    Since I work from separate computers both at home and in my office I can’t really work locally, so I develop my WP sites on a temporary webserver. My local files are synced through Dropbox.

    Biggest hurdle in moving a site back and forth between the testserver and the production server is indeed the migration of database. Especially if you’re doing lots of custom fields/custom post type things, which alter the DB contents. I know how to use PHP admin or do a search and replace on the SQLdump, but still it doesn’t always work out as expected.

    For me the ideal situation would be to make my alterations on my testsite (whether locally or on a testserver) and then, after testing, simply “publish” the changes to the production server, including the DB, without the need to go into PHP admin or do search and replace.

    Now if I understand it correctly this Capistrano thing could do this, is that right? So if you could post on this in more details it would be most helpful.

    0
  14. 47

    Establishing a codebase for your WordPress sites to work off of while maintaining their own theme folders is absolutely essential in maintaining multiple WordPress sites. It negates a lot of the issues.

    0
  15. 48

    …67% said they earn their living from WordPress, which suggests that WordPress developers are generally more inclined to stick with one platform than designers, who are perhaps more agonistic.

    No, it doesn’t really suggest that, Kieran. It suggests that designers make their living doing more than just cranking out WordPress sites. Even the digital-only designer/devs (like myself) are far more likely to make money off of branding, logo design, banner creation, social media marketing, content development, etc. as we get more of that work. By contrast, a full-time dev is more likely to be offered more dev assignments for his/her income (and rightly so).

    0
    • 49

      Kieran Masterton

      April 15, 2013 11:27 am

      Hi Dave,
      I think you’ve misunderstood what I’ve written there to be in some way negative towards Designers. That wasn’t the intention, I was simply making a general comment that it is likely the Developers come to specialise in WP development while Designers tend to be get non-platform specific work. Perhaps I could have been clearer, but I think we’re basically agreeing.

      0
      • 50

        I didn’t take it as negative. I simply think you reached a conclusion (that designers are platform-agnostic) that the data doesn’t necessarily prove. Other data types would be needed to make such a case. I was also adding something the data didn’t show, that I knew to be true (designers make their living from more than just development work). That’s all. :^)

        0
      • 51

        There has never been a distinction between “designer” and “developer” in my 14+ years producing websites. I do both and have always done both. In fact, among the dozens of colleagues in the industry I communicate with regularly, that distinction is pretty much useless.

        I think there’s a lot about that large percentage of WordPress users who are freelancers or small businesses that is very different from the world of agencies and corporations, which viewpoint this article seems to come from.

        0
  16. 52

    I use two environments, dev and production, URL being the same. Vhost setup is pretty easy, I wrote a post on it: http://zigotica.tumblr.com/post/12963774869/how-to-use-vhosts-in-wordpress-development

    1
  17. 54

    Great article, but after reading it I felt guilty. Perhaps that was the idea, but to be honest I am not really sure why. I am kind of freelance although strictly speaking I run a small business with a family business.

    I use FTP without any version control. However we so have dev, staging and live WP sites. We use InfiniteWP which I highly recommend. It enables us to manage multiple websites and keep them all up to date from one dashboard. Most importantly it allows me to clone a dev or staging WP website onto a live one really quickly.

    Our dev and staging sites are on the same server as our live ones. We don’t develop locally. I know a lot of people will think that is mad, but it is the way I have always worked and I don’t see it being a problem. It means the client can easily view it by entering a password and it is much easier to set up particularly when developing from multiple computers.

    The author of this article makes it clear that he is shocked that people are still using FTP and not using version control to develop and manage WP websites. However, why? What is wrong with FTP? What are the big advantages of using version control especially for those like me who are freelance or who run very small businesses?

    0
    • 55

      Kieran Masterton

      April 15, 2013 11:59 am

      Hey Ian,
      Glad you liked the article and the point of the article certainly wasn’t to make you feel guilty. My hope was to highlight some of the places we can encourage professional deployment practice in the WordPress community. My reason for disapproving of FTP is that FTP was first developed in the 1970s and is generally considered insecure, both passwords and data are sent un-encrypted and while it isn’t totally incompatible with using version control it does make workflow clunky and awkward. The advantages of using version control on your own is chiefly for your own peace of mind while coding but also because it engenders good development practice for when you do work with a team. Here’s a good answer on SO to the VC question: http://stackoverflow.com/questions/1408450/why-should-i-use-version-control

      I should add that I do think that best deployment practice does depend on the scale of your team, the websites you work on and the infrastructure you’re deploying to. So I don’t think anyone should feel guilty for not following these practices. I’m just keen to encourage developers to adopt technologies like version control and Capistrano when working with WordPress in order to encourage professionalism in the WP community.

      0
      • 56

        Thanks for your reply. Because I have been working on my own I have developed a way that works for me. I am well aware that there are probably better ways, but if it ‘aint broke don’t fix it has kind of been my thinking.

        I understand the security concerns with FTP but I have an encrypted connection via a VPN and I tend to use SFTP. Yes it is probably clunky but it works well.

        I know I am not the only one in my position- not all of us work in teams and have the advantage of bouncing ideas and skills around. I’d be very interested if Smashing Magazine had an article on best practices on developing WordPress websites with how tos on version control and git. I just haven’t had the time to invest in learning how to use these tools. There seems to be a big learning curve. Being a Windows user they also always seem to be biased towards Mac users.

        A detailed article on how to move away from FTP to using git and version control would be really awesome- spelling it out for us who have been using FTP for years and are afraid to shift.

        7
  18. 57

    Really interesting survey, I’m surprised how many developers don’t use version control. I suppose this could be down to the large amount of freelancers using WordPress but even if your working on a project by yourself source control is a great way to keep a history of your code. Also you can use it with something like phing to easily deploy your code to staging/production servers.

    0
  19. 59

    WordPress move plugin has a migration tool and work very well. Also it’s good for save backups.

    0
  20. 60

    Hi Kieran. Interesting research and nice article! I have yet to take the plunge and integrate version control in my workflow. The biggest obstacle for me is that using GIT is simply too cumbersome and slow. It doesn’t have to be but as a freelance designer-developer the websites I built, are deployed on shared hosting servers. Without SSH access and the use of 3rd party scripts it is impossible to easily push to production (as I understand it).
    I find the conclusions you draw therefore not that remarkable because the demographic is mainly focused around freelance/small business/small agency. In this particular segment you will find a lot more cowboy coding, FTP-ing from IDE to live etc. I am sure that at medium sized agencies and with seasoned freelancers, project management (agile) and workflow is more professionalised looking at security, efficiency, versioning.

    Looking forward to your new blog posts ;-)

    2
    • 61

      Kieran Masterton

      April 16, 2013 1:02 am

      Hey Tim,
      I’m afraid I disagree. I think that in order to improve the sometimes unprofessional image of WP all developers working with WordPress need to think about using these technologies. Personally, I wouldn’t work with a host that didn’t allow you SSH access to the server and I think once you go through the learning curve of working with Git etc. the benefits far outweigh the time it takes to get to grips with them. I’ve worked in all different sized teams using WP and the need for versioning, security and efficiency has always been paramount.

      Personally, I think this is even more true when you’re a freelancer because a security problem or the loss of an important piece of code can cost you a huge amount of time and there’s no team there to back you up. I’m effectively a freelancer and I couldn’t live without these technologies. That said, I certainly appreciate that the immediate need for them is sometimes less evident when you’re not collaborating but that doesn’t mean they’re ineffective. I really would encourage freelancers to abandon FTP etc. and add version control, ssh and the likes of Capistrano to their workflow.

      0
    • 62

      “Without SSH access and the use of 3rd party scripts it is impossible to easily push to production (as I understand it).”

      You just need one 3rd party script: git-ftp.

      It’s trivially easy to use (1 minute to set up a new remote), and it knows exactly which files are different at the remote end, so you only upload the changes. Branches are fully supported.

      Really, try git: you won’t regret it! And see my comment further up for why git is just as good for one-man-operations.

      1
    • 63

      If you need to deploy over ftp (sometimes there’s no other option) look into something like http://beanstalkapp.com/

      0
  21. 64

    This feels like the right post to ask this question.

    - I am just a user of the WordPress, that means, can get by installing WP, set up a Genesis Framework / child theme, and maybe tinker with CSS a little bit, that’s all.

    - I run an online weekly magazine with WP+Genesis framework. I use a separate WP installation called “staging” on the same server, and every week I finalize my posts, along with inner images, plus featured images, on this staging site, and on the day of weekly update, I quickly manually copy all my new images, WordPress Import/Export my new articles to the live site.

    - But it takes at least 3 to 4 hours every week and all that time my live site is in an awkward redressing mode. I don’t want to put “Updating, Coming back soon” page because for some reason Facebook is showing “Updating, Coming back soon” when I link my new articles.

    - I am pretty much fed up with this. I want to move away from WordPress and want to know if there are any real magazine content management software out there that you can recommend. I mean how do sites like Smashing Magazine, or Mashable or even The New York Times for example, how do they do it?

    - Some people suggested Backupbuddy to do backup / restore every week, but that’s not the solution. What I need is a sort of MERGE utility that really really takes all my featured images and posts and everything else, and drops them into my live site.

    Any help? Thanks!

    Raj

    0
    • 65

      Kieran Masterton

      April 16, 2013 12:52 am

      Hey Raj,
      My question would be why do you prepare your posts on stage? Typically staging is used to demonstrate new features etc. and sometimes testing but rarely is new content prepared there for going live. Normal workflow for new posts on WP is that they are saved as draft, reviewed by any editorial staff and then published, all on live.

      If you are keen to keep this workflow for a particular reason I’d suggest simply exporting the desired posts each week and importing them on to live. Then you can let WP deal with grabbing the assets from stage and adding them to live. That said, if your staging site is not accessible from live or has auth in front of it you’ll run into problems. I think the key is to rethink your editorial workflow.

      Hope that makes sense, and I’ve understood your question correctly.

      0
      • 66

        Kieran,

        Thanks for the reply. One main reason we prepare posts on staging site is to finalize the entire front-page of the site, not only just the content of the each post, correctly ordered and placed. For example, this week we may have a flash announcement, or a new feature announcement etc., and we reorder the feature items on the front page. We use the “Featured Posts” widgets (we use Genesis Metro theme) to move articles around from week to week. If we freeze the positioning of the features (third post is always a serialized story, 2nd item on sidebar is always an image etc.) from week to week, then yes, what you said about editing new posts in draft mode on the live site, works quite well. But in our case we can’t be mucking around with reordering posts on a live site, obviously.

        And by the way, for a gazillionth time, the WordPress Import/Export does not work when it comes to featured images of the posts. When I import the exported-xml file, I check on that field about images and attachments, but it just doesn’t bring over the featured images. That fix alone will eliminate my weekly work by half. No one seems to pay any attention to it anymore, or I must be doing something very obviously wrong in using it. Anyway…

        BUT (:- ) ), what you said above might be a clue. My staging site is an entirely separate WP install (though on the same hosting server), and I have different prefix for the WP database. Perhaps I should think about making at least the media location common to both staging and live sites. I might try that…thanks!

        Raj

        0
  22. 67

    For transferring data open PhpMyAdmin, find wp_options table, only two entries are there where the URL is stored, change them with your desired one and you are done.

    -5
    • 68

      Kieran Masterton

      April 16, 2013 12:45 am

      Hi Aamir,
      Sadly that isn’t the case, the site URL is stored all over the database whenever insert an image for example the absolute URL is inserted and stored in the posts table. Likewise, often 3rd party plugins store the URL in serialised data. If you are working with a fresh new db then your method works but if you have large quantities of posts the number of URL instances can run into the thousands.

      1
  23. 69

    Great article! Its interesting to learn more and more about website design although I have mine outsourced by a media agency that have done wonders with the design of my website. But learning more and more about website design helps me understand what the designers are talking about in meetings. Check them out and see if they have services that could help your business: http://www.roimedia.co.za/

    -12
  24. 70

    Setting up Git for the first time is a pure pain in the ***. I’m not surprised that the majority of people give up after two days of trial and errors.

    0
  25. 71

    We recently took the plunge and setup Mercurial to give a client a test server and live server. It was all setup by someone else who works on the site, and all I had to do was pay for a PHPStorm license to make it easier for me to push/pull updates.

    It’s been running for a few months now but I’m afraid I’m just not impressed by the new setup. I just find it makes things more complicated on a day-to-day basis which is why I haven’t bothered proposing the idea to other clients.

    I may be biased with my decision, because I can’t push changes from the test server to the live server, only the other developer can do that. When I get the irate client needing an immediate change I can no longer just develop locally and FTP, like I did for years previously, I have to fire up VM Virtual Box, open PHPStorm, update the project, make the changes, push the changes to the test server, check the test website to make sure its okay (if not, tweak and push again), and then call up the other dev, and if he answers his phone, ask him to push it live.

    There have been so many small little issues where previously it was a 2 second job, such as when I needed to manually generate some thumbnails locally to replace corrupt ones on the live site. I FTP’d them to the test server only to find that it couldnt be done this way as everything must go through Version Control (which is the whole point I suppose), but that meant emailing myself a zip archive of the thumbnails, going back into the Virtual Box, downloading the images from my email to the virtual box, then importing them into PHPStorm etc…. Its the same problem with the database – everything needs to be done with version control and it just slows down the whole process when previously I would run a query locally, and if it worked, I’d run it live – updating the client minutes later to say “job done”.

    I can see and understand the appeal of VC, and admittedly it has allowed the two of us to work on seperate changes to the same files without conflict, but that is such a rare occurance anyway that I’m not convinced it has been worth all the extra hassle.

    Edit: Just to add, the site I’m talking about isn’t WordPress. It’s a fairly large ecommerce site, busy enough to afford paying the two of us to always be working on it. For the record I believe my client has looked at the test deployment once in 6 months. He is running a business and doesn’t have time to check and confirm every little change on the test server just to then give us the “okay” to go live.

    1
    • 72

      I understand where you’re coming from; I often wonder if the extra overhead is worth it. Maybe I’m bad but I don’t follow a strict version control process.

      The only real version control I use is when I’m doing updates to a clients theme that are significant enough that I’ll create a new version of that theme, and backup and replace the old one.

      For a guy like me, is there any advice or ideas for how to add VC into my workflow?

      0
  26. 73

    This article is a great starting point. There are a lot of us out there who wear the developer hat but don’t have best practices for workflow. I went to school for print design and ended up becoming a front-end developer in freelance/small shops and learned all things web based the DIY way. I’m ALWAYS looking for ways to up my game so when I meet real developers they don’t mock me when I walk away. (Well, maybe for other reasons but not for the work I do. ha ha)

    I’d love to see an article on MySQL/databases targeted for beginners, and using SSH if all we’ve ever learned is FTP. If these are already written on Smashing, then I obviously should go use the search tool and read up. I don’t use GIT, but after reading this, I plan to start learning it.

    Thanks for a great read!

    0
  27. 74

    I use WP Migrate DB which takes the same amount of time to search, find and replace url’s as it takes to export the DB. No need for BackupBuddy which only slows down the process.

    0
    • 75

      Another vote for WP Migrate DB. This free plugin changes URLs and file paths (e.g., /home/my_site/public_html). It catches serialized strings and updates the length field. It’s especially handy when migrating from a test server that clients have been adding content to, as it’s impossible to teach them not to include the full URL for internal links in pages and posts. This way I don’t have to worry about it.

      0
  28. 76

    I develop in 4 environments: local, dev.website, staging.website and http://www.website.

    My local and dev environments share a database. Staging and www share another. I never worry about syncing the databases. After all, I’m updating code in my development, not data. I view the local environment as my environment to see changes immediately with dummy data. The dev environment has the same server settings as my live environment, just with dummy data in the DB. The staging environment has the live data with the same hosting setup as live. And the live site is…live.

    I use conditionals in my wp-config to define constants based on what environment I’m in. I dynamically set WP_HOME, WP_SITE_URL, WP_CONTENT_URL, and database credentials. I use an a filter to change the uploads url based on what environment I’m in.

    I use git to push my whole website directory ( Non-WordPress files and WordPress ignoring the uploads folder) from local => dev => staging => www branches of a git repo. My repos are hosted at http://www.beanstalkapp.com, and automatically deploys files via SFTP when I push commits to a branch. Beanstalk App is integrated with Harvest App, so I can log time towards projects in my git comments.

    All of this takes about 30 minutes to set up once you know what you’re doing. I would hate developing without this process.

    0
  29. 77

    People don’t use phing and git for deployment? Jayyyysus….

    0
  30. 78

    Hey Kieran, thanks for writing this. I’ve started using Git but really just on the surface. I would love to learn about remote deployment in plain, non-developer language. Where are you blogging about professional WordPress deployment? Is it right here on Smashing Mag? I would really love to read more in this topic and don’t want to miss your posts. In the meantime ill start with Mark Jaquith’s talk :)

    0
  31. 79

    I develop all my sites using MAMP on my machine; and with WordPress I use Sequel Pro to create my databases locally.

    Once I’m ready to deploy, I upload the site files to a non-indexed folder, export the database, do a big find and replace to fix all the URLs, and import that into the deployed database.

    Once a client has approved the website and made their final edits, I flip the switch, so to speak.

    Like most of you I struggle with the URLs sometimes, particularly in the serialized widget data. Best solution I can come up with is to suck it up and re-build the widgets; but it’s really not so bad.

    If anyone wants to read more on my workflow please do, I hope it helps some of you.

    0
  32. 80

    We use local, sandbox, staging and of course production environments using GIT for version control and Capistrano for deployment.

    As for database migration we use:
    http://wordpress.org/extend/plugins/wp-migrate-db

    We are still defining a process to fully automate deployment, uploads directory is a pain as this can’t ideally be in GIT as the client needs the ability to add to it.

    1
  33. 81

    Any decent host will handle migrations, usually for free, and server backups, FTP, phpMyAdmin or WP import/export methods are perfectly adequate for non-complex applications, so it’s not surprising these approaches to deployment, migration, and revision is the rule, not the exception.

    I’m not sure this is necessarily less “professional” or a problem. That probably depends more on knowledge than technique, except when technique impacts security, like FTP. It is one thing to not provide things out of scope and not in a project budget and another not to know what they are or how to provide them at all. That said, a lot of people doing low-end projects are doing them because they don’t have the knowledge to move up the market, and maybe they’re fine with that. If you think they should work differently, where’s the value for them? Why use Cyberduck, ServerPress and Git instead of cowboy coding with Filezilla, a theme generator or drag and drop “framework,” some of which advertise themselves as businesses in a box for people who can’t code and don’t want to? A lot, if not most, of the WordPress economy revolves around the idea of cheap websites for and by people who don’t want to deal with any kind of code.

    If the survey had correlated agency size, revenue, and project/client value with the techniques and systems used, it would almost certainly have shown that complex, high-value projects with big budget clients are much less likely to get the cowboy coding and zero version control. (If you asked, you’d probably also find that high end agencies do “unprofessional” things like put key passwords and client data in shared, web-accessible documents, aren’t in compliance with privacy laws, and don’t write business continuity plans for their clients that outline what to do in case of a disaster.)

    There is probably a price point that simply reflects how most WordPress “solution providers” (such as they are) satisfy demand for low-budget, one-shot site-builds by customers who have no idea what things like version control are or why it might matter. Whether it’s a piece of brochureware or an active publication they want construct, they think they are buying a fire-and-forget “website” that should hold up for 5, even 10 years. They are closed to or simply unaware of the idea that they might need an ongoing consultative relationship with a professional of some type in order to truly discover and reach their objectives. That may or may not be appropriate or possible, depending on the project specs and budget.

    You might say a stitch in time saves nine, so it’s always best for the bottom line to “do things right” from the start, but often there is no long run or botom line except for web professionals operating as consultants and long term service providers who have ongoing work and income from their clients. The large number of freelancers and others who do not work this way lack not only incentives but the relationship with their clients one needs to have in order to make a professional go of things like security, performance, and maintenance

    So rather than advocate a one-size-fits-all best-practices model, a better conversation might start from the question of how to do the most and and the best with the lowest acceptable outlay of time, skill, and money — and maybe most importantly how to establish a business and clientele that can afford to operate at that level, or preferably higher.

    0
  34. 82

    The easiest solution to having different domain names in different environments is *not* to have different domain names: keep them the same, and use your hosts file to switch between dev/stg/prd environments. I wrote more about it at teleogistic.net/2013/04/using-a-hosts-file-for-easy-management-of-dev-staging-and-production-wordpress-sites/

    0
    • 83

      I agree that using a hosts file can be helpful to avoid having to change the URL, and, on occassion, do do this myself. However, if you’re running your local / dev / stage / whatever server on an abnormal port other than 80, you’ll still be stuck with the same problem.

      0
      • 84

        Other limitations include the requirement that the staging site not be on the same server as the production site, and if you want to let others (like clients) look at the staging site, they have to be able to manipulate their hosts file competently too. (It’s not for everyone.)

        0
  35. 85

    We have been developing all sites locally then moving them to staging for clients approval and then to live.

    For deployment we have found these plugins and tools the most useful:

    - SVN for version control
    - Beyond Compare (PC only) for deployment – simply compare local folder with live or staging and move changes across
    - WP Migrate DB – Brad just released PRO version but even the free version works fine

    WP Migrate DB is also great if you are moving site with serialized data such as Gravity forms.

    Beyond Compare is by far the best software available for comparing folders and file changes. If anyone has recommendation for Mac alternative we love to hear it.

    0
  36. 86

    I’ve got into the habit of opening the .sql file in a text editor, then using find and replace from the old url to the new url. Often changes 100′s of table data. Including all images etc. Jobs a good’un.

    1
  37. 87

    Very interesting (and timely post).

    For me, several years ago I started using Git and can’t imagine life without it (for several reasons already stated).

    My dilemma right now is deployment.

    If I’m deploying to my own server, I have a process that I like. It’s not full blown Capistrano (that seemed a little heavy for me). I used to use a Git based workflow, but had some limitations there. Right now, I use: http://docs.fabfile.org/en/1.4.0/api/contrib/project.html#fabric.contrib.project.rsync_project.

    It’s Fabric (Python based) with their rsync add on.

    In my deploy script, I do the following (not all database steps are optional):
    - clean up temp files
    - compile my Sass or Less files
    - dump my local database
    - rsync the folders to remote environment
    - use curl to fetch Dave Coveney’s scripts (the CLI versions), run my search and replace
    - delete those scripts from the server.

    It works great and I love it. Very flexible and not too difficult.

    My problem lies when I do sites for clients with their own hosts and I don’t have SSH access. At this point, all is lost.

    I’m back to the slow, FTP deployment strategy and I don’t know how to fix that.

    1
  38. 88

    Wow – where to start…

    To all those who say “I don’t need / don’t use version control” the answer is “you do” – unless you have no backups and can never revert to anything beyond what is live on the day. If you do backup, then that backup process _is your VC_ – and to understand what the rest of us are saying about VC just think of ‘real’ VC as smart backup that allows you to selectively restore content, and keeps a comment log of what each ‘backup’ set contained. And a million other useful things.

    On the ssh vs. FTP issue – that is a non-issue – as long as your ‘dev’ ‘test’ ‘prod’ workflow works. The reason to use ssh is not for deployment but for troubleshooting – if you need to investigate and can understand what is going on on the live site (check logs, file permissions, make quick fixes). But as far as the ‘deployment tool’ is concerned the only question is whether it can easily and reliably deploy (and revert) your releases. Which is always going to be scripted in some sense, so which transfer protocol you use is irrelevant.

    And on the third strand – embedded absolute URLs – if WP wants to grow-up it’s community has to grow-up. Plugins and the plugin distribution chain need to have a ‘parental advisory’ policy that just says no to plugins that use absolute URLs. I don’t know enough WP internals, but I’d suggest deprecating the API that allows plugins to even discover what the full site url is….

    1
  39. 89

    Over recent weeks we’ve been reworking our WP development workflow. his excellent Smashing Magazine article has come at a perfect time.

    Interestingly our new workflow encompasses much of the recommendations in the article and comments.

    Advice on using Git (we use BitBucket) and Daves search and replace script are invaluable. We’ve tried other ways of replacing the domain string in the past and have found this script to be the best.

    We’re still looking at ways to streamline the process so Capistrano and looks very interesting.

    0
  40. 90

    Matt Kettlewell

    May 7, 2013 10:28 am

    I really think that there is a solution to this problem ( making deployments less painful) without breaking the existing & legacy systems…

    It just seems to me ( without really digging into the code ), that if we had a wp_option for a base directory ( ie. /home/webroot/ ) that could be set in settings and in wp-config.php ( just like the base URL ), and have wrapper functions that can be called that all of this would just go away as a problem

    So we’d have a function get_base_directory() that returns the base directory, and functions like get stylesheet directory() ( that returns directories like: /home/webroot/wp-config/themes/theme-name ) would utilize this base_directory.

    so deployments would only involve making changes to the wp-config.php file to change the base url and base directory… everything else ( plugins, themes & functions) would rely on the existence of this base directory, and anything that serializes this in database would need to alter the way they are doing things of course.

    And maybe even some flags in wp-config.php for the stage of deployment we are at ( ie. deployment_level = production (or staging, test ) and deployment_url=www.productiondomain.com ( or staging.domain.com, test.domain.com)

    And possibly it could check automatically if for the base_dir, and automatically set it, so that NO changes are needed

    This is me talking of an idea outloud without really digging deep into the problem mind you… so I could be missing something obvious, but I really think this is holding some folks back from doing it right, because there is unnessessary overhead in having dev,test,staging & production servers…

    But no matter what, version control absolutely should be integrated for every project ( large and small), for all the reasons mentioned above…

    Great article on wordpress workflows!

    0
  41. 91

    James Bohan-Pitt

    May 24, 2013 3:10 pm

    This is a great article and reaffirms to us at SiphonLabs that we were on the right track when we developed our WordPress Snapshot feature to help support better version control, staging and basic administration of WordPress sites. Our platform will actually clone an entire WordPress site, or simply the settings, theme and plugins, enabling the user to create a ‘development’ cloud to work on. You can make changes to the development cloud, snapshot the cloud and then inject it into the Production cloud. The whole process takes a matter of seconds.

    Our goal was to offer a toolkit to designers and developers to help them better launch, manage and version control their sites without being too prescriptive.

    If anyone is interested, we talk a little about WordPress Clouds and Snapshot features in our recent video – youtu.be/7eGaJDWMdrI, or check out our site siphonlabs.com/ for more info.

    0
    • 92

      Awesome survey. Super interesting. I’d be curious about the response from the Drupal community. I’d expect about the same! Let’s face it people are lazy and look for shortcuts.

      We’ve just opened up Pantheon – http://getpantheon.com to WordPress development.

      Pantheon is like a giant short cut for developers. Free sandbox accounts. So a lot of best practices come right out of the box and developers don’t have to worry about things like dev, test, live, version control, etc. It is all handled.

      Check it out: http://getpantheon.com

      0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top