Home | Wiki | OI 1.x Docs | OI 2.x Docs |
OpenInteract Guide to Components - Building big things from small pieces
This document describes what a component is in OpenInteract as well as how to create one.
Almost all substantive websites have certain graphical (or textual) items that are repeated on a large number of pages. These can be as simple as a standard copyright notice, or as complicated as a list of the most recent forum posts.
If you find yourself using something in a number of pages, odds are that it can be represented as a component. It's a little more work in the beginning, but it pays off great dividends the more pages in which you use the component, and even greater if you ever have to modify it.
Most generally, a component is any aspect of your page that might be used on more than one page. It can also be any aspect of your page that you want to make separate so you can make your template shorter. All components return fully-formed HTML.
A component can be very short or very long. It can be 100% static HTML or have only enough HTML to format text on the page in a coherent manner.
Technically, just about everything in OpenInteract is a component. Even when you call a simple page that displays a form to edit an object, you're calling a component. But for consistency, we refer to more complicated components as 'handlers'.
In this idea of everything being a component, you can think of the main template as a container for some text and placement of components, which can themselves contain components, which can themselves contain components...
The configuration file holds naming information for all components. There are two basic types of components: template-only components and those with code behind them. The difference in configuration is covered below in How to Create a Component.
Calling a component from a template is quite simple:
Example: Calling a component
This example is using the Template Toolkit processing engine (see
OpenInteract::Template::Plugin
for how to call components).
[% OI.comp( 'component_name', param = value, param = value ... ) %]
The HTML returned by the component will be put in place of the component call.
The 'component_name' is a valid OpenInteract action. If you want to simply include a template, you can use the syntax:
[% PROCESS mypkg::mytemplate %]
or with additional parameters:
[% PROCESS mypkg::mytemplate( foo = 'bar', baz = 42 ) %]
See additional documentation on templates for more.
Wrong component name
If the component name is not found, the system will throw an error with code 312 and return the string 'Error: Unknown component called'. In the future, we'll probably make this message configurable.
Passing parameters
The parameters passed into the component follow many of the same rules as in the templating module. However, since OpenInteract have the standard of having a hashref as the first argument to a handler/component, we massage the parameters a little bit.
Looking into the documentation for the Template Toolkit, you'll see subroutine calls like this:
[% sub( param, param, param = value, param = value ) %]
The docs helpfully go on to say that all named parameters are put into a single hashref and passed as the last parameter. The Component handler takes all of the unnamed parameters and puts them into the '_unnamed_' key of the hashref, then passes the hashref as the ordinary first argument.
Example:
[% OI.comp( 'mycomponent', value1, value2, param3 = value3 ) %]
sub handler { my $class = shift; my $p = shift; print " --> Value of param3: $p->{param3}\n"; print " --> Unnamed: ", join " >> ", @{ $p->{_unnamed_} }, "\n"; ... }
Results:
--> Value of param3: value3 --> Unnamed: value1 >> value2
Yes, this is an incentive to use named parameters. :) (Or rather, a disincentive to using placement parameters.)
Every component simply calls an action. So you could define an action:
googlesearch => { class => 'OpenInteract::Handler::Google', method => 'search', }
And call a component:
[% OI.comp( 'googlesearch', search_param => customer.company_name ) %]
This would deposit the results of the method right into your HTML.
Chris Winters (chris@cwinters.com)