=head1 NAME
 
RapidApp::Manual::Modules - RapidApp Modules
 
=head1 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 C</adm>:

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

=head1 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 
L<RapidApp::Module>. Built-in modules live within the C<RapidApp::Module::> namespace, such as
L<RapidApp::Module::Tree> and L<RapidApp::Module::DbicGrid>.

Note that it is B<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 L<Plugins|RapidApp::Manual::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...


=head1 MODULE RENDERING

By default, Modules expect to be rendered within an ExtJS container structure via Ajax by the
special, RapidApp-specific JavaScript function C<Ext.ux.RapidApp.AutoPanel>. Top-level views
to prepare the HTML markup to accomplish this automatically are provided, such as 
L<RapidApp::View::Viewport>, which is what is used by plugins like
L<TabGui|Catalyst::Plugin::RapidApp::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 C<AutoPanel> function, which should represent a valid ExtJS xtype
panel/component config. This is returned by the C<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 L<TabGui|Catalyst::Plugin::RapidApp::TabGui>
automatically load the target URL in a tab, which will deserialize and render Modules automatically
via C<AutoPanel> in the same manner as views like L<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).

=head2 Direct Rendering URLs

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

There is also C</rapidapp/module/printview/[path]> available. This works exactly like C<direct>
except it renders using L<RapidApp::View::Printview> instead of L<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 C<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 
C<module_root_namespace> is set to 'adm', and the L<TabGui|Catalyst::Plugin::RapidApp::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

=head1 SEE ALSO

=over

=item *

L<RapidApp::Manual>

=item *

L<RapidApp::Module>

=item *

L<RapidApp::Manual::Plugins>

=back
 
=cut
