Welcome to part 1 of MVC Marathon,
a multipart excursion into creating an application in the major
MVC frameworks available today.

The source code for this part can be found here:

Part 1: Creating a New Application

The first step in any new application is creating a directory
structure and any necessary configuration files. Fortunately, most
of the frameworks now a days provide ready made templates or
scripts to make getting started as easy as possible.

Today we’ll explore how to create and run a new application in the
various frameworks and explore the difference between them. You
can jump to any specific framework using the links below. For this
series of articles, I’m going to assume that you already have the
basic frameworks installed.


Creating the Application

The easiest way to create a new ASP.NET MVC application is using
the application templates in Visual Studio. To do that, simply
select File → New → Project:

aspnetmvc create

In the New Project window, select Visual C# as the
language. Select the ASP.NET MVC Web Application, type in the name
of the new application, in our case, BurningPlate and click OK.
Visual Studio will create a new mvc application looking something
like this:

aspnetmvc create

Like nearly all MVC applications, we have the usual Controllers,
Models and Views folders along with some other .NET specific

Running the Application

To run your new application, simply hit F5, which will
start the application in Visual Studios local web server. This
means no messing with IIS until you have to. If all goes well, you
should end up with the default home page:

aspnetmvc run


There seems to be at least two ways to create a new CakePHP
application. The blog example on the CakePHP website say to just
download and extract the latest version and start creating your
application in the app subfolder. This seems like a
good approach if you’re creating app to put on a server where you
don’t know or control the version or even if CakePHP is installed.

If you’re running your own server, you can setup your env to point
to a centralized install of CakePHP and use cake to
create apps that reference the installed software. We’ll do the
latter as it closely follows how the other frameworks work.

Creating the Application

First, let’s see what cake tells us when we run it:

claco@mbp ~/mvc-marathon $ cake
Welcome to CakePHP v1.2.0.7296 RC2 Console
Current Paths:
-app: mvc-marathon
-working: /Users/claco/mvc-marathon
-root: /Users/claco
-core: /sw/cakephp/

Changing Paths:
your working path should be the same as your application path
to change your path use the '-app' param.
Example: -app relative/path/to/myapp or -app /absolute/path/to/myapp

Available Shells:

vendors/shells/: - none cake/console/libs/: acl api bake console i18n schema testsuite

To run a command, type 'cake shell_name [args]'
To get help on a specific command, type 'cake shell_name help'

Next, let’s run cake bake help to see what our options are:

claco@mbp ~/mvc-marathon $ cake bake help
Welcome to CakePHP v1.2.0.7296 RC2 Console
App : mvc-marathon
Path: /Users/claco/mvc-marathon
CakePHP Bake:
The Bake script generates controllers, views and models for your application.
If run with no command line arguments, Bake guides the user through the class
creation process. You can customize the generation process by telling Bake
where different parts of your application are using command line arguments.
Usage: cake bake <command> <arg1> <arg2>…
-app <path> Absolute/Relative path to your app folder.


bake help shows this help message. bake all <name> bakes complete MVC. optional <name> of a Model bake project <path> bakes a new app folder in the path supplied or in current directory if no path is specified bake plugin <name> bakes a new plugin folder in the path supplied or in current directory if no path is specified. bake db_config bakes a database.php file in config directory. bake model bakes a model. run &#x27;bake model help&#x27; for more info bake view bakes views. run &#x27;bake view help&#x27; for more info bake controller bakes a controller. run &#x27;bake controller help&#x27; for more info

Since we’re starting from scratch, let’s give project
a whirl:

claco@mbp ~/mvc-marathon/cakephp $ cake bake BurningPlate
Welcome to CakePHP v1.2.0.7296 RC2 Console
App : cakephp
Path: /Users/claco/mvc-marathon/cakephp
Bake Project
Skel Directory: /sw/cakephp/cake/console/libs/templates/skel
Will be copied to: /Users/claco/mvc-marathon/cakephp/BurningPlate
Look okay? (y/n/q)
[y] >
Do you want verbose output? (y/n)
[n] >
Created: BurningPlate in /Users/claco/mvc-marathon/cakephp/BurningPlate

Creating file /Users/claco/mvc-marathon/cakephp/BurningPlate/views/pages/home.ctp
Wrote /Users/claco/mvc-marathon/cakephp/BurningPlate/views/pages/home.ctp
Welcome page created
Random hash key created for &#x27;Security.salt&#x27;
CAKE_CORE_INCLUDE_PATH set to /sw/cakephp in webroot/index.php
CAKE_CORE_INCLUDE_PATH set to /sw/cakephp in webroot/test.php
Remember to check these value after moving to production server
Your database configuration was not found. Take a moment to create one.
Database Configuration:
[default] > ^C

Running the Application

At first glance, there appears to be no development server for
CakePHP applications. There is a script called
available on the CakePHP website geared for this purpose.
Ironically, the script relies on Python to get the job done. When
I ran it, it appeared to work, but all I ever got when trying to
hit it with the browser was a CGI SCript Error carping about

The second option is to run this application under Apache. Since
I’m on a MacBook Pro and OSX includes a running version of Apache
and PHP, all I needed to do was place the BurningPlate directory
in my Sites folder. After hitting
http://localhost/~claco/BurningPlate/ with my browser
we get:

cakephp run


Creating the Application

Just like CakePHP, Catalyst also has a command line utility for
creating a new application. Let’s see what what it has to say:

claco@mbp ~/mvc-marathon/catalyst $ catalyst.pl
catalyst.pl [options] application-name

&#x27;catalyst.pl&#x27; creates a skeleton for a new application, and allows you to upgrade the skeleton of your old application. Options: -force don&#x27;t create a .new file where a file to be created exists -help display this help and exit -makefile only update Makefile.PL -scripts only update helper scripts -short use short names, M/V/C instead of Model/View/Controller. application-name must be a valid Perl module name and can include "::", which will be converted to &#x27;-&#x27; in the project name. Examples: catalyst.pl My::App catalyst.pl MyApp To upgrade your app to a new version of Catalyst: catalyst.pl -force -scripts MyApp

Looks like we just need an application name:

claco@mbp ~/mvc-marathon/catalyst $ catalyst.pl BurningPlate
created "BurningPlate"
created "BurningPlate/script"
created "BurningPlate/lib"
created "BurningPlate/root"
created "BurningPlate/root/static"
created "BurningPlate/root/static/images"
created "BurningPlate/t"
created "BurningPlate/lib/BurningPlate"
created "BurningPlate/lib/BurningPlate/Model"
created "BurningPlate/lib/BurningPlate/View"
created "BurningPlate/lib/BurningPlate/Controller"
created "BurningPlate/burningplate.conf"
created "BurningPlate/lib/BurningPlate.pm"
created "BurningPlate/lib/BurningPlate/Controller/Root.pm"
created "BurningPlate/README"
created "BurningPlate/Changes"
created "BurningPlate/t/01app.t"
created "BurningPlate/t/02pod.t"
created "BurningPlate/t/03podcoverage.t"
created "BurningPlate/root/static/images/catalyst_logo.png"
created "BurningPlate/root/static/images/btn_120x50_built.png"
created "BurningPlate/root/static/images/btn_120x50_built_shadow.png"
created "BurningPlate/root/static/images/btn_120x50_powered.png"
created "BurningPlate/root/static/images/btn_120x50_powered_shadow.png"
created "BurningPlate/root/static/images/btn_88x31_built.png"
created "BurningPlate/root/static/images/btn_88x31_built_shadow.png"
created "BurningPlate/root/static/images/btn_88x31_powered.png"
created "BurningPlate/root/static/images/btn_88x31_powered_shadow.png"
created "BurningPlate/root/favicon.ico"
created "BurningPlate/Makefile.PL"
created "BurningPlate/script/burningplate_cgi.pl"
created "BurningPlate/script/burningplate_fastcgi.pl"
created "BurningPlate/script/burningplate_server.pl"
created "BurningPlate/script/burningplate_test.pl"
created "BurningPlate/script/burningplate_create.pl"

Running the application

Unlike CakePHP, Catalyst includes a development server to get you
started. No need to futz with Apache:

claco@mbp ~/mvc-marathon/catalyst $ BurningPlate/script/burningplate_server.pl
[debug] Debug messages enabled
[debug] Statistics enabled
[debug] Loaded plugins:
| Catalyst::Plugin::ConfigLoader 0.20 |
| Catalyst::Plugin::Static::Simple 0.20 |

[debug] Loaded dispatcher "Catalyst::Dispatcher"
[debug] Loaded engine "Catalyst::Engine::HTTP"
[debug] Found home "/Users/claco/mvc-marathon/catalyst/BurningPlate"
[debug] Loaded Config "/Users/claco/mvc-marathon/catalyst/BurningPlate/burningplate.conf"
[debug] Loaded components:
| Class | Type |
| BurningPlate::Controller::Root | instance |

[debug] Loaded Private actions:
| Private | Class | Method |
| /default | BurningPlate::Controller::Root | default |
| /end | BurningPlate::Controller::Root | end |
| /index | BurningPlate::Controller::Root | index |

[debug] Loaded Path actions:
| Path | Private |
| / | /default |
| / | /index |

[info] BurningPlate powered by Catalyst 5.7014
You can connect to your server at http://localhost:3000
[info] * Request 1 (0.125/s) 1941 [Sat Jun 28 19:24:35 2008] *
[debug] "GET" request for "/" from ""
[info] Request took 0.017728s (56.408/s)
| Action | Time |
| /index | 0.000507s |
| /end | 0.000745s |

The development server was nice enough to tell us where to go. Hitting
http://localhost:3000 in our browser yields:

catalyst run


Creating the application

Rinse. Lather. Repeat. As with the previous two frameworks, we just
need to run a command line script to create a new application.

claco@mbp ~/mvc-marathon/django $ django-admin.py
Usage: django-admin.py action [options]
adminindex [appname …]
Prints the admin-index template snippet for the given app name(s).

createcachetable [tablename] Creates the table needed to use the SQL cache backend dbshell Runs the command-line client for the current DATABASE_ENGINE. diffsettings Displays differences between the current settings.py and Django&#x27;s default settings. Settings that don&#x27;t appear in the defaults are followed by "###". dumpdata [—format][appname …] Output the contents of the database as a fixture of the given format flush [—verbosity] [—interactive] Executes ``sqlflush`` on the current database. inspectdb Introspects the database tables in the given database and outputs a Django model module. loaddata [—verbosity] fixture, fixture, … Installs the named fixture(s) in the database reset [—interactive][appname …] Executes ``sqlreset`` for the given app(s) in the current database. runfcgi [various KEY=val options, use `runfcgi help` for help] Runs this project as a FastCGI application. Requires flup. runserver [—noreload] [—adminmedia=ADMIN_MEDIA_PATH] [optional port number, or ipaddr:port] Starts a lightweight Web server for development. shell [—plain] Runs a Python interactive interpreter. Tries to use IPython, if it&#x27;s available. sql [appname …] Prints the CREATE TABLE SQL statements for the given app name(s). sqlall [appname …] Prints the CREATE TABLE, initial-data and CREATE INDEX SQL statements for the given model module name(s). sqlclear [appname …] Prints the DROP TABLE SQL statements for the given app name(s). sqlcustom [appname …] Prints the custom table modifying SQL statements for the given app name(s). sqlflush Returns a list of the SQL statements required to return all tables in the database to the state they were in just after they were installed. sqlindexes [appname …] Prints the CREATE INDEX SQL statements for the given model module name(s). sqlinitialdata RENAMED: see &#x27;sqlcustom&#x27; sqlreset [appname …] Prints the DROP TABLE SQL, then the CREATE TABLE SQL, for the given app name(s). sqlsequencereset [appname …] Prints the SQL statements for resetting PostgreSQL sequences for the given app name(s). startapp [appname] Creates a Django app directory structure for the given app name in the current directory. startproject [projectname] Creates a Django project directory structure for the given project name in the current directory. syncdb [—verbosity] [—interactive] Create the database tables for all apps in INSTALLED_APPS whose tables haven&#x27;t already been created. test [—verbosity] [appname …] Runs the test suite for the specified applications, or the entire site if no apps are specified validate Validates all installed models.

—version show program&#x27;s version number and exit
-h, —help show this help message and exit
—settings=SETTINGS Python path to settings module, e.g.
"myproject.settings.main". If this isn&#x27;t provided, the
DJANGO_SETTINGS_MODULE environment variable will be
Lets you manually add a directory the Python path,
e.g. "/home/djangoprojects/myproject".
—plain Tells Django to use plain Python, not IPython, for
"shell" command.
—noinput Tells Django to NOT prompt the user for input of any
—noreload Tells Django to NOT use the auto-reloader when running
the development server.
—format=FORMAT Specifies the output serialization format for fixtures
—indent=INDENT Specifies the indent level to use when pretty-printing
Verbosity level; 0=minimal output, 1=normal output,
2=all output
Specifies the directory from which to serve admin
media for runserver.

To create a new app, we’ll run the startproject command:

claco@mbp ~/mvc-marathon/django $ django-admin.py startproject BurningPlate

Unfortunately, no matter what —verbosity level I set, this is the
only output I get.

Running the Application

claco@mbp ~/mvc-marathon/django $ python BurningPlate/manage.py runserver
Validating models…
0 errors found.

Django version 0.96.2, using settings &#x27;BurningPlate.settings&#x27;
Development server is running at
Quit the server with CONTROL-C.
[28/Jun/2008 18:40:25] "GET / HTTP/1.1" 404 2065

Lets hit and see what we have:

django run

Ruby on Rails

Creating the Application

Another framework; another script.

claco@mbp ~/mvc-marathon/rails $ rails
Usage: /sw/bin/rails /path/to/your/app [options]

-r, —ruby=path Path to the Ruby binary of your choice (otherwise scripts use env, dispatchers current path).
Default: /sw/bin/ruby1.8
-d, —database=name Preconfigure for selected database (options: mysql/oracle/postgresql/sqlite2/sqlite3).
Default: mysql
-f, —freeze Freeze Rails in vendor/rails from the gems generating the skeleton
Default: false

Rails Info:
-v, —version Show the Rails version number and quit.
-h, —help Show this help message and quit.

General Options:
-p, —pretend Run but do not make any changes.
—force Overwrite files that already exist.
-s, —skip Skip files that already exist.
-q, —quiet Suppress normal output.
-t, —backtrace Debugging: show backtrace on errors.
-c, —svn Modify files with subversion. (Note: svn must be in path)

The &#x27;rails&#x27; command creates a new Rails application with a default
directory structure and configuration at the path you specify.

rails ~/Code/Ruby/weblog

This generates a skeletal Rails installation in ~/Code/Ruby/weblog. See the README in the newly created application to get going.

Looks like Catalyst. Give it an app name and go:

claco@mbp ~/mvc-marathon/rails $ rails BurningPlate
create app/controllers
create app/helpers
create app/models
create app/views/layouts
create config/environments
create config/initializers
create db
create doc
create lib
create lib/tasks
create log
create public/images
create public/javascripts
create public/stylesheets
create script/performance
create script/process
create test/fixtures
create test/functional
create test/integration
create test/mocks/development
create test/mocks/test
create test/unit
create vendor
create vendor/plugins
create tmp/sessions
create tmp/sockets
create tmp/cache
create tmp/pids
create Rakefile
create README
create app/controllers/application.rb
create app/helpers/application_helper.rb
create test/test_helper.rb
create config/database.yml
create config/routes.rb
create public/.htaccess
create config/initializers/inflections.rb
create config/initializers/mime_types.rb
create config/boot.rb
create config/environment.rb
create config/environments/production.rb
create config/environments/development.rb
create config/environments/test.rb
create script/about
create script/console
create script/destroy
create script/generate
create script/performance/benchmarker
create script/performance/profiler
create script/performance/request
create script/process/reaper
create script/process/spawner
create script/process/inspector
create script/runner
create script/server
create script/plugin
create public/dispatch.rb
create public/dispatch.cgi
create public/dispatch.fcgi
create public/404.html
create public/422.html
create public/500.html
create public/index.html
create public/favicon.ico
create public/robots.txt
create public/images/rails.png
create public/javascripts/prototype.js
create public/javascripts/effects.js
create public/javascripts/dragdrop.js
create public/javascripts/controls.js
create public/javascripts/application.js
create doc/README_FOR_APP
create log/server.log
create log/production.log
create log/development.log
create log/test.log

Running the Application

claco@mbp ~/mvc-marathon/rails $ BurningPlate/script/server
=> Booting WEBrick…
=> Rails application started on
=> Ctrl-C to shutdown server; call with —help for options
[2008-06-28 19:20:36] INFO WEBrick 1.3.1
[2008-06-28 19:20:36] INFO ruby 1.8.6 (2008-03-03) [i686-darwin]
[2008-06-28 19:20:36] INFO WEBrick::HTTPServer#start: pid=1929 port=3000 – - [28/Jun/2008:19:20:41 EDT] "GET / HTTP/1.1" 200 7557
- -> / – - [28/Jun/2008:19:20:41 EDT] "GET /javascripts/prototype.js HTTP/1.1" 200 125605
http://localhost:3000/ -> /javascripts/prototype.js – - [28/Jun/2008:19:20:41 EDT] "GET /javascripts/effects.js HTTP/1.1" 200 38916
http://localhost:3000/ -> /javascripts/effects.js – - [28/Jun/2008:19:20:41 EDT] "GET /images/rails.png HTTP/1.1" 200 1787
http://localhost:3000/ -> /images/rails.png

Loading in our browser, we see:

rails run


There weren’t too many shockers here. For the most part, it’s just a
matter of running a command to get an application structure up and
running. There are some areas that could use a few tweaks to help out
the people new to their respective frameworks:

  • CakePHP really could use a development server. For development,
    it’s nice to not have to mess with Apache configs.

  • Django needs to output something when it’s successfully created
    a new application. No output equates to thinking nothing happened
    or that something is broken.

  • Catalyst, Django and Rails would be a touch better if after they
    created the new applications would tell the user how to run them.
    i.e. “App created. please run xxx xxxx/xxxxx ro start your new

  • All of the frameworks except for ASP.NET MVC tell the user where
    to go next and/or what files to start to configure. It would be
    nice if ASP.NET MVC did the ame thing rather than just display
    the “Home” page.

See more posts about: offtopic | All Categories