Re: How to Implement a Menu Component

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

Re: How to Implement a Menu Component

Richard Eng
I'll also offer up how I do it, a slight variation on Michael's approach...

I start with a regular, static HTML mockup of my website (complete with
separate, external CSS files), comprising a number of webpages. For each
webpage, I create a class. Each class renders the HTML of the corresponding
static webpage.

(Actually, I start with a "template" class that renders individually--ie,
with individual methods--the logo, the menu, the footer, the sidebar, etc.
Each webpage class subclasses the template. This allows me to customize the
look of each webpage, eg, perhaps I don't want a menu or sidebar for a
particular page. I'm leveraging HTML reuse here as best I can. And note the
side-effect benefit: the menu method, which renders an unordered list, can
make #call: <webpage class> calls that replace the entire page, rather than
just the content subcomponent!)

I also make use of "announcements" in my GSServiceCentre webpage, which, as
I alluded to above, has a customized look--no navigational menu, but rather
a menu in the sidebar [implemented with announcements] that swaps out
content subcomponents. Really quite nifty, actually.

It seems to me that announcements are too specialized (swapping out content
subcomponents only) to be used for general page handling as I've outlined
above. (I'm sure it can be done, but at what cost to complexity or design
obfuscation?)

Regards,
Richard

------------

> My Seaside application have 3 components
> 1.) main component with two instance variables for menu and content
> and a children method (array with: menu with: content)
> 2.) menu subcomponent
> 3.) content subcomponent

Here's how I do it, but your mileage may vary:

I have an "Interface" component for each of my main sections.  My
Welcome page, which handles logins and new user creation is called
"GHWelcomeInterface".  Once you get beyond that, you are sent to the
meat of the app, the GHUserInterface.

GHUserInterface handles rendering the menu and has a content
subcomponent.  Since the menu is actually part of the GHUserInterface
instance rather than a subcomponent, it just swaps out 'main' (or
'content' in your case) with the appropriate content instance.

So, just to be clear, I don't have three components, I just have two:
one that handles the general state of things (including the menu), and
the other is the actual content.

Hope this helps,

Michael Gorsuch


_______________________________________________
Seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: How to Implement a Menu Component

Conrad Taylor
Hi, do you have sample code to compliment the description below?

Thanks,

-Conrad

 
On 7/30/07, Richard Eng <[hidden email]> wrote:
I'll also offer up how I do it, a slight variation on Michael's approach...

I start with a regular, static HTML mockup of my website (complete with
separate, external CSS files), comprising a number of webpages. For each
webpage, I create a class. Each class renders the HTML of the corresponding
static webpage.

(Actually, I start with a "template" class that renders individually--ie,
with individual methods--the logo, the menu, the footer, the sidebar, etc.
Each webpage class subclasses the template. This allows me to customize the
look of each webpage, eg, perhaps I don't want a menu or sidebar for a
particular page. I'm leveraging HTML reuse here as best I can. And note the
side-effect benefit: the menu method, which renders an unordered list, can
make #call: <webpage class> calls that replace the entire page, rather than
just the content subcomponent!)

I also make use of "announcements" in my GSServiceCentre webpage, which, as
I alluded to above, has a customized look--no navigational menu, but rather
a menu in the sidebar [implemented with announcements] that swaps out
content subcomponents. Really quite nifty, actually.

It seems to me that announcements are too specialized (swapping out content
subcomponents only) to be used for general page handling as I've outlined
above. (I'm sure it can be done, but at what cost to complexity or design
obfuscation?)

Regards,
Richard

------------

> My Seaside application have 3 components
> 1.) main component with two instance variables for menu and content
> and a children method (array with: menu with: content)
> 2.) menu subcomponent
> 3.) content subcomponent

Here's how I do it, but your mileage may vary:

I have an "Interface" component for each of my main sections.  My
Welcome page, which handles logins and new user creation is called
"GHWelcomeInterface".  Once you get beyond that, you are sent to the
meat of the app, the GHUserInterface.

GHUserInterface handles rendering the menu and has a content
subcomponent.  Since the menu is actually part of the GHUserInterface
instance rather than a subcomponent, it just swaps out 'main' (or
'content' in your case) with the appropriate content instance.

So, just to be clear, I don't have three components, I just have two:
one that handles the general state of things (including the menu), and
the other is the actual content.

Hope this helps,

Michael Gorsuch


_______________________________________________
Seaside mailing list
[hidden email].org
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside


_______________________________________________
Seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: How to Implement a Menu Component

Richard Eng
In reply to this post by Richard Eng
Conrad Taylor wrote:
----------
Hi, do you have sample code to compliment the description below?
Thanks,

-Conrad


On 7/30/07, Richard Eng <richard.eng at rogers.com> wrote:

>
> I'll also offer up how I do it, a slight variation on Michael's
> approach...
>
> I start with a regular, static HTML mockup of my website (complete with
> separate, external CSS files), comprising a number of webpages. For each
> webpage, I create a class. Each class renders the HTML of the
> corresponding
> static webpage.
>
> (Actually, I start with a "template" class that renders individually--ie,
> with individual methods--the logo, the menu, the footer, the sidebar, etc.
> Each webpage class subclasses the template. This allows me to customize
> the
> look of each webpage, eg, perhaps I don't want a menu or sidebar for a
> particular page. I'm leveraging HTML reuse here as best I can. And note
> the
> side-effect benefit: the menu method, which renders an unordered list, can
> make #call: <webpage class> calls that replace the entire page, rather
> than
> just the content subcomponent!)
>
> I also make use of "announcements" in my GSServiceCentre webpage, which,
> as
> I alluded to above, has a customized look--no navigational menu, but
> rather
> a menu in the sidebar [implemented with announcements] that swaps out
> content subcomponents. Really quite nifty, actually.
>
> It seems to me that announcements are too specialized (swapping out
> content
> subcomponents only) to be used for general page handling as I've outlined
> above. (I'm sure it can be done, but at what cost to complexity or design
> obfuscation?)
>
> Regards,
> Richard
----------------

These are the classes representing my various webpages:

#GSAboutUs
#GSContactUs
#GSHomePage
#GSRegistrationLogin
#GSServices

They all subclass #GSTemplate which has the following methods:

#renderAdditionalLinksOn:
#renderFooterOn:
#renderLatestNewsOn:
#renderLinksOn:
#renderLogoOn:
#renderOtherInformationOn:
#updateRoot:

So, for example, #renderContentOn: for #GSServices looks like this:

renderContentOn: html
 html div
  id: 'main';
  with:
   [self renderLinksOn: html.
   self renderLogoOn: html.
   html div
    id: 'content';
    with:
     [self renderMenuOn: html.
     html div
      id: 'column1';
      with:
       [self renderAdditionalLinksOn: html.
       self renderOtherInformationOn: html].
     html div
      id: 'column2';
      with: [html heading level: 1; with: 'services']].
   self renderFooterOn: html]

And #renderMenuOn: looks like this:

renderMenuOn: html
 html div
  id: 'menu';
  with:
   [html unorderedList:
    [html listItem:
     [html anchor
      callback: [self call: GSHomePage new];
      with: 'home'].
    html listItem:
     [html anchor
      callback: [self call: GSAboutUs new];
      with: 'about us'].
    html listItem:
     [html anchor
      id: 'selected';
      with: 'services'].
    html listItem:
     [html anchor
      callback: [self call: GSRegistrationLogin new];
      with: 'registration/login'].
    html listItem:
     [html anchor
      callback: [self call: GSContactUs new];
      with: 'contact']]]

Note that all of the above is a direct mapping of static HTML to Seaside
code, using the web design template that I got from www.openwebdesign.org.
This is particularly nice because the web design template has clear
separation between clean standard-compliant HTML and CSS--it makes my job so
much easier.

#GSServiceCentre is a special-case webpage. It's the main service page for
my website. It does not require the navigational menu, so I don't include
it:

renderContentOn: html
 html div
  id: 'main';
  with:
   [self renderLinksOn: html.
   self renderLogoOn: html.
   html div
    id: 'content';
    with:
     [html div
      id: 'column1';
      with:
       [self renderLogoutOn: html.
       self renderSideMenuOn: html].
     html div
      id: 'column2';
      with: [html render: selectedComponent]].
   self renderFooterOn: html]

The sidebar menu for "service items" is implemented using announcements:

renderSideMenuOn: html
 html div
  class: 'sidebaritem';
  with:
   [html div
    class: 'sbihead';
    with: [html heading level: 1; with: 'service items'].
   html div
    class: 'sbilinks';
    with: [html render: menu]]

Part of the announcement setup involves building the menu (I won't include
all the announcement code):

buildMenu
 menu := GSMenu new.
 #('Ask a question' 'Consultation' 'View my videos' 'View my documents')
 with: {WACounter. GSConsultation. WACounter. WACounter}
  do: [:each1 :each2 |
   | menuItem |
   menuItem := menu menuItemNamed: each1
    withContent: each2 new.
   menuItem announcer
    when: GSMenuItemClicked
    do: [:ann | selectedComponent := ann menuItem component]].

Note that this is a temporary mockup. WACounter is just a placeholder.

On Thursday, I'll show you guys the work-in-progress website, which is
currently forwarded to my test server at home. (This server is rarely up but
just for you folks, I'll leave it up and running for a couple of days.)

Ta-ta till then...

Regards,
Richard

_______________________________________________
Seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: How to Implement a Menu Component

Richard Eng
In reply to this post by Richard Eng
As promised, I have my test server at home up and running. The URL is:

http://www.goodsexnetwork.com/

Some of the links do nothing. The most interesting page is
"REGISTRATION/LOGIN". You can register and you can login. The Service Centre
page does nothing exciting, except Logout.


My Apache2 configuration is dead-simple. The reason is because I couldn't
adapt any of the blog posts I found about "reverse proxy" and "URL
rewriting" and get them to work. Apache is extremely arcane and I have a
hard time understanding it.

Anyway, here's my Apache2 httpd.conf:

ProxyRequests off
DocumentRoot /var/www
ProxyPass  /goodsexnetwork  http://localhost:9090/seaside/goodsexnetwork
ProxyPassReverse  /goodsexnetwork
http://localhost:9090/seaside/goodsexnetwork

I guess I'll have problems later with scaling and load-balancing. But I'll
cross that bridge when I come to it.


I'll leave the server on till Friday morning. Have to conserve electricity,
you know...  :-)

Regards,
Richard


===========================================================
Richard Eng wrote:

These are the classes representing my various webpages:

#GSAboutUs
#GSContactUs
#GSHomePage
#GSRegistrationLogin
#GSServices

They all subclass #GSTemplate which has the following methods:

#renderAdditionalLinksOn:
#renderFooterOn:
#renderLatestNewsOn:
#renderLinksOn:
#renderLogoOn:
#renderOtherInformationOn:
#updateRoot:

So, for example, #renderContentOn: for #GSServices looks like this:

renderContentOn: html
 html div
  id: 'main';
  with:
   [self renderLinksOn: html.
   self renderLogoOn: html.
   html div
    id: 'content';
    with:
     [self renderMenuOn: html.
     html div
      id: 'column1';
      with:
       [self renderAdditionalLinksOn: html.
       self renderOtherInformationOn: html].
     html div
      id: 'column2';
      with: [html heading level: 1; with: 'services']].
   self renderFooterOn: html]

And #renderMenuOn: looks like this:

renderMenuOn: html
 html div
  id: 'menu';
  with:
   [html unorderedList:
    [html listItem:
     [html anchor
      callback: [self call: GSHomePage new];
      with: 'home'].
    html listItem:
     [html anchor
      callback: [self call: GSAboutUs new];
      with: 'about us'].
    html listItem:
     [html anchor
      id: 'selected';
      with: 'services'].
    html listItem:
     [html anchor
      callback: [self call: GSRegistrationLogin new];
      with: 'registration/login'].
    html listItem:
     [html anchor
      callback: [self call: GSContactUs new];
      with: 'contact']]]

Note that all of the above is a direct mapping of static HTML to Seaside
code, using the web design template that I got from www.openwebdesign.org.
This is particularly nice because the web design template has clear
separation between clean standard-compliant HTML and CSS--it makes my job so
much easier.

#GSServiceCentre is a special-case webpage. It's the main service page for
my website. It does not require the navigational menu, so I don't include
it:

renderContentOn: html
 html div
  id: 'main';
  with:
   [self renderLinksOn: html.
   self renderLogoOn: html.
   html div
    id: 'content';
    with:
     [html div
      id: 'column1';
      with:
       [self renderLogoutOn: html.
       self renderSideMenuOn: html].
     html div
      id: 'column2';
      with: [html render: selectedComponent]].
   self renderFooterOn: html]

The sidebar menu for "service items" is implemented using announcements:

renderSideMenuOn: html
 html div
  class: 'sidebaritem';
  with:
   [html div
    class: 'sbihead';
    with: [html heading level: 1; with: 'service items'].
   html div
    class: 'sbilinks';
    with: [html render: menu]]

Part of the announcement setup involves building the menu (I won't include
all the announcement code):

buildMenu
 menu := GSMenu new.
 #('Ask a question' 'Consultation' 'View my videos' 'View my documents')
 with: {WACounter. GSConsultation. WACounter. WACounter}
  do: [:each1 :each2 |
   | menuItem |
   menuItem := menu menuItemNamed: each1
    withContent: each2 new.
   menuItem announcer
    when: GSMenuItemClicked
    do: [:ann | selectedComponent := ann menuItem component]].

Note that this is a temporary mockup. WACounter is just a placeholder.

On Thursday, I'll show you guys the work-in-progress website, which is
currently forwarded to my test server at home. (This server is rarely up but
just for you folks, I'll leave it up and running for a couple of days.)

Ta-ta till then...

Regards,
Richard


_______________________________________________
Seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside
Reply | Threaded
Open this post in threaded view
|

Re: How to Implement a Menu Component

Richard Eng
In reply to this post by Richard Eng
The following user is already in the database:

username: [hidden email]
password: AstonMartin

You can try registering it to see the error message.

Regards,
Richard


_______________________________________________
Seaside mailing list
[hidden email]
http://lists.squeakfoundation.org/cgi-bin/mailman/listinfo/seaside