One step further with Iliad

Tagged:  •    •  

Hi again.

Now I want you to show, how to use the subclassed Iliad.Application class as a real dispatcher.

First, I will create a menu-class, that our web-pages has a seperate menu. And this menu is the same on every page, I created an extra class for that.

Here we are:

Iliad.Widget subclass: Menu [
    | entries |

    entries [ ^entries ]

    addEntry: aString withAction: aBlock [
        self entries add: aString -> aBlock
    ]

    initialize [
        super initialize.
        entries := OrderedCollection new.
        self
            addEntry: 'Home' 
                withAction: [self redirectToLocal: '/'];
            addEntry: 'Login' 
                withAction: [self redirectToLocal: '/login'];
            addEntry: 'Register' 
                withAction: [self redirectToLocal: '/register'].
    ]

    contents [
        ^[ :e |
            | ul |
            ul := e unorderedList.
            ul id: 'nav'.
            entries do: [ :each |
                (ul listItem anchor) text: each key; action: each value
            ]
        ]
    ]

]

And you notice here, the redirectToLocal method of the Iliad.Widget object. This is a direct url, to which we are jumping from the menu. Therefore, these url's have to be configured somewhere...

Our Application Object is the place, where we have to do this dispatching. Our default-entry point the / is already there, this is managed by the #index method. We should have now two additional methods, the #login and #register. Don't forget to put them into the same category as the index method. They all has to be in the <category: 'views'>.

Here is the code for the additional methods:

    login [
        <category: 'views'>
        ^[ :e |
            e add: Login new build
        ]
    ]

    register [
        <category: 'views'>
        ^[ :e |
            e add: Register new build
        ]
    ]

By the way...:
|-
|It returns now a string with 'urpics' instead of 'UrPics'. The other possibility was, to change the proxy-settings of apache, that the /urpics redirect would change to /UrPics. Otherwise, the href would point to /urpics/login and the applications-path would be /UrPics which look a bit strange - I think.
I refactored the path-class-method of the Application!

Okay, now our dispatcher is calling 3 different subclassed Iliad.Widgets. They contain the page-content for the different pages... In an application, most pages are build with a lot of same components, like a header, a menu, and e.g. a footer. So I created a PageTemplate class, which holds all the same content:

Iliad.Widget subclass: PageTemplate [
    | menu |

    menu [ ^menu ]
    menu: aMenu [ menu := aMenu ]

    initialize [
        super initialize.
        menu := Menu new.
    ]

    contents [
        ^[ :e |
            e 
                build: self headerContent;
                build: menu;
                break; break;
                build: self mainContent;
                build: self footerContent.
        ]
    ]

    headerContent [
        ^[ :e |
            e h1: 'My Application!'.
        ]
    ]

    mainContent [
        ^[ :e | ]
    ]

    footerContent [
        ^[ :e |
            e horizontalRule.
            e image source: '/resources/gst_medium.png' alternativeText: 'GNU Smalltalk'.
            e image source: '/resources/iliad_medium.png' alternativeText: 'Iliad Framework'.
        ]
    ]

]

And the subclassed "pages" from this one looks like:

UrPics.PageTemplate subclass: UnknownHome [

    mainContent [
        ^[ :e |
            e h1: 'UnknownHome Object!'.
        ]
    ]

]

UrPics.PageTemplate subclass: Login [

    mainContent [
        ^[ :e |
            e h1: 'Login Object!'.
        ]
    ]

]

UrPics.PageTemplate subclass: Register [

    mainContent [
        ^[ :e |
            e h1: 'Register Object!'.
        ]
    ]

]

In these classes, we only have to overwrite the mainContent part.

And with all these modifications, you would end with the following:

2450427.png

So again, happy coding!

Joachim.

Joachim,

in your #contents methods you could use the Element>>build: method like this:

contents [
        ^[ :e |
            e 
                build: self headerContent;
                add: menu build;
                break; break;
                build: self mainContent;
                build: self footerContents.
        ]
    ]

Ahh! Thanks Nicolas!

That looks a lot better than my approach!

If you agree, I'll change the code in the example, that others that might read it wont't be confused by my solution...

Joachim.

As Paolo proposed on the mailing list, now you can even do:

contents [
    ^[:e |
        ...
        e 
            build: aWidget;
            build: self footerContents]
]

Seen..., tried..., worked! and changed in the HowTo!

Thanks to Paolo, You and Sebastien!
Looks a lot nicer than before...(my first code).

Best regards,
Joachim.

User login