Norbert Hartl

mostly brackets and pipes

Pier Surgery 2: Creating Your Own Widgets

Last year I started really motivated with this pier surgery series. Shame on me that I did only this first article. I almost feel like an open source project on sourceforge. If I lost interest in pier? No, not at all. Quite the opposite happened. Pier is a really generic and complex piece of software. It’s not too easy to understand the internal because it is very generic and sometimes it just appears utterly complex. But it has great potential. At the moment I’m trying more and more to use it as basis for web application development.

There are web applications and there are CMSes. The web applications are programmed to solve some data management issues. A CMS is made to ease the building of a web site structure, uploading images etc. Usually they are quite distinct. Pier offers some things to lower the barrier between the HTML-only and the code-only worlds. As an illustration I want to do a little component that shows some of the integrative stuff. If you use pier you know already that you can easily embed components into your site. If you write an embedded link (surrounded by +) than you will be asked what you want to embed.

One of the choices is component. But what do you need to do in order to have your own component to show in the pull-down? You need to make your own component a subclass of WAComponent. That would make it a seaside component. To ease some of the steps necessary to deal with pier it is a good choice to make your component a subclass auf PRWidget. Here we go.

PRWidget subclass: #MyPierWidget    
   instanceVariableNames: ''    
   classVariableNames: ''   
   poolDictionaries: '' 
   category: 'Pier-Example'

Pier has a notation of abstract and concrete classes. Only concrete ones will be integrated into the component choice. To make it visible we need to add on the class side of our class

   ^ false

The class is now available in the component pull-down under the category Pier Widgets. The name will be My Pier Widget. Pier derives that name from the class name. You can give the component your own name by implemententig a method on the class side

   ^ 'my first pier widget'

It is now called my first pier widget. But it is still in the category Pier Widgets. It is a good idea to have your own category where you easily find your own components. You can change that by implementing a method on the class side

   ^ 'My Pier Widgets'

It will now be display in its own category My Pier Widgets. The only thing that is left to do to make it a fully working widget is to implement the seaside rendering method on the instance side

renderContentOn: html   
    html text: 'this is my first pier widget'

Let’s embed this into our test site. Log into pier and create a page in the top called example1. In the page write the text

this is the example1 page with embedded component +component+

In the following dialogs chose component and then select your component from the pull-down. By now we have created a component and embedded it into the web site. With this we can achieve already a lot of things. Just manage the web site with pier and embed your little widgets wherever you need some special functionality. This covers the things that pier can do with components. But there are also ways how components can do things with pier.

The PRWidget has a method context that gives us access to the structure our component is embedded into. I won’t go into detail how this works. This is left as an exercise for you. Having the access to the pier we can even lookup a strcuture somewhere in the CMS. We can do this by utilizing

PRPathLookup start: self context structure path: '/some/path'PRPathLookup 

does a lookup of a structure starting at self context structure (where we are at the moment) to another structure that is denoted by the path string. Pier extends the anchor tag to utilize this. By writing

html anchor 
   goto: (self context structure: (
      PRPathLookup start: self context structure path: '/example2'));   
   with: 'advance to next page'

we can navigate from inside our component to a different page inside the pier CMS. Just create a page example2 in the root of your CMS and write “this is the target page example2” as text into it. Change the renderContentOn: method to

renderContentOn: html   
   html anchor      
      goto: (self context structure: (
            start: self context structure 
            path: '/example2'));        
      with: 'advance to next page'

If you now go to your /example1 page you will see the link advance to next page. By clicking it you make pier changing the page to the /example2 page. We have created a component that is embedded inside a page in the CMS and the component can instruct the CMS from inside to navigate to somewhere else. The link you navigate is not just an external link where “you know” the target and just link to it. No, you have the target in your hand and pier is creating an appropriate link for it. Change your renderContentOn: to

renderContentOn: html   
   | target |   
   target := PRPathLookup start: self context structure path: '/example2'.  
   html anchor      
      goto: (self context structure: target);       
      with: target title

The anchor will now show whatever title the page we link to has. You can change the title of /example2 afterwards and the link on /example1 will reflect that. The same way we read the title from the target of the link we could access the target in any thinkable manner. In one of the next articles we’ll explore this. I hope I could illustrate how pier and programmed components can interact to lower the barrier between components and CMS.