It's so weird to stop


I've been running non-stop on a couple of different projects for several weeks now. Today was the first day where I've really not had anything to do but email in forever. So I guess I should update with how the freelance stuff is going.

Short Version : Way Better Than I Hoped

When I made the move to freelance a few months ago, I was a bit nervous about it. I pretty much never have money saved up, and no real customers that I could count on. I knew the marketplace sales were going to up, but not how fast that would be.

It seems like that's changed pretty quickly. I have several large solid clients who all have work for me. It's looking like it might actually be hard to take all of it on. 

That's not really what I was expecting at all.

I also had a lot of trepidation about handling the business end of things. This was one of the biggest hurdles for me trying to get started a few years ago when I first went off to do freelance after the print shops. But I feel like I have a pretty good handle on that, too. A friend of mine was able to help me get quickbooks online working, and that's been fairly easy to keep up on. I've moved most of my utilities, rent, etc to a business account, too. 

Overall, I feel really confident that this endeavour will work out. That makes me really happy.

Keep reading to find out how everything is in detail.


So Much To Do

It's been awhile since I've been keeping so many irons in the fire at once. Juggling estimates, code due dates, following up on emails and statuses, and then of course, coding? It's taking up a pretty big chunk of my day. Remembering to follow up is one of the key bits. I've been using google calendar for that, but sometime soon I'm hoping to write a basic c5 based CRM that lives up to my own needs. With an integrated time and project management system. For now, I'm juggling a fair amount of that just in my head, which can be a bit dicey. A long term way of doing it is pretty high up on the list.

The projects have been pretty interesting, too. I just finished up with a job posting / applying system that I'm really happy with. The client presented it to his HR department today, he was confident that they'd love it. He said that loved the front-end parts that they had already seen.

What I really liked about this one was that it let me finish up with a lot of things that I've been trying to get done for the Best Suite : Core system.  

On the Midwest PHP site, I had moved to putting the list and edit screens for the speakers totally on the front end. It turned out to be really difficult to get it all integrated and looking right. The timeframe and budget were tight on this one, so I didn't even bother asking about if it needed to be on the front end. Turns out that would have been preferred, but by that point there was no time to adjust. 

It still needed customization
The job management system was not like a blog or news manager where you want to have stuff for managing versions and permissions for the front end. And they don't want to delete pages, either. The application data needs to be kept for at least a year. So the only buttons that I used were preview, view applicants, and edit. 

The editing form needed to be different, too. They didn't want to allow the HR people to access everything about the page, and it was to be as simple as possible.

I ended up making another 'write' page type that was specific to the package, but basically exactly the same as the one from the core system as far as functionality. In the dashboard, you cannot specify the theme. So you can't do something like override the view of a page type. It kind of makes sense if you are using single pages, but if you are using page types, it can be annoying. That's why I needed a completely different page type.

I will actually be moving this to a system that lets you specify a package element to use instead. The hard part, I think, is going to be making a nice interface to get the blocks that you need. Totally changing the order of the attributes is not hard at all, but if you want to move around blocks and haven't named them... That's a different story. It's entirely possible that I'll end up extending the composer page type with one that keeps track of the composer items in a bit better way. 

Basically, it was adding a new write page type and a new list page type. That didn't take long at all. Then I created new search forms and list elements. I having all the code at my fingertips from the core system. I tweaked a couple of tools files, too. The dashboard search results tool, for instance, need to simply include a different element for the output.

Smooth Installation
Then, I had to set up everything for the job system to work. If you know how I work at all, you know that I don't like setting up much of the systems I build for clients by hand in the GUI. I think it's just a huge recipe for disaster, especially if you are using different databases for live or staging. Asking someone to go through and add in 20 different attributes with all the same details, then set that up in composer? I'm not putting bets on the deployment going smoothly.

That is all set up in the package install. So any tweaks that I need to do to the live site go without much chance for error. Typically, I pull down the live database right before deploying code, then test the finall upgrade locally (after backing up my local db, too, of course) to make sure it's all seamless. Typically goes without a hitch, and then the client can be entering data and playing with the system while you build, which can be good for production because you have live feedback and can catch bugs while they're still fresh and easy to find. 

I even set up everything for permissions and composer in the package installation. With that, I can architect a full application with no code at all outside of the controller if I wanted. The only thing that I had difficulty with was the sub-page permissions on the page where the jobs were added. It kind of set, when I went to the page after installation and added the proper groups to be allowed to add the pages, the page types they were supposed to be able to add were already filled in. 

This is another pretty big component of the system. It's not really ideal to just have the pages showing up in search if they're not approved or finished. I might have to put the saving draft stuff in there, too, but it was working a bit weird. If they just visit, then leave the page, then they can get blank titled pages in the list. I'm not sure how to get around that. 

But when they do hit save, I need to make sure that it's completely filled out. The not navigating away is a training issue. I might do a javascript alert that you're leaving or closing the window. If you hit 'discard permanently' it won't save the job at all. They had me turn off autosave, as well.

What I ended up being able to do is put a tiny bit of code into the controller on the write page:

And then wrote a function on the page type controller to run the validation:

That's really all there was to it. It should work for any page type, as long as the function exists, it will validate and abort the publish if it's not filled out. The sweet thing about doing it like this is how flexible it is. Obviously, I could do something like they do for user attributes, just put a required checkbox on it. But that might not always be good. Maybe you want to share 'thumbnail' between three different packages. For blogs, it's not needed. But for a product page type, you might want to require it. And actually, you might even want to verify that the image is a certain size. Or any other fine-grained method of validating the attributes and blocks. By doing it with a method on the controller, there's a ton more that I can do.

One Note: When adding options to error objects, remember that it's a singleton.  I declared the error object in the write page controller and then again in the page type controller. When I came back from the page type, the errors I had added there were already included in the overall list.

It's a bit weird, not sure why they did it that way. I think it could be good to have discrete error sets for a lot of reasons, like if you have two forms on a login page and want to diplay the error message next to each form instead of only at the top of the page. I guess you could do it with another 'error position' or 'error type' variable set for the view...

I think that is really one of the more important things to have working in this system if I want to get it to be extensible for other applications. 

Customized Page List
The system has some customized date and geolocation search, too. So I extended the page list model to have extra functions for shortcutting those. This code will be useful in a lot of other applications, I think. Any location manager would need it.

The front end uses this page list for pulling up the results via ajax. It makes for a really slick searching interface.

Advanced Forms / Data Display Integration
This is another component that enabled the system to be created so quickly. The job management was built on my stuff, but the actual application process was handled with Advanced Forms. I'm using a library that makes it easy for me to filter out form submissions that are unique to a particular job page. I'm storing the id from a URL parameter, so it's easy to filter from the page. 

The client was also able to completely format their application form and detail view themselves. That was all done with the GUI, and not part of the 'development' time for the system.  It's an expensive package set, but when you're looking at cutting 10-20 hours off of an application's development time line... It's worth it.

Overall Analysis

Everything that I've been doing on the last several projects is directly related to extending the Best Suite system for the marketplace. There's so much potential there. This whole system took a little over 30 hours, which I think is really good for this level of functionality.  

Next up is to make a 'skeleton' package for extending the core out into new systems like this. Depending on how my other workloads are, I might be able to release an app or two a week!