Wednesday, September 30, 2009

Digitalus Framework Core

The Dig_Core package is the base of Digitalus Framework, and should be the first thing that you install in your project. It registers the Dig library with the application and adds the core classes.

You can check it out here: 

Package Structure

Digitalus Framework is going to be released as a set of packages, so you can export just what you need for a project, and don't have to sort through hundreds of files that you will never use.

Each package is going to follow the ZF standard project structure: /library, /public, /application

This will enable you to create a default project with Zend_Tool and then export the packages that you need into the root of the project.

I just released the first component, Dig_Core, but that is another story...

Monday, September 28, 2009

Digitalus Framework API

I constantly find myself copying and pasting library items from project to project; usually the same items. I am in the process of building a Digitalus Framework based API that will make it much easier to share this functionality.

The first component (user mgmt) is mostly done; I will release it as a private beta. If you are interested in taking part please contact me through the Digitalus Media site.

Friday, September 25, 2009

CMS Pages

The default ZF MVC structure makes a lot of sense for web applications. It only stands to reason that CRUD functions, for example, should be encapsulated in a single controller class.

On the other hand, it is difficult to explain to new developers why you need to create the controller class, a new view folder, and a view script to render a simple content page.

I think it is time to start looking at these as separate components of a CMS site. Well designed CMS sites generally consist of a number of landing pages, which load dynamic content from modules, such as news, events, or blog posts. This abstraction makes it possible to aggregate content, making the most out of your resources.

I am working on a different way to manage these pages. From a high level it works like this:
  1. You build a site much like you would a static HTML site, but you build it out of Zend View scripts.
  2. The CMS indexes the site folder and adds each page to the router. The CMS routes to the pages in exactly the same way that a standard site would; /about/team would render /site/about/team/index.phtml.
Each of these view scripts can have an optional controller, which is a little different than a standard Zend Controller. There is a one to one relationship between controllers and view scripts. If you render /about/team.phtml the CMS will look for a controller class in /about/TeamController.php. Since these controllers are tightly coupled with the views they are able to share information much more easily. You can access any public property in the controller from the view, without explicitly passing it.

A few Notes
  • This works in addition to ZF; the rest of your application functions exactly like any other ZF application. You can still create as many controllers and modules as you need, and you should. This is where all of the data management happens.
  • These views are rendered through the standard Digitalus Framework template engine.

Saturday, September 12, 2009

Another approach to models?

I have been playing around with a couple alternatives to the single table approach that the first round of the models used. I just came up with a pretty cool alternative; a conventional db structure that the models build.  It works like this:

  1. You set 'buildDb' parameter to true in your db connection options. You can do this in application.ini.
  2. You create a new model class. You add fields to this class in the init() method, exactly the way to do with a form. There are types for each type of db field. Note that at this point this uses SQLite as the back end,which makes permissions much easier.
  3. When you create an instance of the model it checks the buildDb flag; if it is set to true then it creates the table if it does not exist. It then confirms that each of the fields exists; creating those that do not. 
  4. It also validates the type, but at this point it just throws an exception. I will probably add a clean mode option which will change types, but this will take some consideration.

Saturday, September 5, 2009

Rapid CMS Development

Digitalus Framework will provide Zend Tool providers to aid in rapid application development. At this point I'm just playing with the providers, but the goal is to be able to build content types with a single command. The command will look something like this:


zf create person customer

This will do the following:
  1. Create a new person model
  2. Create a new person form
  3. Create a new person controller, with the following actions:
    1. index: this will display a list of the people, with links to open / delete them
    2. open: this will open the person. Initially it will simply render a list of the properties (k => v)
    3. create: create a new person
    4. update: update an existing person
    5. delete: delete the person
Each of the concrete models will contain a set of default properties. You can optionally pass a third parameter, which is a CSV list of the properties to create.

You can create models in modules by specifying the module as the fourth parameter.

Thursday, September 3, 2009

Prototype

The working prototype of Digitalus Framework has shown that the project has a ton of potential; it makes building custom CMS solutions easy, and that is the name of the game.

I just moved the prototype to a new tag, and cleaned out the trunk. I will replace the files as they are:

  • cleaned up
  • documented 
  • unit tested
When this is done I will push out version 0.1!

Link Manager

There are always a number of utility methods that you need to be able to use site wide but are specific to your site. I have used many approaches to this challenge and just tried a solution which involves utility plugins.

The first implementation is the LinkManager, which helps you fetch the right URLs to open dynamic content items with.

You configure them in application.ini:

resources.util.LinkManager.Forum_Model_Forum.open = "/forum/forum/open/{id}"

And then you can fetch the LinkManager from the Digitalus Core:


$linkManager = Dig_Core::getInstance()->getUtil()->LinkManager;
$forum = new Forum_Model_Forum(4);
echo $linkManager->getOpenModelUrl($forum);

Link Lists

I have no idea how many times I have created a list of links, but its quite a few. I've written a couple different functions to make it easier, but none has stood the test of time.

I just put together one that ties into Digitalus models and supports link templates; its a big time saver.

Say for example you are rendering a list of links to threads.

$threadList = $this->linkList($threads, "<a href='/forum/thread/open/id/{id}'>{subject}</a>");

The helper searches the template and populates it with data from the threads.

Wednesday, September 2, 2009

REQUEST PARAMETERS

I was never happy with the way that Digitalus handled URI parameters. We handled them outside the scope of Zend_Controller_Front and then manually set the request params. This is an effective way, but not as elegant as fuller integration.

I just created a new resource plugin for the application which parses the URI, then creates a new instance of Zend_Controller_Request_Http, and sets it up approapriately.

You set the separator in your application.ini file like this:

resources.request.paramSeparator = "p"

Then you can pass URI parameters like this:

/page/subpage/p/param/1

The trick here is the fact that this is done prior to the front controller being dispatched; this means that the front controller is none the wiser that you altered the URI; the technique works for your CMS pages as well as the ZF application pages (which use MVC routing).

PAGINATING CONTENT ITEMS

I just ran into an issue that will likely come up many times; how to paginate model result sets. Zend Framework has the Zend_Paginator component, but the closest adapter to use would be the DbTableSelect adapter, which returns a Zend_Db_Table_ResultSet.

I could have made this work, but decided to try and  write a Zend_Paginator adapter. It turns out (at least in this case) it was incredibly simple.
  1. I copied the DbTableSelect adapter, which only has one method, get items.
  2. I updated the constructor to take a Dig_Model rather than a select object. It sets the model, and then passes the model's select object down to the parent Zend_Paginator_Adapter_DbSelect class.
  3. I updated the getItems method, so it uses the model's fetchAll() method, rather than the Zend_Db_Select fetchAll() method.

Tuesday, September 1, 2009

INTEGRATING THE DIG_FORM WITH MODELS

I was just working with some comments and saw a familiar pattern for updating a model:
  1. Get the values from the form.
  2. Create an instance of the model.
  3. Populate and save model.
I added a method to the Dig_Form class that should make this easier;  getValuesAsModel(). You pass this method the class name of a model, and creates an instance and loads it for you.

$modelPost = $formPost->getValuesAsModel('Blog_Model_Post');

I added a second convenience method to this, saveToModel(), which you pass the name of a model to. It fetches the model (using the getValuesAsModel method) and saves it.

Digitalus Forms

Digitalus Form is a fairly straight implementation at this point;

Digitalus Form adds a hash control to avoid cross site attacks.

The validatePost() method does a few things that you need to do every time you process a form. It:
  • determines that the request method was post
  • loads the post
  • validates the form
If the form is valid it returns true, otherwise it returns false.

The populate() method accepts a Digitalus_Model as the argument (as well as an arrray).

There is a getReferrer() method tells you which page submitted the form.