The previous post on the PHP Bridge Design pattern shows how a Bridge pattern has two connected but independent interfaces to make design flexibility for different online devices. This post explores how that same flexibility extends to making a Content Management System (CMS). Most of the Bridge participants in the design are unchanged or only slightly changed.

The major change in the Bridge design pattern actually makes it more in line with the original intention of the Bridge. The RefinedAbstraction participant (RefinedPage) no longer includes concrete content for the page. Instead, it provides the parameters for a client to add the content. This change adds flexibility and gives the developer more options than the original StandardPage class.

Two UIs and Multiple Clients

In order to make a decent CMS, you need to have at least two UIs:

An Administrative UI for previewing and adding new content

A User UI for viewing but not changing content

In creating the Administrative UI (HTML5/PHP/JavaScript), I had to use two PHP clients. One client is to preview the new data entered by the admin and the other client is to store the new data (after previewing and possibly editing it). Figure I provides a general overview of the UIs and the Clients that will use the Bridge pattern for a CMS:

Figure 1: User Interfaces and Clients

The Administrative UI (BridgeCMSAdmin.html) uses the BridgeCMSAdminClient class for displaying different content and the StoreDataClient class for storing the information in a JSON file. An important condition to remember is that when using JSON files, you need to make their permissions available for reading and writing. (See the Memento II post and the special mini-post on setting permissions on Raspberry Pi systems.) Thus, the need for two clients; one for previewing new material and another for storing it in a JSON file. A lot of files are involved in this CMS; so take a look at the two different UIs and download the files for everything:

To use the Administrator Module, follow these steps in the listed order:

Type in Header data, select a graphic from the drop down menu, and then type in text for the body.

Click a Desktop, Tablet or Phone radio button and then click Preview Page

When you have everything the way you want it, First click Transfer to Storage and next click Store Data

Now click the Play button and see the page you created.

In the admin UI, I used a drop down menu with only three selections for the graphic file since only three were set up. However, it would not be difficult to upload graphics and their file names. (See the post on uploading graphics using the Template Method.)

The UIs and their Clients

The main feature in creating a CMS is the Administrative UI. It calls two different clients for dealing with previews and persistent data storage. Unless you’re planning on a fairly long body text entry, the JSON file works fine. Look at the code below, and you can see that one of the issues is that the data that is entered for the preview must be transferred to a different form. It transferring the data is a simple task with a little JavaScript. The following script is all it takes:

As you can see, it is almost identical to the client used in the first post on the PHP Bridge pattern. (Remember, code re-use is an essential goal of both OOP and Design Patterns.) You will see the same code re-use in the Bridge portion of the program. Figure 2 provides an overview of the Bridge portion:

Figure 2: Bridge used in CMS

While the code is not identical to the PHP used in the initial Bridge example, it’s pretty close, and as you can see, the design is the same.

The Bridge (Again)

Some small but key changes have been made in the Abstractor classes, while the Implementor interface/classes are virtually the same. (There’s that re-use again). First, take a look at the two classes that make up the Abstractor side of the equation:

The Abstractor has an aggregate relationship with the Implementor (IDevice) in the reference to the concrete implementation of IDevice. The Implementor participants have changed little from the initial post of the Bridge pattern. They have not needed to. As this project grows from a simple example to a more and more complex CMS, the objects still work well together and can be changed independently of one another. That’s the beauty of design patterns. They handle complex quite well.

With the interface and classes that make up the Implementator, you see very little change compared to the original. As you can see in Figure 3, each concrete implementation receives content through the parameters, passes those values into the big heredoec string and returns it all to the client. The client in this case is actually an aggregate part of the bridge between the the Abstractor and Implementor participants. If you look at the IPage buildPage() method, you can see that the method prints (using the echo statement) the Web page embedded in the returned heredoc string. Taken as a whole, the Bridge is the composite object that displays the Web page from any one of the three devices. The following are all of the objects in the Implementator side of the Bridge:

The object in the form of a Web page can be understood in the context of OOP PHP as an object. Instead of thinking of and treating Web pages as separate entities from other PHP objects, by treating them like any other object, you can program them with the flexibility of OOP PHP. They then become dynamic entities instead of static ones.

One Last Bridge to Cross

To complete the Bridge CMS project, we need one more (small) element. Building on this and the previous Bridge design pattern, the little page that has been dynamically created and stored in a JSON file, needs a Web site context. A CMS that changes one dynamic aspect of a Web site while leaving the static material in the page is far more useful than one that just generate a small site. So, in the next and final installment of the Bridge CMS, the Web context will be the last piece of the puzzle.