Rebuilding Wardrobe: Week 3

Welcome to week three in the rebuilding Wardrobe series. This week my goals are to get migrations, repositories, and hopefully an admin editor all setup. If you need to catch on previous weeks check the bottom of the announcement post.

Let’s get starting with migrations first.


For the migrations I had to use the ones from v1 so that way people upgrading will have an easy flow. Laravel 5.0 now includes the ability to easily alter columns and I am hoping to make use of that for a few fields. Hopefully not much will need to be changed but I did notice a lot of cruft in v1.

Originally I wanted Wardrobe to be Tumblr style with a post type for image, quote, link, and standard text because that’s how I like to blog. I find that style great for sharing quick things I find throughout the day instead of having to write just text. However, now that these fields are included who knows if people have used them and with good faith I probably shouldn’t just remove them. Talk about an unexpected surprise.

The one exception to this is the tags table. In v1 I setup tags as a one to many. One post has many tags. This should have been a many to many. By changing it, managing tags will be a whole lot easier.

The question is… What would be the easiest way to migrate the data?

I think by creating a new “post_tags” table as the lookup and then utilizing an artisan command to move the tags and re-sync them will work. I’m not certain how clean that will be but they should be moved.

I’m going to build this command later so I can ensure all my fields and everything is setup properly before spending time on it. Now I’m ready to start moving into the workbench package code.

Wardrobe Package Code

If you are familiar with v1 then you may know one of my original goals was to allow any type of storage system. Database, flat file, dropbox, etc. I only launched with database support but planned around others in the code by creating interfaces to the repositories. Secretly I was hoping the community would add other storage systems but that never happened. Now though, Laravel 5.0 will include Flysystem and these other providers should be easy to include. So I will plan for that again but still only release with a db.

This week I started building out the post interface, repository, and a request class. The new form validation in Laravel 5.0 is really brilliant. Here is a link to the base request class and the create post.

Not much going on in these files yet but with a base class I should only have to worry about the individual form rules going forward.

With the validation set I created the PostInterface and a DbPostRepository. These are basically copied pasted from the previous version and are really basic right now. Next in the WardrobeServiceProvider I register the Interface to point to the DbPost. That way all the controllers will code to the interface and swapping out will be easy.

The final new feature I wanted to mention is I added an Event call after the post is created:

public function create(array $data)
  $post = $this->post->create($data);

  Event::fire('post.create', $post);

  return $post;

My thoughts here are this will allow third parties to tie directly into any of the CRUD operations. This opens up a lot of possibilities such as scheduling a social media post on create or modifying the data. You can use your imagination to come up with several other ideas I’m sure.

Route Changes

Another new change I’m going to make is with public routes. V1 had public routes inside the package and my reasoning for doing this was so if I needed to make any changes upgrading would be easy. So far these haven’t needed to be updated and I feel it’s more of a hinderance to the end user.

So I’m going to change this. Inside the base install I will include all the public controllers. Mainly home and posts then these will type hint the package interface and have a few basics setup. Something like this:

public function __construct(PostRepositoryInterface $posts)
  $this->posts = $posts;

public function getIndex()
  $posts = $this->posts->active();

  return view('archive', compact('posts'));

As you can hopefully see this will be more powerful and easier to use. At least that is my goal.

New Blade Changes

It’s worth mentioning that Blade has changed the tag pairs in v5. I actually wrote about this in last weeks Laravel Digest but to recap, both the double and triple curly braces now escape output. To get raw parsing you must use: {!! … !!} for example…

{!! Form::open(['route' => '']) !!}

I like this change because I found the difference between {{ and {{{ indistinguishable. This makes it immediately known.

Keep in mind though. This is still beta so it could potentially change again before the official release in November.

Admin Editor

I’ve been doing a lot of thinking on the editor as it’s such a core feature in the app. I tried doing research to find out the average post length and the search engine told me 1,600 words is ideal. For me writing over 1,000 words in a wysiwyg is not my favorite thing. I write locally, copy/paste, save draft, then preview. Rinse and repeat many many times.

This led me to send out a tweet asking how many people actually write in the browser versus a native client. The responses all pointed to writing in the browser and more than a few recommended Ghost editor. I tried Ghost when it first came out but couldn’t remember how their editor worked. So I installed it and gave it a go.

What I found great was the split pane on large screens. So you see the preview in real time as you type. What I didn’t like is the way images are handled.

To insert an image into your post, you need to first type ![]() into the Markdown editor panel. This will create an image upload box in your preview panel. You can drag and drop images (.png, .gif, .jpg) from your Desktop over the image upload box to include it into your post, or alternatively click the image upload box to use a standard image upload popup.

I’m not a fan of that workflow. I would rather just drag and drop the image directly into the editor. Of course the disadvantage to this is resizing, altering, etc. That would all need to be done before inserting. This is fine for developers, maybe not so much for others.

I believe I have a solution though. What I want to do is setup different editors and you can choose which you prefer. Either a straight markdown editor or Redactor for the wysiwyg crowd. Redactor is commercial and I wasn’t willing to fork over the cash for a license, but a community member PIXELFUSION decided to sponsor a Redactor OEM license and that will for sure be in the final release.

For the markdown wysiwyg I found a lot, but none I thought were great. Here are a few I came across:

There are lots more available and I’m going to keep researching until I find the diamond.

Wrap Up

This week I really wanted to get a lot more accomplished but ran out of time. I have so much left to do just for post storage such as dynamic slug creation, form options like publish date, and status. I also feel behind on the UI end. So much to do… So little time. You can see all the code for this week in the week-3 branch

Next week I’ll continue on with the Post crud and work on the form styles. Until then thanks again for tuning in.

0 Replies to “Rebuilding Wardrobe: Week 3”

  1. This is a great series and thank you so much for taking time to present the material in this format!

    A bit of feedback: I think it would make more sense to fire the events at the controller level upon successful repository transaction. Otherwise, alternative implementations of *Repository will have to be sure to dispatch the appropriate events. The controller (or an application service used by controller) would be a great alternative place for interacting with an event dispatcher.

      1. A service dedicated to use case under execution is the “appropriate place”. I agree controller logic should be bare and in this case the controllers are playing dual roles of HTTP/infrastructure facilitation and use case orchestration. That said, tying into framework infrastructure at the controller level is reasonable and would be acceptable here. Be wary of abstractions because someone else’s experiences. Write just enough code to do the job, maintain clean separation of concerns and maximize expressiveness in abstractions. Event publishing is an infrastructural concern. The events themselves are of the domain. Important distinction.

        I tend to stay away from absolute statements so I apologize if I misled. There are no “right” ways to do this stuff.

        1. Agreed. I would argue that a service-oriented architecture for wardrobe would maximise the opportunities of the goals @ericbarnes:disqus is looking to achieve.

          Also, there may not be a single “right” way to do things, but there’s definitely the wrong way…

Leave a Reply