How to create a blog with Portofino 4
This article begins a series of five tutorials on how to create a blog with Portofino 4 step by step. We'll develop an application that will implement the common features of a blog such as the management of posts, comments, users and permissions.
The folllowing picture shows the goal of this article.
The series will address the following topics:
- Use Portofino 4 to build the data model and the features of a blog with Portofino “out of the box” functions.
- Set users permissions and change the graphical theme.
- Customize the “Post” page
- Customize the “Comment" page
- Create RSS feeds.
Let's start with the first one.
Step 1. Start Portofino 4 and create a connection to the DB
Download the latest version of Portofino and start the framework.
> cd portofino-4.0.8/apache-tomcat-6.0.36/ > bin/startup.sh
Open your browser and log in with default user "admin" and password "admin".
For this tutorial I have created a new database called "blog" on Postgresql. Now let's create a connection to this database.
- Click on "Administration" (on the top right corner) > "Wizard"
- Step 1. Connect to your database. Create a JDBC Connection as shown in the next picture, and click on "Next >>".
- Step 2. Select the database schema(s) to import. Select the schema (e.g. public), and click on "Next >>".
- Step 3. Set up user management, ignore and click on "Next >>".
- Step 4. Generate pages. Select "don't generate anything" and click on "Next >>".
- Click on "Finish"
Step 2. Create the Data model
We are going to store posts and comments in the database, therefore we will create the data model for the blog. We can create it in two ways:
- create the data model directly in the DB outside Portofino, e.g. via pgAdmin, SQuirreL, ... ,
- use Liquibase embedded in Portofino to create the data model and keep track of the model versions.
In this tutorial we choose the second option. Use a text editor to create the Liquibase file. By convention the file must be in the directory dbs under your app (e.g. apps/default/dbs). The file name must have the name databasename-schema-changelog.xml, (e.g. blog-public-changelog.xml).
Liquibase files are easy to read and easy to write (see the code below). The file is divided into changeset, identified by a unique id, containing the SQL commands.
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd"> <changeSet id="blog-1" author="Giampiero Granatella"> <createTable tableName="post"> <column name="id" autoIncrement="true" type="int"> <constraints nullable="false" primaryKey="true"/> </column> <column name="title" type="varchar(255)"> <constraints nullable="false"/> </column> <column name="summary" type="text"></column> <column name="body" type="text"> <constraints nullable="false"/> </column> <column name="author" type="varchar(100)"> <constraints nullable="false"/> </column> <column name="date" type="date"> <constraints nullable="false"/> </column> </createTable> </changeSet> <changeSet id="blog-2" author="Giampiero Granatella"> <createTable tableName="comment"> <column name="id" autoIncrement="true" type="int"> <constraints nullable="false" primaryKey="true"/> </column> <column name="post" type="int"> <constraints nullable="false"/> </column> <column name="comment" type="text"> <constraints nullable="false"/> </column> <column name="author" type="varchar(100)"> <constraints nullable="false"/> </column> <column name="date" type="date"> <constraints nullable="false"/> </column> </createTable> </changeSet> <changeSet id="blog-3" author="Giampiero Granatella"> <addForeignKeyConstraint baseTableName="comment" baseColumnNames="post" constraintName="fk_post" referencedTableName="post" referencedColumnNames="id"/> </changeSet> </databaseChangeLog>
I have made three changeSet to create the table "post" (blog-1), the table "comment" (blog-2) and the foreign key that links the comments to a post (blog-3). The posts have the fields: id, title, summary, text, author and date. The comments have the fields: id, text, author and date.
Eventually, as an exercise, you can customize it adding new changesets and let the embedded Liquibase to keep your model updated.
Refresh the model by clicking on "Administration" > "Reload Model" to run the Liquibase script just created. Then we synchronize the database ("Administration" > "Connection providers" > "blog" and then click "Synchronize") to update the application model with the objects in the database.
Step 3. Create the “Post” page
Let's create a page to manage the posts as a CRUD page. CRUD operations are at the core of database-driven applications.
To create this page, click on the "+" ("Add Page") in the upper right and compile the form as follows.
Note that we selected "at the top level" in the "Where" field to have the "post" page at the first level of navigation.
Now click on "Create New" and configure the CRUD as shown below.
The “Query” field contains the HQL query (Hibernate Query Language) "from post order by date desc, id desc". This query returns all the rows in the table "post" ordered by date and id.
We also set "post" for the name of the variable; we will use it later for the definition of the comments.
Save the configuration and come back to it. Now you can select the fields that will be used in the CRUD and define which will be insertable, editable, which ot them will appear in the summary (the list table) and in searches.
As shown in the figure above, "id" and the "date" fields are neither insertable nor modifiable.
The "id" field is managed internally by the database with a counter (look in the Liquibase file for its definition), while the date will be automatically generated during the creation of the post.
Go to the Script section at the bottom of the page.
Each Groovy class has hooks where you can add application logic. We'll use Groovy to insert the date automatically. For our purpose implement the createSetup method (executed during the setup of the creation page)
protected void createSetup(Object object) { object.date = new java.util.Date(); }
In the previous code, pay attention to the the object, the element we are working on, persisted by Hibernate. We can access its properties by just writing object.propertyName. In our example, we store today in the "date" field.
Click on "Update Configuration".
We can now create a sample post, and then click on "Create new"
Note that the “date” field is set automatically as we wanted. Click on "Save" and the search page will be as shown below.
Step 4. Create the "Comment" page
Let's manage the comments now.
The page with the comments is a child of the post to which it belongs. Go to the page with post details and create a new page from there.
Notice that we put "as a child of Post" in the "Where" field.
Click on “Create new” and then fill the form as follows.
In this case, the HQL query has a where clause.
%{#post.id} is an OGNL expression which takes the id field from the variable "post" set in the previous step.
In the comments we generate the date automatically, and also manage the relationship with the owning post. As we have seen previously, we make this operation in the "createSetup" method in the Groovy script.
protected void createSetup(Object object) { object.date = new java.util.Date(); object.post = ognlContext.post.id; }
Now click on "Update Configuration".
We can try our application, and insert posts and comments.
A nice feature would be to have the list of comments in the same page as the post. Portofino allows you to display a page child in the parent page. Come back to the post page and click on "Page children" (in the top right corner the icon with a folder), check the flag "Embed in parent?" for the "Comments" page.
With this operation, we reached the goal of our first tutorial.
In the next tutorial we'll introduce permissions and we'll change the graphical layout.