Skip to end of metadata
Go to start of metadata

<h3>Symfony</h3>

<h3>Screenshots</h3>

<p>Installation via the PEAR channel was simple and it give you a system wide interface into creating Symfony based projects.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 1.png" /></ac:image></p>

<p>The help system is in its expected place... And as a side note, all utilities for "tooling" run through this installed "symfony" command line. The interface while good, is a little unintuitive. The groupings of commands and their actions is limited. One NICE thing is that there is the concept of a task name namespace. This is useful for logical grouping of tasks.</p>

<p>Another nice aspect of this is the ANSI color coding, it visually breaks the screen up into easier to see "chunks".</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 2.png" /></ac:image></p>

<p>The actions by default are very verbose, as you can see below every filesystem action is logged to the screen whether its for file/directory creation or chmoding. Also note the use of columns and ANSI colors.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 3.png" /></ac:image></p>

<p>I setup both my hosts and Vhost so that the newly created app could be served via my local apache instance.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 4.png" /></ac:image></p>

<p>Originally, nothing came up. The default project doesnt have an index.php file.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 5.png" /></ac:image></p>

<p>Creating an "app", which is similar in nature to a ZF "module" created an index.php file. This file actually came up with broken images. </p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 6.png" /></ac:image></p>

<p>Upon further investigation, I found i needed an alias to the system wide public files shipped with symfony. This is good and bad. (....)</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 7.png" /></ac:image></p>

<p>The working front page of the symfony project I setup.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 8.png" /></ac:image></p>

<p>Propel is the ORM that is "default" (although there are other options available.) Propel uses YAML to describe the ORM data model. This YAML file is a metafile that will then be used to both generate code as well as generate the db tables.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 9.png" /></ac:image></p>

<p>Building models actually means taking the metafile and generating a new xml based metafile. Thats a lot of artifacts isnt it?</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 10.png" /></ac:image></p>

<p>Configuring the projects database connectivity.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 11.png" /></ac:image></p>

<p>There is actually a mismatch in the versions of Symfony and PropelPDO and what it expects <br />
as a connection string. This problem is not resolved yet which means you have to edit the files by hand. Connection settings are written into the database.yml file.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 12.png" /></ac:image></p>

<p>One must run the sql build task in order to generate the SQL necessary for the project.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 13.png" /></ac:image></p>

<p>Screenshot of the generated SQL code.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 14.png" /></ac:image></p>

<p>(reconfiguring b/c of bug mentioned above)</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 15.png" /></ac:image></p>

<p>The new database file edited.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 16.png" /></ac:image></p>

<p>Building, and executing the SQL. REALLY nice use of ANSI blocking to show the user the status of an operation.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 17.png" /></ac:image></p>

<p>Building Forms.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 18.png" /></ac:image></p>

<p>Forms are quite simple</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 19.png" /></ac:image></p>

<p>Generated code for a "CRUD action".</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 20.png" /></ac:image></p>

<p>A generated html form.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/symfony/Picture 21.png" /></ac:image></p>

<h3>Summary</h3>

<p>This framework has the best "framework" feel. Installation was easy using the PHP package manager PEAR (leveraging the PHP ecosystem). From a tooling standpoint, its the most advanced and fluent (even over rails). The ANSI colors give it a polished feel, even though the command line structure is less than ideal. The verbosity of output gives a great feel of transparency in all that its doing.</p>

<p>Symfony creates a nice (read: pretty), default project screen. It also gives you access to developer tools, (loggers, consoles, etc).</p>

<p>The downside is that symfony is packaging several technologies that are not under the same umbrella. This gives a less than intuitive API across the board, as well as having to understand different versions of technolgies within a single version of symfony itself.</p>

<p>Another downside is that there is an extensive use of metafiles and config files for generating scaffolds & CRUD artifacts.</p>

<h2>CakePHP</h2>

<h3>Screenshots</h3>

<p>The console window with no options</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 2.png" /></ac:image></p>

<p>Making the environment. This is essentially b/c cakephp is a download and go type of setup. There is no pear installer.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 3.png" /></ac:image></p>

<p>The full "bake" all. Baking is the term the cake project uses to "do something"</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 3b.png" /></ac:image></p>

<p>The Database settings that were generated from the command line.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 4.png" /></ac:image></p>

<p>After creating a table, you can run bake model and it will introspect the database. It will attempt to find table names and create models based off them. It expects tables to be plural.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 4b.png" /></ac:image></p>

<p>The generated Controller.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 5.png" /></ac:image></p>

<p>The base model.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 6.png" /></ac:image></p>

<p>The ctp is the cake tempalate file. This one is the actual form. As you can see it utilizes view helpers to generate the views.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 7.png" /></ac:image></p>

<p>The generated edit form.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 8.png" /></ac:image></p>

<p>This is the generated index or listing view script.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 9.png" /></ac:image></p>

<p>The generated view view script.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 10.png" /></ac:image></p>

<p>This a screenshot of the page (with debugging on as you can see in the bottom).</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 11.png" /></ac:image></p>

<p>Html view of the add form.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 12.png" /></ac:image></p>

<p>HTML view of the edit form.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/cakephp/Picture 13.png" /></ac:image></p>

<h3>Summary</h3>

<p>Install doesnt use PEAR, must download and go. There is a "cake script" in the scripts/ directory, and the expectation for usage is to put it in your PATH.</p>

<p>The console script itself is kinda clunky. The argument ordering is less than intuitive and they are using framework specific terminology - for example "cake bake ....".</p>

<p>The Scaffolding itself is decent, although its fairly opinionated. It expects the db tables to have pluralized names. That said, it does a decent job of doing the existing dbtable -> code generation. The generated code is very verbose, which makes it easy to customize individual actions later on down the line.</p>

<p>Cake also comes decent UI for scaffolding as well as a "Development mode" which will show all of the queries used to build a page. This is similar to Rail's server console window, and symfony's developer "toolbar".</p>

<h2>RubyOnRails</h2>

<p>Installed via GEMS, the Ruby package manager.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 1.png" /></ac:image></p>

<p>The rails help menu.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 2.png" /></ac:image></p>

<p>The verbosity of creating a new project</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 3.png" /></ac:image></p>

<p>The default screen for a newly created project</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 4.png" /></ac:image></p>

<p>Editing the database.yml file by hand to add our projects database connectivity</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 5.png" /></ac:image></p>

<p>(I actually had to recreate a project b/c your database needs to be configured in the same line as the project creation.)</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 6.png" /></ac:image></p>

<p>For some command you switch over to rake to execute. For example, this one does the creation of the database if its needed</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 7.png" /></ac:image></p>

<p>Creating a Home Controller and index action</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 8.png" /></ac:image></p>

<p>The generated view script</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 9.png" /></ac:image></p>

<p>Rails comes with a small web server to run your project out of during development. The idea that this is also the logging mechanism is kinda cool. This will show you all of the dispatch and sql information as the page is generated.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 10.png" /></ac:image></p>

<p>Scaffolding. This is the creation of a CRUD based controller, model and associated views for creating a quick and dirty CRUD functionality and data model</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 11.png" /></ac:image></p>

<p>A log of the utilization of the CRUD controller from the server running within rails</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 12.png" /></ac:image></p>

<p>(this should be moved above, but this is a longer listing of the steps to do CRUD scaffolding from the command line)</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 13.png" /></ac:image></p>

<p>This is an HTML view of the generated CRUD</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/rubyonrails/Picture 14.png" /></ac:image></p>

<h3>Summary</h3>

<p>While there is no doubt that RoR is popular, it suprises me that there is not a more fluent interface for the "tooling" that comes with it. There are 3 main ways of executing a command, which leaves the uninitiated user with a lot of documentation and tutorial needs. These commands are rails, rake and script/generate.</p>

<p>The framework is especially verbose and offers a ton of transparency. Also, the built in server is nice when used as a logging window for development.</p>

<p>Scaffolding generates lots of customizable code, even though its very verbose when doing it from the command line: "script/generate scaffold Paste username:string ..."</p>

<h2>Django</h2>

<h3>Screenshots</h3>

<p>Django is installed by downloading the tar ball and executing the setup script. It will copy the necessary libraires into the system django setup.</p>

<p>At this point, you can start a "project". Projects are actually django namespaced packages. This has some unfortunate side effects, particularly with naming.</p>

<p>Not alot of files are created. In fact, Django is not a true MVC framework.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 1.png" /></ac:image></p>

<p>Database file for connectivity must be edited by hand.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 2.png" /></ac:image></p>

<p>Upon "syncing" the database, it asks to create an "Authetication and Autorization" system.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 3.png" /></ac:image></p>

<p>The product of the setup of the auth stuff.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 4.png" /></ac:image></p>

<p>Creating an "app" within a project. Similar to ZF's creating a module inside an application.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 5.png" /></ac:image></p>

<p>Must add the "app" to the main settings.py to be loaded by the project when the python web server starts up.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 6.png" /></ac:image></p>

<p>The generated SQL</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 7.png" /></ac:image></p>

<p>Models in django are created via the command line, and the stucture must be defined inside of the model itself. The command line tools will then read the model and create the appropriate database.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 8.png" /></ac:image></p>

<p>Running the database generation script.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 9.png" /></ac:image></p>

<p>The new table 'pastebin_paste'</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 10.png" /></ac:image></p>

<p>Adding the built-in admin interface for the project.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 11.png" /></ac:image></p>

<p>The login screen (this utilizes the auth system setup previously).</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 12.png" /></ac:image></p>

<p>The main admin screen. As you can see its a full admin for managing authentication and authorization types of information.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 13.png" /></ac:image></p>

<p>After adding the admin to the project, and adding admin capabilities to the pastebin "app", it can now be administered through the built-in admin.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 14.png" /></ac:image></p>

<p>Listing uses the auto string casting.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 15.png" /></ac:image></p>

<p>Defining the string casting method to be used in the built-in admin.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 16.png" /></ac:image></p>

<p>The running of the web server handling this project.</p>

<p><ac:image><ri:url ri:value="http://ralphschindler.com/dropbox/framework-screenshots/django/Picture 17.png" /></ac:image></p>

<h3>Summary</h3>

<p>Out the box, the interface is not very intuitive. Also, the structure is less than ideal. A "project" is a python "module", and as such, contains the same structure as a library component. Also, Django is not MVC. It looks and feels like a custom or home grown framework, similar to the numerous frameworks in PHP during the 2001-2005 timeframe. </p>

<p>Again, there are multiple commands the user must know: django-admin.py as well as python manage.py xxx. This also leaves the developer with a less than intuitive experience.</p>

<p>The highlights of django are that for basic crud projects (the 90% projects), it gives you both an admin interface to the tables you've created (which by the way is Model -> dbtable creation), as well as installs a pretty extensive authentication and authorization system.</p>

<p>Django also comes with a simple web server to run your project which also will show any exceptions thrown from a bad request. ALso, since its Model -> Database generation, this leaves you with a pretty rigid db structure that probably cannot be changed easily since its tied so closely to the model.</p>

<p>On the plus sides, the admin is very nice and it does give you some common structure to work with when you are into python based web development.</p>

<h2>Feature chart</h2>

<table><tbody>
<tr>
<th><p>Framework</p></th>
<th><p>Installation Mode</p></th>
<th><p>Project/Application Creation</p></th>
<th><p>Application Module Creation</p></th>
<th><p>Controller View Generation</p></th>
<th><p>Model Generation</p></th>
<th><p>Metadata -> Model&Table</p></th>
<th><p>Table -> Model Gen</p></th>
<th><p>Model -> Table Gen</p></th>
<th><p>CRUD Admin</p></th>
<th><p>Cli Help System</p></th>
<th><p>Embedded Web Server</p></th>
<th><p>Logging Console</p></th>
<th><p>Library Freezing</p></th>
<th><p>Welcome Screen after Project Creation</p></th>
<th><p>Config VS. Convention</p></th>
</tr>
<tr>
<td><p>Symfony</p></td>
<td><p>PHP's PEAR</p></td>
<td><p>Y</p></td>
<td><p>Y ("App")</p></td>
<td><p>Y</p></td>
<td><p>Y ("Module")</p></td>
<td><p>Y (Propel)</p></td>
<td><p>N</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>N</p></td>
<td><p>Y - help bar</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>Convention before Config</p></td>
</tr>
<tr>
<td><p>Cake</p></td>
<td><p>Download & Drop</p></td>
<td><p>Y</p></td>
<td><p>Y ("plugins")</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>Convention</p></td>
</tr>
<tr>
<td><p>Rails</p></td>
<td><p>Ruby's Gems</p></td>
<td><p>Y</p></td>
<td><p>Y ("components")</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>N</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>Y (limited)</p></td>
<td><p>Y</p></td>
<td><p>Y (via web proc)</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>Convention</p></td>
</tr>
<tr>
<td><p>Django</p></td>
<td><p>Download & setup.py</p></td>
<td><p>Y</p></td>
<td><p>Y ("App")</p></td>
<td><p>N</p></td>
<td><p>Y (empty)</p></td>
<td><p>N</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>Y</p></td>
<td><p>N</p></td>
<td><p>Y</p></td>
<td><p>Y (via web proc)</p></td>
<td><p>N</p></td>
<td><p>N</p></td>
<td><p>None</p></td>
</tr>
</tbody></table>

Labels:
None
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.
  1. Feb 02, 2009

    fc

    <p>Symfony, Django, Zend. Oh yes, come on Ralph, add the Zend_Tool_Magic <ac:emoticon ac:name="smile" /></p>

  2. Feb 03, 2009

    <p>Great comparison! It's interesting to note that each framework seems to have 1 or 2 really strong points. I hope that if anyone outside of the ZF community reads this, they understand that any critical analysis of other frameworks is intended to identify the ideas that we think would work well for the ZF community and which don't fit the ZF philosophy well.<br />
    A couple of points: I don't remember setting up scaffolding in Rails being so verbose. Can't the system introspect the database for fields and types, or was this not possible because your table wasn't conventional.<br />
    One limitation of the sample app is that there only seems to be one table. Adding additional tables with joins require additional statements in the model files IIRC, and there are other framework features around this, although more ORM-oriented than tooling oriented.</p>

    1. Feb 04, 2009

      <p>Yeah, the goal here was to demonstrate the "development time" features of different frameworks. Specifically as presented to the uninitiated developer. Since multiple related tables is moving more towards ORM, I attempted to stay away from that b/c it doesnt speak for the framework on a whole, just the ORM capabilities.</p>

      <p>While RoR might have great db introspection to create migrations and model files, its not completely apparent by the most popular tutorial, or the CLI help system. In this case, I went with the most apparent means of "modeling".</p>

      <p>The overall idea here is to identify the great aspects of each framework, and also the pain points.</p>