Ferreteria/v2/usage/browser

From Woozle Writes Code
< Ferreteria‎ | v2‎ | usage
Jump to navigation Jump to search

How to generate browser output depends on what kind of output you want to generate.

Page Title

There are actually two kinds of page title, both of which can be set or updated at any time prior to the rendering phase:

  • browser title: what the browser shows in its window frame
  • content title: text displayed in a standard prominent format at the top of the page, sometimes with a menu

It's frequently best to set them both to the same thing, but sometimes you want to format the browser title differently, and sometimes you might want to use HTML markup in the content title (font effects, links, etc) which would not work for the browser title.

fcApp::Me()->GetPageObject()->SetPageTitle('Your Title');   // set titles for both browser and content
// ...or...
fcApp::Me()->GetPageObject()->SetBrowserTitle('Your Title');    // set the browser title
fcApp::Me()->GetPageObject()->SetContentTitle('Your Title');    // set the content title

display format

Ferreteria can be configured (via your site's fcPage_standard descendant) to automatically insert your site's name or other text in the browser title (as an indicator that these pages are on your site) while leaving the content title exactly as requested.

We have found that it's better to show the set title (the string you request for the title, which should describe the specific page you're displaying) before the site name, because tabs can be displayed in such a way that only the first part of the title text is visible, and the site name can easily take up all of the available space, leaving no way to distinguish between pages at a glance. A better way to indicate site ownership of tabs is to have a distinctive favicon, though there's no harm in also having your site name after the page descriptor.

Page Content

fcApp::Me()->AddContentString('your content here');

Note that page content will be preserved in the event of an internal redirect, and should be displayed automatically by the target page.

Status Messages

To indicate the status of an attempted operation, use one of the following:

fcApp::Me()->GetPageObject()->AddErrorMessage($s);
fcApp::Me()->GetPageObject()->AddWarningMessage($s);
fcApp::Me()->GetPageObject()->AddSuccessMessage($s);

...where $s is the message you want to display.

Section Headers

Section headers are created from scratch:

$oHdr = new fcSectionHeader('Your Section Title',$oMenu);

The $oMenu parameter is optional. The Section Header object must be rendered in order to show up on the page:

fcApp::Me()->AddContentString($oHdr->Render());

Header Menus

VbzCart's Supplier menu as implemented on vbz.net, showing the Departments listing selected in the page-header menu

The content header (which includes the content title) has its own menu object, which you retrieve like this:

$oMenu = fcApp::Me()->GetHeaderMenu();

To add a menu to a section header, just create a new menu object (from scratch) before you create the section header object:

$oMenu = new fcHeaderMenu();
$oHdr = new fcSectionHeader('Your Section Title',$oMenu);

In either case, you can then add items to the $oMenu object, which will be rendered when $oHdr is rendered. If you're using the page header, then it's rendered automatically; if you've created a subheader (as above), then you can render it into your output string ("$out", by convention) like this:

$out = $oHdr->Render();

Menu Content

Menu items currently consist of three main types:

  • standalone links (name/value pair, name optional)
    • These do not currently support independent toggle-values under the same name, though perhaps they should. For now, you have to use a different name for each value to toggle.
  • group folders (shows static text and also has a name)
  • group options (like radio buttons, all sharing the group folder's name but each with its own value)

Actual code for showing menu options for a supplier in VbzCart:

                                 // ($sGroupKey,$sKeyValue=TRUE,$sDispOff=NULL,$sDispOn=NULL,$sPopup=NULL)
          $oMenu->SetNode($ol = new fcMenuOptionLink('do','edit',NULL,'cancel','edit '.$sName));
          $oMenu->SetNode($oGrp = new fcHeaderChoiceGroup('show','Manage'));
                                   // ($sKeyValue,$sPopup=NULL,$sDispOff=NULL,$sDispOn=NULL)
	    $oGrp->SetChoice($ol = new fcHeaderChoice('dept',$sName.' departments','departments'));
	    $oGrp->SetChoice($ol = new fcHeaderChoice('rreq',$sName.' restock requests','restocks'));
	    $oGrp->SetChoice($ol = new fcHeaderChoice('events',$sName.' system events'));

...where $sName is the supplier's name (an optional frill to make the popups a little more contextual).

Menu Values

Items actually selected on menus can be retrieved by either of two methods:

  • Querying the menu item object (preferred)
  • Querying the pathinfo object

via menu item object

The user's selection can be retrieved from the menu item objects by adding some lines to the above example:

	  $oMenu->SetNode($ol = new fcMenuOptionLink('do','edit',NULL,'cancel','edit '.$sName));

	    $doEdit = $ol->GetIsSelected();
	    
	  $oMenu->SetNode($oGrp = new fcHeaderChoiceGroup('show','Manage'));
						// ($sKeyValue,$sPopup=NULL,$sDispOff=NULL,$sDispOn=NULL)
	    $oGrp->SetChoice($ol = new fcHeaderChoice('dept',$sName.' departments','departments'));
	    $oGrp->SetChoice($ol = new fcHeaderChoice('rreq',$sName.' restock requests','restocks'));
	    $oGrp->SetChoice($ol = new fcHeaderChoice('events',$sName.' system events'));

	    $sShow = $oGrp->GetChoiceValue();

(I also made this change to the actual production VbzCart code.) While this has the slight disadvantage that you can't retrieve the user's menu choice(s) until the menu has been created, it also frees your code from any dependence on what values or keys you use in the pathinfo. I could now change 'rreq' to just 'rr' or 'restock-request' without having to make any other code changes.

via pathinfo object

The pathinfo object can be accessed like this:

$oPathIn = fcApp::Me()->GetKioskObject()->GetInputObject();

In the above menu example, the user's selection could be retrieved like this:

	$doEdit = ($oPathIn->GetString('do') == 'edit');   // the 'edit' toggle
	$sShow = $oPathIn->GetString('show');	// dept/rreq/events

This can be done before the menu items are actually created (a small advantage to this method).

Input

User input comes through the browser in two ways:

  • clicking on a link - Ferreteria internal links generally contain pathinfo which can contain quite a lot of information about what the user wants to see or do
  • submitting a form - the traditional way for users to submit input to a browswer

A reasonably good practice for building admin-UI output – especially when remediating code that wasn't written with Ferreteria's current API in mind – is to place this code at the start of each method that needs to read input:

	$oPathIn = fcApp::Me()->GetKioskObject()->GetInputObject();
	$oFormIn = fcHTTP::Request();

This provides objects which allow you to access both types of input via a common interface.

A better practice for pathinfo is to query the menu objects which created the links (see "via menu item object" above).