Brad Lucas

Programming, Clojure and other interests
June 11, 2017

PHP To Clojure

Overview

I have a few old sites that were developed in PHP using the Zend framework. Since moving to Clojure mostly full-time I thought it would be good to do some house cleaning and move these old sites over to Clojure. While doing so I and seeing that there was a basic pattern to the process I thought it might help others if I mocked up an example and put some notes together.

Now, before I go on I'll say that my example is very simple and it covers a basic site. Highlighting the structure of the PHP/Zend site and the Clojure/Compojure site is the main idea I'd like to get across. Those with more complex sites will clearly need to do more. Hopefully, the following will help get them started.

Repo

To start visit or clone the following repo. It contains two examples of the same simple site. One in PHP and the other in Clojure. I'll walk through the differences.

https://github.com/bradlucas/php-to-clojure

The PHP site is currently (as of today) running at http://php.beaconhill.com and the Clojure version at http://clj.beaconhill.com.

PHP

Starting with the PHP/Zend site you'll see the structure looks like the following:

.
|-- application
|   |-- Bootstrap.php
|   |-- configs
|   |   `-- application.ini
|   |-- controllers
|   |   |-- AboutController.php
|   |   `-- IndexController.php
|   |-- layouts
|   |   `-- scripts
|   |       `-- layout.phtml
|   `-- views
|       `-- scripts
|           |-- about
|           |   |-- contact.phtml
|           |   `-- index.phtml
|           `-- index
|               `-- index.phtml
|-- library
|   |-- Emailer.php
|   `-- Library.php
`-- public
    `-- index.php

The main directories to review are the controllers, the layouts/scripts and the views/scripts. This is a familiar MVC layout. The controllers have methods which end with the display of a view. The base or main template for the site is in layouts which leaves the views to implement the specific parts for each page.

The library directory is where you can put more granular 'class-ish` files that you can reference from any controller. For more real-world sites you'll see other files called display helpers to fill in pieces of pages. I don't have any here but they are simple to grasp and port.

Clojure

The Clojure project is built with Compojure. To start your own version use this command, lein new compojure my-site. I'm also using the Selmer templating library. Having done a fair bit of Django development I find it familiar and easy to use. For this project you'll see how each view has {% %} blocks. These are for the templating.

To compare here is the project's structure:

.
|-- README.md
|-- project.clj
|-- resources
|   `-- public
|       |-- about.html
|       |-- base.html
|       |-- contact.html
|       `-- index.html
|-- scripts
|   `-- run-php-to-clojure.jar
|-- src
|   `-- php_to_clojure
|       |-- core.clj
|       `-- handler.clj
`-- test
    `-- php_to_clojure
        `-- handler_test.clj

The key points to note are that your layout and views are in the resources/public directory. The base.html is layout or main template and the other html files are the views. Your application is inside of src/php_to_clojure. Review the handler.clj file. This is where your controller logic is. You should see the pattern.

To run the site locally enter lein ring server or build the uberjar, lein uberjar and then run the jar java -jar target/php-to-clojure.jar.

Pattern

  1. Move over your layout.phtml file to base.html. Fix up the container block.
  2. For each of your views/scripts phtml files create a similar html file over in your Clojure project. Add the block to reference base.html.
  3. Build your handler functions to replace your collection of Controllers. Review each Controller and it's view methods.
  4. Iterate over each page getting each to work in turn. When all work review your library files. These you need to port on a file by file basis

Summary

If you take the above as a guide with your own site and move forward you'll find the following useful:

Tags: selmer clojure zend php compojure