The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

RapidApp::Manual::Modules - RapidApp Modules

DESCRIPTION

RapidApp "Modules" are special object classes, specific to RapidApp, that encapsulate a fully working interface, usually with an embedded ExtJS panel/component front-side view, which is designed to render via Ajax within other rendered Modules (such as within a Viewport, Tab panel, window, etc).

Modules are a special kind of "thick controller" which include controller actions to handle any Ajax callbacks which the given interface view may depend on, such CRUD calls associated with a DataStore, which are tied to DBIC models, models for tree drag/drop persistence, and so on.

Modules live in a hierarchy starting with the "Root Module" which is mounted as a normal Catalyst controller within the application. There is always one - and only one - Root Module which is mounted at the root namespace for the application ('/') by default, but can be changed via app config option to any location. For instance, to have the module hierarchy start at /adm:

 # in the main catalyst app class...
 
__PACKAGE__->config(
 # ...
 'RapidApp' => {
   module_root_namespace => 'adm',
   
   # ...
 }
 
);

AVAILABLE MODULES

There are a very large number of built-in modules included in the RapidApp distribution to achieve all sorts of turn-key interfaces. The bulk of them focus on grids and trees, including a number of composable roles which accomplish broad functions like attaching CRUD DataStores to DBIC models (internally these are the "DbicLnk" interfaces).

Modules have their own DSL which is quite powerful. A Module is defined as any class which extends RapidApp::Module. Built-in modules live within the RapidApp::Module:: namespace, such as RapidApp::Module::Tree and RapidApp::Module::DbicGrid.

Note that it is NOT REQUIRED to know the Module DSL, or even interact directly with Modules at all in order to develop using RapidApp. This is because of the declarative configuration layers which are provided by the Plugins. The APIs of the plugins layers will be maintained for backward compatibility from version to version, while the Module API may still change somewhat as cleanup work progresses...

MODULE RENDERING

By default, Modules expect to be rendered within an ExtJS container structure via Ajax by the special, RapidApp-specific JavaScript function Ext.ux.RapidApp.AutoPanel. Top-level views to prepare the HTML markup to accomplish this automatically are provided, such as RapidApp::View::Viewport, which is what is used by plugins like TabGui to render the RESTful navigation interface.

Modules return a HashRef structure when their URL controller path is accessed from the JavaScript client by the AutoPanel function, which should represent a valid ExtJS xtype panel/component config. This is returned by the content() method of the Module class, and is automatically serialized as JSON and returned to the client by the Module dispatch system. Thus, it is possible to easily override the returned config in any Module class with a simple method modifier:

around content => sub {
 my ($orig, $self, @args) = @_;
 
 return {
   %{ $self->$orig(@args) },
   title => 'Custom title',
   xtype => 'panel',
   width => 420,
   # ...
 
 }
};

The hashnav URL navigation system provided by plugins like TabGui automatically load the target URL in a tab, which will deserialize and render Modules automatically via AutoPanel in the same manner as views like RapidApp::View::Viewport do.

Modules also automatically detect if they are being accessed via Ajax or direct browser call. When accessed directly, they attempt to redirect to the hashnav path to render in a tab automatically, assuming a hashnav URL navigation scheme is active (and, other custom behaviors for direct browser calls can be implemented as well).

Direct Rendering URLs

There are also special controller dispatch paths provided to directly render any module on-the-fly via RapidApp::View::Viewport by prefixing the module path with /rapidapp/module/direct/[path] or /rapidapp/module/navable/[path]. The navable path will wrap the rendered module within a "navable" TabPanel container, which will allow hashnav URL links to work. Otherwise, when rendered via direct, any hashnav links will be stripped (unless of course the target module is already a navable component).

There is also /rapidapp/module/printview/[path] available. This works exactly like direct except it renders using RapidApp::View::Printview instead of RapidApp::View::Viewport. This view attempts to render modules in a manner which is optimized for printing, which primarily has to do with scrolling (i.e. browser scroll to not chop off unscrolled content). This mode only works for modules which have been specifically written to support it, such as AppDV. Grids currently do not support this mode because their height is always based on a container.

The direct module dispatch URLs are useful to render a specific module outside the context of RapidApp-provided interfaces, such as directly within HTML of public/custom content, via iframe:

<iframe 
   class="ux-mif" 
   frameborder="0" 
   style="overflow: auto; width: 100%; height: 450px;" 
   src="/rapidapp/module/navable/some/module/path"
 ></iframe>

To summarize, all the following URLs can be used to access the same module (assuming the module_root_namespace is set to 'adm', and the TabGui plugin is active):

/adm/#!/adm/some/mod/path                     # Renders normally in a TabGui tab via Ajax
/adm/some/mod/path                            # Redirects to /adm/#!/adm/some/mod/path (like above)
/rapidapp/module/direct/adm/some/mod/path     # full-screen in dedicated Viewport
/rapidapp/module/navable/adm/some/mod/path    # full-screen in dedicated TabGui-like interface
/rapidapp/module/printview/adm/some/mod/path  # full-screen in a print-optimized Viewport

SEE ALSO