Category: Blog

  • Minnesota: The north shore, a giant lake, and a lighthouse

    Wedding Week part two began with a drive from Madison to Minneapolis followed by another drive in the morning from Minneapolis to Castle Danger, an “unincorporated community in Silver Creek Township, MN”, nestled along the shore of the world’s largest freshwater lake, Lake Superior.(1)

    Silver Creek is a short drive north from Two Harbors, MN where we stopped for a bridal hair preview appointment. While Danielle was busy I gave myself a quick tour of the city that birthed one of the world’s most innovative companies, 3M.

    The company originally called “Minnesota Mining and Manufacturing” started in this humble location in Two Harbors.

    By the time we made it to Castle Danger there was just enough light for a dinner over last minute wedding planning. From the decks on our rooms we could see infinite darkness stretching across the lake, and looking up countless stars glimmering above. It was the first of what would turn out to be a phenomenally beautiful weekend on Minnesota’s North Shore.

    The next morning we decided to go for a bike ride. The hotel rented bikes for free and while none of them were bikes I would buy, they were suitable for the 20 mile ride to Split Rock Lighthouse and back. We headed out on the Gitchi-Gami State Trail, a network of 29 complete miles of off-highway bike trail that will one day connect Two Harbors and Grand Marais over 88 miles of bike trail. From Gooseberry Falls onward we rode on one of the newest stretches of trail, stopping along the way to pick agates, visit with boaters, and take in magnificent views of the North Shore.

    A scenic overlook from the Gitchi-Gami Trail near Iona’s Beach Scenic Natural Area, MN.

    It had been at least 15 years since I was last at Split Rock Lighthouse, and had forgotten its importance to the region. It was built in response to a series of wrecks cause by a large storm that hit the lake in 1910 and was a large motivator to extending the road that became Highway 61 up to Split Rock due to its popularity as a tourist attraction. I have to say the station is something to behold. While there we learned that it was built in such a precarious location that all kinds of clever—and dangerous—methods were used to supply the lighthouse and it’s keepers with basic necessities before the road was built. If you pay the admission you can climb the tower and get up close and personal with its Fresnel lens.

    A Fresnel is a type of lens constructed to project a beam of light visible for distances upward of 20 miles. This one is apparently “third order” and the light is officially visible at a distance of 22 miles, though the MNHS reports some fishermen could spot the light from 60 miles north of the station.

    By the time we arrived back in Castle Danger, our guests were starting to
    trickle in and the full wedding weekend really began.

    1. By surface area.

  • Wisconsin: Mud races, free ferries, and small towns

    The first day of Wedding Weekend brought us to Parfrey’s Glen State Natural Area in Southern Wisconsin, the first stop on our Saturday tour. Here, a section of The Ice Age Trail follows a creek bed that has carved a beautiful, fertile canyon that eventually brings hikers to Devil’s Lake. In 2008 a major flood washed out many of the boardwalks and natural walkways that long made up the trail and the beginning of it has since been paved.

    Once we were past the paved and gravel portions of the trail, we found ourselves amidst the serene beauty that is Southern Wisconsin.

    Along Parfrey’s Glen, a mossy wall carved into the ancient creek bed.

    (more…)

  • An open letter to a certain DC driver

    This is just to say,

    You’re right. I did turn left onto N St. from 11th St. NW yesterday. It was not even 8:00 in the morning but there I was, on Brooks Saddle attached to my Surly frame, riding comfortably in the bike lane until about a block before my turn when, signaling as I went, I merged: first into the right lane, then the left, then, finally, into the turn lane.

    Forgive me.

    I have a driver’s license so I know how hard it is to move that right foot from the accelerator all the way to the brakes in order to accommodate slower moving traffic in front of you. And how difficult it must be to see such inferior technology making its way through our city faster than the half ton pickup truck you were driving. Such amazing amounts of energy to go so slowly through an urban area. How much gasoline did you us on your commute yesterday? About a gallon? And there I was impeding you ability to use it more quickly.

    How thoughtless. I deserved to be nearly run off the road by you.

    But honking wasn’t enough for you to tell me how disgusted you were with my choice to make a legal left turn. No, you also had to stop at a green light and slow down everyone behind you so you could verbally let me know exactly how inconvenienced you were. I suppose you would have rather I darted into your lane without signaling. Or perhaps, better, you would have rather I sped up, crossed N half way and ridden in circles around the intersection before running the red light to cross 11th in front of you. That certainly would have made it easier for you to exact your death wish upon me.

    I swear to better reinforce dangerous behaviors in the future.

    Maybe I just have you all wrong, fellow driver, because even yelling at me wasn’t enough for you. No, you had to take it one step further and impersonate a police officer who could “lock me up” for turning left. I wasn’t aware left turning was a jail-able offense but thank you for sparing me, oh wise one. You are just looking out for the law abiding people of the District of Columbia. I assume you also honk and stop to berate every driver who has ever cut off a cyclist, or driven their car without headlights at night or through a snowstorm, or idled in a bike lane, or failed to signal a turn.

    Yes, I judged you all wrong, Driver. You weren’t a rude, snarling human being driving a vehicle 20 times the size of mine but a misunderstood civic activist, making sure that every traveler through DC’s streets is doing so to your liking. I should be thanking you for helping me better understand which vehicles are larger than others. I only wish I could have learned more from you. I hope we can meet again so you can teach me how to properly turn left on a bicycle, or how you might better design our streets to safely accommodate all modes of traffic.

    Best wishes from your favorite cyclist,
    Greg Boone

    Apologies to William Carlos Williams

  • JSON Resume

    A couple years ago my brother turned me on to LaTeX for writing and publishing documents. He’s a math guy and used it for just about everything he did. I’m not sure if he had a working copy of Microsoft Word on his computer, but he definitely had an updated MacTeX. I loved the What You See Is What You Mean philosophy behind TeX and the idea that content was code. I wasn’t a huge fan of how verbose it was both in PDF-generation output and, especially, in the front matter. After writing my first résumé in TeX I thought it was cool how I could write a document style that would show and hide different pieces of it depending on how I output it but, coming from HTML/CSS, everything seemed like it was more difficult than it needed to be. Wouldn’t it be great, though, if there was a way you could keep your résumé data in a standard format, with all the data required to build a full CV or a simple one-pager available when you need it? The JSON Resume project gets that process started. Using a standardized JSON schema, you can generate as complete or simple a resume as you want with a simple
    command: resume export. Check it out at http://jsonresume.org and on GitHub: https://github.com/jsonresume/resume-cli

  • My First Django Project!

    It’s no secret that I’m getting married in August. When the time came to build a wedding website, I saw it as an opportunity to try something new. That opportunity: build my first Django project.

    Prior to this project I had really only worked with WordPress and static site generators. That was fine if all I wanted out of my wedding site was a few pages giving people information about the wedding, but I could get that out of any boilerplate wedding site out there. I wanted more out of my website, and I saw a long list of things it could do, very little of which actually made it into the final product. The biggest thing I wanted, though, was to avoid having 65 tiny pieces of paper coming back to us in the mail to tell us who was or wasn’t coming. I foresaw disaster with things getting lost in the mail (probably would have happened), us losing them (definitely would have happened), and on top of all that, we were just going to manually transfer all that information into a Google Doc anyway. Why bother with the pesky middleman? Our Minimally Viable Wedding-site, then, would include an RSVP app, and I’m proud to announce it is finished, in production, and performing well.<!–more–>

    Why Django?

    Choosing not to stick with WordPress for this project was no small decision. Had we gone with WordPress we could have better integrated with the content on harmsboone.org out of the box. It also would have been easy to distribute as a WordPress plugin. While I haven’t had a ton of experience extending WordPress’s database layer, and I know it has a pretty extensive API for working with your MySQL instance in a safe way, writing this app in WordPress would have meant designing the data structures ostensibly from scratch. With Django, on the other hand, we have a highly flexible and intensely powerful web framework with database extension built right in. It’s been an absolute pleasure to work with and learn how to use it for this project, and I got to learn Python, too, which is a tremendously fun language to use.

    The MTV Pattern

    Django, for the uninitiated, is a Python web framework built upon a Model-View-Template (MTV) pattern (similar to a Model-View-Controller (MVC) pattern). In this way it’s not unlike Rails, Grails, or a litany of other web frameworks out there. The concept is simple. You separate your application into three parts: models, or representations of the data in code; views, methods that prepare data for display; and templates, HTML injected with variables passed from views. Thinking about the application in this way was amazingly helpful in figuring out what data we needed to collect about our guests and how we would use it. We added a hotels model so that we could better determine what kind of transportation we would need to and from the wedding site, and an events model should give us an accurate headcount of who will attend what. Since we didn’t have to mess around with complicated SQL queries, we could write clean, simple data models and quickly extend those models as needed. Here’s all the code we needed to start adding guests to our wedding:

    class Guest(models.Model): # we create a model for a single guest
      first_name = models.CharField(max_length=45, null=True, blank=True)
      last_name = models.CharField(max_length=45, null=True, blank=True)
      attending = models.BooleanField(blank=True)
      primary_email = models.EmailField(max_length=254, null=True, blank=True)
      street_addr = models.CharField(max_length=255, null=True, blank=True)
      city = models.CharField(max_length=255, null=True, blank=True)
      state = models.CharField(max_length=2, null=True, blank=True)
      zip_code = models.IntegerField(max_length=5, null=True, blank=True)
      primary = models.NullBooleanField(null=True, blank=True)
      events = models.ManyToManyField('Event', null=True, blank=True)
      hotel = models.ForeignKey('Hotel', null=True, blank=True)
      bride = models.BooleanField(default=False)
      groom = models.BooleanField(default=False)
    
    class Meta:
      ordering = ['-last_name', '-first_name']
    
    def __unicode__(self):
      return u'%s' % (self.first_name, self.last_name)
    
    

    One of the most powerful fields on a Django model are the foreign key and many-to-many fields which let you relate objects to each other in the database. At first wrapping my head around the distinction among these two was a bit tricky but after a few hours of playing around with it, I was able to structure my models so that they had meaningful relationships where necessary. In the example above, you see there is a ForeignKey relationship between the Guest and Hotel model. This was because each guest could only stay in one hotel (or if they were staying in more than one, we only care about one of them), but many guests could stay in each hotel. For events, however, we knew our guests could attend more than one, so we have a ManyToMany field there. This became especially useful when we made the front-end of the RSVP application. We wanted a way for anyone in a party to be able to RSVP or update their party’s information, but without having some way of relating all of them together, we had no way of knowing which guests were related to any random guest in our system. At the advice of a colleague I created a Party object that would hold some basic information about each group of individuals attending the wedding: who they are, how many of them there can be at a max (it’s +1, not +∞), and whether they have responded. This way, whenever any member of the Snodgrass family RSVPs, all of their data can be updated together, but we can still maintain separate records for each person—not all guests within the same party have the same address, for example.

    South (now Migrations)

    I’m going to say it now: I would have given up on this project were it not for South, a tremendous migration library for Django that, as of 1.7 was merged into core. A crucial missing feature in earlier versions of Django was a way of adding fields to a model after they were initially loaded into the system. If you tried, you would get this strange error saying that that field didn’t exist on the model; of course it didn’t, that’s why I added it! South lets you easily move your models forward by adding the rows in the database necessary to add that field. The coolest part of it is that you get this nice version history of how your models have changed over time. So, it’s really easy to go back to the first migration and say ‘what was I thinking!’

    Django Forms

    I really feel like I only scratched the surface of what can be done with Django Forms. Coming from WordPress I was used to writing my own forms in HTML and validation methods that prepare submitted $_POST data for saving to a database. Django approaches the problem differently. Writing a forms.py file is a lot like writing a models.py file. Each form is a class with a handful of variables and methods that define what kind of data the form should collect and what should be done with them. You can then drop a form into a View and prepare it to display in a specific way before rendering it in a template. In that last step, the entire form can be displayed with this code: `. When the form is submitted, checking that required fields are present and that the data are safe and valid is as simple as thisform.is_valid(). Saving it?form.save()`. Making a form that would add a guests +1 was as simple as:

    if partyForm.is_valid():
      partyForm.save()
    

    That’s it. Django makes some important abstractions in the process of creating and processing forms that helped focus development on how the data need to change.

    Next steps

    I’d like to refactor the views to take advantage of class-based views. One of the guiding principles of Django development is strict adherence to the DRY principle (Don’t repeat yourself). There is way too much repeating myself going on in this app. All but one view in the RSVP app starts with pk = request.session.get('pk') and guest = Guest.objects.get(pk=pk) and passes a global variable ‘bride’ and ‘groom’ to each view. This is super annoying! Django’s class based views should help me get passed that, but there wasn’t room for it in this release.

    Another thing that needs done is to split the RSVP app into it’s own project and make it installable with pip. It’s currently bundled in a repo with the Posts app which is ostensibly a clone of the tutorial’s blog app and a bunch of Django configuration crap that you wouldn’t need if integrating it with an existing Django project. There are also way to many static assets hard-coded into the CSS and template files. I’ll want to make those a bit more modular and perhaps even rewrite the CSS in less before it’s ready for reuse. All in all, though, it’s basically ready to go if someone else wanted to use it in their wedding website.

    Future versions of the app might also include a table manager, so someone could design their seating charts through the Django admin, and food options (our wedding is a buffet, so you get no choice on the RSVP). I’d also be keen on some design pull requests. I’m clearly not a very imaginative visual designer and while the CSS here isn’t bad, it could use a little love.

    Let’s face it, the list of what can go in a wedding website is unending. But this is a good baseline for building any of it.

    In the meantime fork the project on GitHub!

  • Flannel: A Python Project

    I’m a big fan of learning new things in programming. It’s part of
    why I tried running this blog on a static site generator only to get scared back onto WordPress, and why I’ll probably give SSGs another shot before swearing them off completely. I recently had the opportunity to work on a project in Python for work (in addition to a WordPress plugin) and it was an absolute thrill.

    The Problem:

    My client had a rather large WordPress site that relied on a home cooked theme, a few internally developed plugins, and a few plugins from the WordPress Plugin Repository. We also have a process for upgrading those plugins and WordPress core that is a bit more complicated than just hitting the ‘upgrade’ button in wp-admin. We also have a lot of users, not just registered users, but people who visit our website, too, who do not want the site going down, stop working, or unexpectedly changing dramatically. That is, we’re not facebook, we prepare our users for changes to their user experience. We had to maintain all those things but also make the deployment and upgrade process easier, faster, and less prone to human errors.

    (more…)

  • How can I Configure WordPress to Handle Dynamic Hostnames?

    An increasingly common problem enterprise-level WordPress installations will face is how they handle build, staging, and production environments where IP addresses inside a VPN use a different hostname to access the same server as those outside the VPN. In this case, the wp-config.php file is a little more complicated than in the famous 5-minute install.

    It’s somewhat common practice now to lock WordPress’s site URL setting in code rather than in the settings menu. Mostly people do this because it is good insurance that nobody will ever change them but at my client we do it so that local environments, and our private and public servers can all share the same wp-config. We did it, fairly standardly, with the HTTP_HOST key from the $_SERVER superglobal. It’s pretty neat and makes life really easy.

    We ran into a problem with our unified wp-config this week when a new load-balancing and proxying environment caused ‘HTTP_HOST’ to point at an inaccessible address in some environments. What to do?

    The proxy was ferrying our visitors around using a standard called X-Forwarded-For (XFF). If the user was coming from outside the VPN, their request would be forwarded through to the correct location. Simple enough but, because the requests are all pointing to an internal hostname, HTTP_HOST was resolving to an address inaccessible to the user and thus all our static assets were unable to load. The problem turned out to be easy to solve.

    As it turns out an X-Forwarded-For is often accompanied by an X-Forwarded-Host (the hostname the user was trying to reach). We simply sniff out whether $_SERVER has a X-Forwarded-Host key and set site_url and wp_home to the X-Forwarded-Host and fall back on HTTP_HOST for non-forwarded environments. Something like this:

    if ( array_key_exists( "HTTP_X_FORWARDED_FOR", $_SERVER ) ) {
        define( "site_url", $_SERVER["HTTP_X_FORWARDED_FOR"] );
        define( "wp_home", $_SERVER["HTTP_X_FORWARDED_FOR"] );
    } else {
        define( "site_url", $_SERVER["HTTP_HOST"] );
        define( "wp_home", $_SERVER["HTTP_HOST"] );
    }
    
  • Markdown&#58 It’s not for everyone

    Interesting perspective from Tom McFarlin on Markdown as a choice, not a default. He gets at an underlying issue of my struggle to fully adopt a static site blog where Markdown, with HTML as a fallback, is the default mode of entry.

  • Writing Integration tests in WordPress

    Integration testing, like unit testing, is a best practice with the goal of evaluating a piece of software’s ability to interface with the rest of a system. Earlier I elaborated on the distinction between integration and unit testing and I won’t repeat myself here. Instead I’ll briefly expand our definition of integration test and demonstrate how to use the WordPress Unit Test Suite to test a plugin.

    What’s an Integration Test?

    Tests which execute your code directly to determine if it properly interfaces with its dependencies are called integration tests. They require the greater system be installed in order to verify where a failure might occur. Unlike unit tests, integration tests do not necessarily test the correctness of your code as much as they do the system’s stability and your code’s interaction with it. For example, if we’re building a method to save data passed through a POST request into a database, a unit test would demonstrate that our method prepares that data appropriately and calls the correct methods for saving the data. An integration test would actually instantiate the database and save the record. For this reason, integration tests are more expensive. You’ll recall that the WordPress Unit Test Suite (WUTS) requires a dedicated MySQL database and a working copy of WordPress in order to execute tests. Reading and writing from MySQL can be an intensive process.

    For a plugin we are developing at my client, we had five tests that verified a feature. With WPUTS, the tests took nearly 42MB of memory out of our server, when we tested the same feature with unit tests, we shaved it down to 8, about a 5.25x improvement. The unit tests might be faster, but the data gleaned from an integration test is valuable in its own right. How else do you evaluate why a plugin fails when all of its unit tests pass? Perhaps it’s because you are sending the wrong data to the methods you’re mocking. Integration tests will catch that, unit tests won’t.

    How to do it

    First install WP-CLI as it will make everything much easier. The directions on getting the plugin tests initialized through WP-CLI are very clear and I won’t repeat them here. This will install a separate copy of WordPress and a separate database for testing. If you run phpunit from your root directory, you should output similar to this travis build. Passing tests validate the stability of WordPress, the failing and skipped tests are either incomplete or anticipate features in development. The tests will probably take under two minutes to execute depending on your system. If you cd into wp-content/plugins/your-plugin you should see a tests directory, a phpunit.xml file, and a bootstrap.php inside the tests directory. Run phpunit from your plugin’s root directory and it will execute any files which begin with ‘test-‘ and end with ‘.php’. Go ahead and create a test-your-plugin.php file inside the tests directory.

    ProTip:To change which files phpunit will pick up when you run it, modify the bootstrap.php file.

    Your first test

    As we did with unit testing, let’s start with a simple test we know will always pass. You’re going to want to first extend the WordPress unit test suite:

    class YourPluginTests extends WP_UnitTestCase {

    }

    Then inside that class, write a simple test:

    function testIsAlwaysTrue() {
        // Arrange
        $foo = true;
    
        //Assert
        $this->;assertTrue($foo);
    }

    `$foo` will always be true and that test should pass if you run phpunit. Now let’s take a look at some of the features the WPUTS has to offer.

    The factory

    WPUTS has a factory for creating things you might need for your tests. Let’s say we’re writing a method to check the title of a post. Since we have none, WPUTS should create one for us. Let’s write a test that checks if a newly created post has a title.

    function testPostHasTitle() {
        // Arrange
        $post_id = $this->factory->post->create();
    
        // Act
        $post = get_post($post_id);
    
        // Assert
        $this->assertTrue(!empty($post->title));
    }

    That’s a fine looking test, and it passes! But what does it tell you? Does it verify the `get_post()` method? In some ways it does, but it certainly doesn’t verify all of `get_post()`. In this case it mostly verifies that a post can be fetched out of the database. Let’s take the same method [we verified earlier][4] and write an integration test for it, only this time we won’t mock it. We’ll start with the same name:

    public function testTestPostExpectsMetaDataSaved(){
    
    }

    In our arrange section we’ll use the factory to create a post, and we won’t do any mocking. Remember, we’re interested in whether the system is functioning with our code in it. Our arrangement, in this case, will also include a variable `$expected` we will use in the assert section. The act section will be mostly the same, and the assert section will contain a check to `get_post_meta` and an `assertEquals` statement compairing $expected and our result. If all is well with our `save_meta_data` and the WordPress methods used in it, they should be the same. We can also write a message to print if the test fails.

    // arrange
        $post_id = $this->factory->post->create();
        $expected = 'New meta value'
    
        // Act
        $methods = new MetaMethods();
        $methods->save_meta_data($post_id);
    
        // Assert
        $actual = get_post_meta($post_id);
        $this->assertEquals(
          $expected,
          $actual,
          'Meta data expected to equal ' . $expected . ' but instead was ' . $actual);
    

    If we run the test now, it will either fail or error out because we haven’t written $methods->save_meta_data yet. Our development goal: make the test pass. Once this test passes, we can say, with a bit more certainty, that our method saves meta data properly.

    Unit and integration testing are similar but one distinct advantage of integration testing is that we can use the testing environment to experiment with core WordPress functions. We can use it to get under the hood, as it were, without digging through the codex and StackOverflow. If your unit tests are passing but your plugin isn’t working, try running an integration test and see if maybe you’re not feeding the mocked function the proper data.

    Testing of any kind allows you to think carefully about what your method should do and how to make it happen. Do you need a full post object, or do you need only the ID? Do you need all those conditionals? How much work is this method actually doing? The more you test, the simpler your code will be. Simpler code is easier to test, troubleshoot, and extend. It is important, however, to be mindful of the differences between the two concepts as they have implications for what you can and can’t say for certain about your code.

    As before, our full test is below:

    class YourPluginTests extends WP_UnitTestCase {
        function testPostHasTitle() {
            // Arrange
            $post_id = $this->factory->post->create();
    
            // Act
            $post = get_post($post_id);
    
            // Assert
            $this->assertTrue(!empty($post->title));
        }
    
        public function testTestPostExpectsMetaDataSaved(){
            // arrange
            $post_id = $this->factory->post->create();
            $expected = 'New meta value'
    
            // Act
            $methods = new MetaMethods();
            $methods->save_meta_data($post_id);
    
            // Assert
            $actual = get_post_meta($post_id);
            $this->assertEquals(
              $expected,
              $actual,
              'Meta data expected to equal ' . $expected . ' but instead was ' . $actual);
        }
    }
  • Using Composer to Manage a WordPress Installation

    The team at Roots.io have a fantastic walkthrough of Composer and why and how you should use it in managing a WordPress site. Composer is a wonderful piece of technology that reduces the headache of figuring out how to managing the individual components of your site to a single file and software solution. With WordPress, a utility like composer breaks an installation into discrete pieces. This allows you to automate deployments and updates of your site using only the composer.json file and isolating each part of your site to its own maintainable place. I plan to make composer-automated installations the default on all future WordPress projects I undertake.

  • Octopress: Six Months Later

    When I was a week into this blog, I wrote down some of the reasons I liked Octopress, my initial impressions of it as a blogging platform and whether it could compete or replace WordPress. It was a leap for me, a WordPress developer and long time fan of the platform. In general I have found Octopress to be an interesting experiment in hacker blogging but am back to WordPress as of this entry.<!–more–>

    Starting, as before, with what I (still) like about Octopress. There is still a lot to like.

    1. I love writing in Markdown. WordPress.com recently added Markdown support, so it’s only a matter of time before I can write in Markdown here without a plugin, but being able to practice What You See is What You Mean (WYSIWYM) while blogging without writing straight HTML is really quite convenient. When I write on WordPress blogs at work I often forget it’s either straight HTML (too cumbersome) or the TinyMCE What You See Is What You Get (WYSIWYG) editor (too unreliable).
    2. Simple local previews are another thing I really love. rake preview is up there with Django’s ./manage.py runserver test server in simplicity. What I would change is that the rake server is not nearly as competent as Django’s when it comes to compiling sites after making changes and letting you know about errors. For example, using quotation marks in categories causes errors in site generation with Octopress but the only output in the preview terminal is the somewhat unhelpful WARN Could not determine content-length of response body. Set content-length of the response or set Response#chunked = true. Nevertheless it is quite simple to get a full, local, site preview while you’re still editing.
    3. Accidental publishing happens less frequently. This relates to 2 in that you have to be pretty deliberate about publishing the post for the world to see. Saving the file locally preserves your work. rake preview let’s you see it in a browser (almost) exactly as it should appear. Getting it out in the public, however requires rake gen_deploy run from the terminal.

    With all that said, Octopress has a long way to go. Most of what I missed is WordPress’s user interface and content management features.

    1. Drafting posts. In WordPress, your post isn’t given a published date until you hit Publish, at which point it records the exact moment in time you hit publish as the date posted. In Octopress, this timestamp is added as soon as you execute rake new_post[]. I’m a drafter. Sometimes I’ll start three blog posts at once to get some ideas on the page and then put them aside until I have time work on them. (I started this one on January 1 and look at me now.) December 23, for example, I wrote Why Unit Testing Matters in one go. But I also started two follow on posts about writing good unit and integration tests. I ran rake new_post three times and each post had the same publish date even though the last two hadn’t been published yet! When I rake deployed, I had the post I wanted buried under two empty posts. When I finally finished the first of the others it was 2014 and I had to manually change the date and time as well as the published status. Manually managing these publish times was a bit of a nightmare.
    2. Visualizing published work. A blogging UI that can list posts and organize them by date and time published or category is incredibly useful when trying to reference older works. As is being able to quickly copy the permalink out of the admin (or right within the post editing UI in WordPress) and paste it into a link block. Octopress has no such mechanism and URLs can get really long. In fact, the permalink structure I’m using here is consistent with Octopress to maintain backward compatibility and I’m more or less stuck with it even though I’d rather it be much shorter.
    3. Version control over posts. This doesn’t matter to me as much anymore as it did in August. Markdown doesn’t version control very well anyway since lines are sometimes thousands of lines long. Also, with WordPress’s new drafting system, keeping track of changes in the post content is trivial and much more visual that it ever has been.
    4. Getting out. WordPress’s export/import functionality made switching to Octopress and it would have made switching back easy except that Octo has no similar feature. The upshot is that everything in Octo is straight HTML so importing wasn’t terribly difficult, but, manually re-entering the posts was time consuming and I’d rather not repeat it.

    Paul Graham tweeted recently that static sites are “the fixies of the Internet”. I found that a compelling metaphor. To extrapolate it to my favorite bike company, WordPress is a complete Long Haul Trucker. Well built, tough and reliable enough to last you a long time. Octopress is the Cross-Check frame. It looks like it can do a lot but it’s unclear whether it’s a fixie, for touring, commuting, or something else entirely. The DIY aspects have a lot of advantages but also puts a lot of pressure on the user to decide what to do with it. Octopress clearly has a lot of advantages. But at the end of the day all I really want is to sit down and write a blog.

  • How can I use PHP Namespaces in WordPress Plugins

    PHP has long had a problem of naming collisions. Because older versions of PHP had no way of declaring methods outside the global space, developers came up with several different ways of preventing and checking for namespace collisions, none of which treated the underlying condition. These many and varied solutions begged for a unifying standard as they made things like autoloading and package management increasingly difficult. PHP 5.3 introduced a feature called ‘namespacing’ to solve this problem and WordPress developers should begin adopting. With proper namespacing, WordPress plugin and themes will become clearer, more stable, and more portable.

    (more…)