Tags:
component1Add my vote for this tag twiki_application1Add my vote for this tag user_interface1Add my vote for this tag create new tag
, view all tags

MasonPlugin

This plugin allows to embed calls to Mason components within topics.

Description

Mason is a powerful tool for embeding Perl code in arbitrary text. It can be used to build sites with dynamic content or in any other context where dynamic texts are useful, especially html documents. The build blocks of a mason site are components. Each component can have its own initializazion code, receive arguments (that can be filled with a default value if missing), call another components, etc.
Build a complex and full featured site with mason is as easy as putting some micro components together. This power makes mason a good choice for interface design of web applications.

MasonPlugin allows to call mason components from within topics. This way it's possible to build web applications interface in a collaborative fashion, and more: join existing perl applications to TWiki.

The interface design is a critical point within the application development process. The consequences of a poor interface are disgusting: they can obfuscate a great application and make user's work harder or inefficient.
By definition users are the most qualified people to tell how the application interface should be. If there were an easy way they could take part of the interface design we would get better interfaces in shorter time.
Combining TWiki's simplicity and Mason's flexibility MasonPlugin turns the interface design process as easy and simple as editing topics and thus allows users to play around with the interfaces as much as their imagination permits. smile
Another interesting consequence is that this collaborative work is a great place for new ideas and feature requests, that is, the whole web application development process is potentially enhanced.
Besides enhanced interfaces the possibility of putting some application within TWiki is a great thing: It's possible to aggregate unlimited functionality to TWiki and get powerful integrated environments easily.

Syntax Rules

Components may be called by %MASON{"/path/to/component" app="foo" args="var => 'val', list => [10, 5.2e-100, 'el3'], hash => {key1 => 'val1', key2 => 'val2'}" post_render="yes"}%, where:

  • "/path/to/component" is the component been called. Required.
  • app="foo" specifies which application to use, since it's possible to have more than one application available. Required, but see bellow.
  • args="..." passes arguments to the component. Optional, but see bellow.
  • post_render specifies if the result of this component call must pass by twiki render. If set to yes no autolink, substitution or any kind of formatting is performed. Sometimes it's useful, but most of times it isn't. It depends on the component. Optional. Defaults to no or %MASON_POST_RENDERING%, if defined. It can be set globally, in a web or in a topic. Web settings take precedence over global settings and topic settings take precedence over web settings.

To make it possible to MasonPlugin call the correct component it needs to know which component to call and to which application it belongs. If there is only one application available to the web/topic the app argument can be ommited. It's also possible to set a default application, choosed when no app is given. It's done by setting the MASON_DEFAULT_APP variable. It can be done in a topic, web or globally (in this topic). Web settings take precedence over global settings and topic settings over web settings.

args are a list of "key => value" pairs

  • keys must begin with a letter, followed by any number of letters, digits or underscores (_).
  • values can be:
    • A number (integer or floating point)
    • A string (and if so it needs quotes. Double quotes must be escaped with \)
    • A comma separated list of values, surrounded by [ ].
    • A list of "key => value" pairs, surrounded by { }.

Note that these definitions are recursive, allowing to specify complex data structures if it's needed. Most of times it doesn't and things remains simple. wink

MasonPlugin itself doesn't require the args specification, but some specific components of particular applications may require arguments. Refer to the application's docs for details.

  • %MASON_APPS% shows which applications are able to run, regardless permissions.
  • %MASON_ENABLED_APPS% shows which applications are enabled to run in the current web.
  • %MASON_APPS_TABLE% shows web's permissions to run applications in a table.
  • %MASON_FAILED_APPS% show error messages generated by the application's loader, if any. It's useful for initial setup of new applications.

Examples

  • %MASON_APPS% = %MASON_APPS%
  • %MASON_ENABLED_APPS% = %MASON_ENABLED_APPS%
  • %MASON_APPS_TABLE% = %MASON_APPS_TABLE%
  • %MASON_FAILED_APPS% = %MASON_FAILED_APPS%

Installing Applications

In order to an application work it needs a loader. The application loader is in charge of make any initialization process (parse configuration files, load needed modules, etc), set up some extra functionality that will be available for components and tell MasonPlugin the arguments to invoke the mason interpreter. These arguments must, at least, specify where the component's root of that application is, so the mason interpreter will be able to resolve the component path. The directory where MasonPlugin expects application loaders is configurable via TWiki configure script, or by editing $TWiki::cfg{MasonPlugin}{ApplicationsDir} in lib/TWiki.cfg or lib/LocalLib.cfg.

For security reasons the available applications must also be specified via configure or by setting $TWiki::cfg{MasonPlugin}{Applications}. This field must be filled by a comma separated list of applications' name.

If Foo and Bar are available applications, MasonPlugin expects the loaders Foo.pm and Bar.pm to exist in the ApplicationsDir. Loaders, components and specific instructions are part of applications' port. See "Porting Applications to MasonPlugin" below for details.

Be sure that:

  • ApplicationsDir is readable by the webserver user
  • Component root used by applications is also readable
  • Data dir used by applications is readable and writable
  • The spelling of application name is right in Applications and there exists ApplicationsDir/<AppName>.pm
  • Applications are enabled for the web(s) they will be used

Use %MASON_APPS%, %MASON_FAILED_APPS% and %MASON_APPS_TABLE% for diagnostics.

Security Issues

Mason components may have arbitrary Perl code, that gets executed on the server when corresponding components are called. That's why loaders directory and available applications are configured via configure script and all applications are disabled by default.

Don't use twiki's pubdir as directory to put loaders or components. If you do so, be sure you know exactly what you're doing. If users can upload mason components then arbitrary code will get executed on the server.

Take a look at the loaders code and be sure that users can't upload to application's data_dir nor comp_root.

If the only choice left is to use twiki's pubdir then use pub/_work_areas/MasonPlugin and configure webserver to deny access to this directory.

As applications get integrated to TWiki using this plugin security holes of that applications may be brought to TWiki as well. Install and make available as few applications as possible. It's also a performance tip. See bellow.

Be sure to restrict write access to this topic. If any user can edit it then applications could be enabled globally and get you into trouble.

Warning

  • The authors built and distributes this software in the hope that it will be usefull. Use it at your own risk. The authors shall not in any case be liable for special, incidental, consequential, indirect or other similar damages arising from the use of this software

Performance Tips

MasonPlugin perform its work as late as possible, and try to avoid re-executing tasks. When needed applications loaders get executed and remains in memory as long as TWiki itself. So the next time application is needed it's not necessary to load it again.
But if twiki is running as CGI script then every time a request comes (to view some topic that uses MasonPlugin) then everything is executed again, since CGI scripts don't remain in memory when the request ends. This can decrease TWiki's performance a lot, since applications can perform many tasks at initialization time. It's very recommended to use some persistence mechanism such as SpeedyCGI, FastCGI or even ModPerl.

If you're porting some application to use with MasonPlugin, be in mind that loaders may be executed only once. Parse configuration files, load related modules and initialize some global data structures are good tasks to be performed by a loader.
Tasks that depends on the execution, such as user specific tasks and even database connections can be handled by autohandler mason component, within a <%init> block.

Porting Applications to MasonPlugin

If it's possible to build a Perl application's interface using Mason, then this application can be ported to MasonPlugin. If the application already has a Mason interface then very little work is needed. smile
The main differences between a stand alone Mason interface and a MasonPlugin interface is that TWiki peforms most of the work, thus components with MasonPlugin are more simple. For instance, if a component needs a table then it doesn't need to output all the table code. It can use the much cleaner twiki notation. Variables, such as %TOPIC% are also expanded. In short, components can output twiki notation instead of html code.
But if TWiki's rendering facillities aren't desired components may output html code and user should call them with post_render="yes".
Another important difference is that the $r variable isn't available or doesn't have the desired effect. Sorry. If very needed components can use the CGI object, returned by TWiki::Func::getCgiQuery().
Mason components have access to the entire twiki plugins API, so have fun. wink

MasonPlugin is shipped with a module that allows to access the session as a tied hash. To use this feature use a code like this:

    tie %session, 'TWiki::Plugins::MasonPlugin::SessionTieHash';

And put a use vars qw(%session) in the loader, as in the example bellow. This way components may use $session{key} instead of TWiki::Func:: getSessionValue($key). The TWiki plugins API doesn't yet permit iterate trhough all session's keys, so code like keys %session will not work.
Refer to perltie man page for details about the tie mechanism.

The application loader must implement the interpArgs method, that return a hash that will be passed to mason interpreter. Here an example of a Foo loader:

# filename: Foo.pm
package Foo;
use strict;
use warnings;

sub interpArgs {
   return (default_escape_flags => 'h', 
             comp_root => '/usr/local/share/MasonPlugin/Foo', 
             data_dir => '/var/lib/MasonPlugin/Foo' );
}

# Optionally bring something to HTML::Mason::Commands namespace,
# that is the namespace of components.
{
   package HTML::Mason::Commands;
   use vars qw(%session); # All components will be able to access the %session hash
   use DBI;
   use Date::Parse;
}

1; # Required!!!!

MasonPlugin gets its work done in two or three steps. In the first it discovers all component calls and applications that are needed by the topic. Then it builds a component on the fly that calls every components for an application. One component is built for each application. Theses dynamic components are executed by a Mason Interpreter, initialized with the parameters returned by interpArgs method of the corresponding loader. In the second step all component calls that should pass through the twiki render are replaced with the corresponding result. Then, after twiki rendering, the remaining component calls are replaced.
The dynamic components inherit from /autohandler component. MasonPlugin makes %masonShared available to all components belonging to some application, so they can exchange messages. Note that components order is important. If component B is executed after component A than B can't send messages to A. If your components need some special order, document this issue properly, so the users won't make a mistake.
The %masonShared variable is good for short and fast communication. If components need some kind of persistence, such as login information, then they should use the session. Sessions can also be used to inter-application communication, since %masonShared works with each application independently.
Many different applications and TWiki itself shares the session, so name collisions can take place. A simple way to avoid it is to prefix all keys, like in $session{APP_key} or even $session{APP}{key}.

Finally some guidelines to be in mind:

  • Write short and well specified components
  • Document components behavior and each argument it handles
  • Try do write flexible components, so you give more power and freedom to users to customize their interfaces.
  • Avoid performing unnecessary work

Cool Links

Plugin Settings

  • One line description, is shown in the TextFormattingRules topic:
    • Set SHORTDESCRIPTION = Allows to embed calls to Mason components within topics.

  • Debug plugin: (See output in data/debug.txt)
    • Set DEBUG = 0

  • Security Action: Uncomment the following line

By default applications are disabled for all webs. They must be enabled manually, via:

  • Set ENABLE_APPNAME_IN = comma separated web list
The special keyword ALL enables application in all webs, public or not. Particular webs can be disabled by the web name prefixed with a minus signal. Use ALL with care.

Even if the application's name is Foo, FoO, fOO or whathever it is, it must be written with upcase letters on permissions preferences.

Examples:

  • Set ENABLE_FOO_IN = Main, TWiki enables application Foo in Main and TWiki webs. Application name must be uppercase in permission settings.
  • Set ENABLE_BAR_IN = ALL, -Trash, -TWiki, -Main enables Bar application in all webs, except Trash, TWiki and Main.

Applications permissions must be set only in this topic. Web and/or topic settings, if any, are discarded. See "Security Issues" above.

Plugin Installation Instructions

Note: You do not need to install anything on the browser to use this plugin. The following instructions are for the administrator who installs the plugin on the TWiki server.

  • Download the ZIP file from the Plugin web (see below)
  • Unzip MasonPlugin.zip in your twiki installation directory. Content:
    File: Description:
    data/TWiki/MasonPlugin.txt Plugin topic
    data/TWiki/MasonPlugin.txt,v Plugin topic repository
    lib/TWiki/Plugins/MasonPlugin.pm Plugin Perl module
    lib/TWiki/Plugins/MasonPlugin/SessionTieHash.pm Helper Perl Module
    MasonPlugin_installer.pl Installer script

  • Configure the Plugin:
    • Run MasonPlugin_installer.pl. It will hep you to configure ApplicationsDir and Applications
    • Run the configure script to enable the Plugin
    • Change the Plugin settings as needed

Plugin Info

Plugin Author: TWiki:Main.GilmarSantosJr
Copyright: © 2006, TWiki:Main.GilmarSantosJr
License: GPL (GNU General Public License)
Plugin Version: 27 Jul 2006 (V1.000)
Change History:  
27 Jul 2006: Initial version
TWiki Dependency: $TWiki::Plugins::VERSION 1.1
CPAN Dependencies: HTML::Mason >= 1.33
Safe >= 2.10
Other Dependencies: none
Perl Version: 5.005
Benchmarks: GoodStyle 97%, FormattedSearch 99%, MasonPlugin 94%
Plugin Home: http://TWiki.org/cgi-bin/view/Plugins/MasonPlugin
Feedback: http://TWiki.org/cgi-bin/view/Plugins/MasonPluginDev
Appraisal: http://TWiki.org/cgi-bin/view/Plugins/MasonPluginAppraisal

Related Topics: TWikiPlugins, DeveloperDocumentationCategory, AdminDocumentationCategory, TWikiPreferences

-- GilmarSantosJr - 26 Aug 2006

Topic attachments
I Attachment History Action Size Date Who Comment
Unknown file formatmd5 MasonPlugin.md5 r1 manage 0.2 K 2006-08-26 - 12:54 GilmarSantosJr  
Compressed Zip archivetgz MasonPlugin.tgz r1 manage 18.1 K 2006-08-26 - 12:53 GilmarSantosJr  
Compressed Zip archivezip MasonPlugin.zip r1 manage 26.8 K 2006-08-26 - 12:54 GilmarSantosJr  
Edit | Attach | Watch | Print version | History: r4 < r3 < r2 < r1 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r4 - 2012-12-03 - PeterThoeny
 
  • Learn about TWiki  
  • Download TWiki
This site is powered by the TWiki collaboration platform Powered by Perl Hosted by OICcam.com Ideas, requests, problems regarding TWiki? Send feedback. Ask community in the support forum.
Copyright © 1999-2016 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.