The custom model creates a php class and you are required to define the body of the generate function of the class. This function must return whatever content is to be generated. Here we see an example of a generate function that generates the classic "Hello World!" page.
Notice that the entire function declaration is not entered, only the body of the function. The function name is indicated by the Section Id in column 3 and the Location column is set to Replace Body to indicate that only the body portion if the function is being entered.
The Example Code button can be clicked to obtain examples of other functions that can be coded. To use one of these functions, change the Function Type column from example to function.
In most cases the custom page is going to need information from various sources in order to decide what to generate. Here we discuss some of the more common data sources.
From Site Information
Most custom pages require access to the site object. In order to gain access to the site object, the custom page class, or one of its parent classes, must define a set_site method. There are several ways that this can be achieved including the following:
This site object contains with a great deal of information about the current environment. For example, consider the following generate code:
Requesting this page in the live site would return the text 'This is the live site'. In the sandbox this would return 'This is the sandbox site'.
The site object also exposes all dollar functions programmatically. Here we see a sample generate function that appears in the page called sitemap located in system. This is used to build a sitemap page (as opposed to an xml sitemap) for any site that has a menu or a bootstrap navigation object.
Notice that the first parameter to the site object's dollar_function method is the name of the function that you want to execute. This is followed by the parameters that you would normally pass to the function. Pass in NULL to skip parameters. We will see later that it is also possible to pass the parameters using a keyed array. When there are several parameters that is the preferred approach for increased readability.
From Passed Parameters
Let's suppose you are building a page that returns employee information and we want to allow the following three parameters to be passed to the page:
There are two main ways to dynamically pass these values:
Let's look at a sample custom page that uses these parameters.
Recall that all custom pages are implemented as php classes. Methods of this class will be called at various points in the page building/rendering process so you might want to define some class variables to "remember" information from one call to the next. In our example we are going to define the following class properties (variables):
Next we will need a way to copy parameters passed into this page over to the class properties we defined. This could be done using the set_parameter method as we see here:
Notice this method accepts a parameters object as a parameter. This is the same object that can be accessed from most code via $this->site->parameters. This object offers several ways to extract parameter data. Here we are using the set_if_supplied method to set properties if they have been passed. Other methods that could be used include:
The get_required_parameter method would trigger an error if the requested parameter was not passed.
We could also use, this method:
This would set the occupation property to the occupation value that was passed to the program, if no such value was passed it would set it to '*'.
Note that it is not necessary to save your parameters in class variables. This is done when using the set_parameters method so that the parameters are available to other methods, such as generate. If you only need these parameters within the generate method you can also access the site's parameters object directly as we show here:
Let's look at some examples of how these parameters can be passed into this page.
Passing Parameters Via the Querystring
Suppose our page is called emplist and the page is requested using a url such as www.example.com/emplist?last_name=smith&city=toronto
This would have the effect of setting the last_name and city parameters.
Passing Parameters Via the $page function
If you are rendering the page as a component of another page, you can supply parameters to the $page function as in:
It is important to note that parameters passed to the page function in this way cannot be overridden via the querystring. The parameters object will define the union of both sets of parameters but the page parameters will take precedents over the querystring parameters.
The pre_generate method should be used if you need to define any custom styles or script or set certain containers. For example, let's suppose that you want to dynamically populate the meta description for the page based on the parameters passed to it. This could not be done in the generate method since the meta description tag would have already been generated by the time the page's generate method is triggered. On the other hand, you can do this in the pre_generate method as we see in this example:
Since this page could be embedded into different layouts, it is unwise to assume that the containing layout even supports meta descriptions. For example, perhaps this page is being rendered as the contents of an email. Meta data would normally not be rendered in such a case. We handle this uncertainty by first asking the layout for the metatags object and we only attempt to update the meta description if the layout returned an object.
Other page content, such as title and header tags could be updated dynamically if suitable containers exist within the current layout (codeframe). The following sample code shows how this could be done:
A more convenient method for setting these attributes is to use the trait named dynamic_seo. In so doing you can set these properties as follows:
In the above example we only show a subset of the parameters that can be defined when calling the site object's add_script method. Let's review the other parameters that can be passed. Here we see the signature of the method:
Let's review all of the keys that can be set in the array passed in parameter 2.
Adding Styles Dynamically
This signature of the site object's add_styles method is similar to add_script as we see here:
The parameters behave in a similar way except parameter 2 is an array used to configure style behavior. The keys to this array are defined below:
Extracting Information From an SQL Database
In many cases the data you will be presenting in the generate method will come from a database. Often, you will be able to use the db_table_browse model for this purpose but there will be times when you may want more control over the presentation of the data. There are several ways that a custom generate method can access SQL data.
When using the first option, you may want to utilize the function code builder by clicking on the $function Help button shown here.
This will bring up a screen that will help you ascertain what parameters the function needs as we see below:
After clicking on the Accept button in the popup page, the suggested code will be returned next to $Function Help button as we see here:
Copy and paste the code to use this as part of your generate method. In many cases you will need to adapt the code to cater to special situations. Here we show how the search fields could be dynamically added based on the parameters passed to the page.
Developing Custom SQL Queries
Sometimes the queries you need to write may be too complex to be handled by the $dbselect or $dblookup functions. In such a case you can build your query from scratch using supplied base classes provided by the GenHelm framework. In this example, we show a custom query developed using the supplied sql_handler class.
Prevent Parsing of Dollar Functions
If you are using the custom model to generate content which may contain dollar functions but you don't want these dollar functions to be parsed you can supply an optional function named get_parse_dollar as shown here:
Since this function returns false, any dollar functions generated by the custom component will remain as dollar functions, they won't be resolved. Keep in mind that if your page is nested inside another page that does parse dollar functions, your page's dollar functions may be parsed as part of the container page's rendering.
Using Custom Pages in Combination with Other Models
Another potential data source for custom pages may come from components generated by other models. For example, the xml_sitemap model allows you to specify pages from system and other inherited sites to be included in the xml sitemap for the site. The information is saved as a php "snippet" (.inc file). The sitemapindex page (defined in system) is based on the custom model and it uses components generated by the xml_sitemap model to determine what the xml sitemap should contain for the current site.
Some of your custom pages may want to render on-page messages within the message area codeframe object. To do so, they should first obtain a copy of the message_area object from the site's layout object to make sure that the layout they are currently running within supports the message object. Here we show how you can check for this.
Once you have determined that your container codeframe supports standard messaging there are a number of ways that your custom page can set a message. One option is to assign the messages directly to the message object as shown here:
The above code defined within the generate method of the custom page would render the following content:
Custom pages should generally call upon other objects to implement business logic and processes. In so doing, the business logic becomes more reusable since it is not tightly coupled to a specific custom page. If the objects that your custom page calls extend the standard_base class, you will normally want to capture any messages that your called objects have set.
Here we show an example in which the custom generate method calls another "processor" object which may set one or more messages. After calling the object we transfer any messages that it may have set to the message_area object by calling the transfer_your_messages_to_me method. If needed, we can also add more messages to the message_area object.
The transfer_your_messages_to_me method should normally be called after calling any object that inherits standard_base (even if the object does not set a message). By doing so, the caller's code will not have to be changed if the called object is updated at a later date and introduces message assignments.
In most cases, the caller will pass itself as a parameter to transfer_your_messages_to_me as in:
The advantage of having a standard approach to message handling is that the object you call can call methods of other objects which call methods of still other objects and if all of these objects handle messaging the same way all messages will percolate up the call chain right back to you without requiring any complex logic.
Including the trait Definition
Traits defined using the php_trait model are generated into the trait subfolder of the main classes folder. Therefore, to incorporate traits defined within system you first have to require the trait using:
If the trait is defined within the current site, it should be included using:
In each case, tname is the name of the trait to be used.
The reference should be defined within the Before Class definition as shown.
Adding the use Statement
Within the Custom Code section, set the Section Type to be use and set the Location to be After Last Sibling. Enter the full use statement within the Custom Code column as shown:
Sorting Properties and Functions
You can sort both properties and functions (methods) by using the sort command. To only sort properties you can enter the command sort properties. To only sort functions, enter the command sort functions.