Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 42f69828

Von Sven Schöling vor etwa 12 Jahren hinzugefügt

Lange überfällige Doku zu Layouts

Unterschiede anzeigen:

SL/Layout/Base.pm
}
1;
__END__
=encoding utf-8
=head1 NAME
SL::Layout::Base - Base class for layouts
=head1 SYNOPSIS
package SL::Layout::MyLayout;
use parent qw(SL::Layout::Base);
=head1 DESCRIPTION
For a description about the external interface of layouts in general see
L<SL::Layout::Dispatcher>.
This is a base class for layouts in general. It provides the basic interface
and some capabilities to extend and cascade layouts.
=head1 IMPLEMENTING LAYOUT CALLBACKS
There are eight callbacks (C<pre_content>, C<post_content>, C<start_content>,
C<end_content>, C<stylesheets>, C<stylesheets_inline>, C<javscripts>,
C<javascripts_inline>) which are documented in L<SL::Layout::Dispatcher>. If
you are writing a new simple layout, you can just override some of them like
this:
package SL::Layout::MyEvilLayout;
sub pre_content {
'<h1>This is MY page now</h1>'
}
sub post_content {
'<p align="right"><small><em>Brought to you by my own layout class</em></small></p>'
}
To preserve the sanitizing effects of C<stylesheets> and C<javascripts> you should instead do the following:
sub stylesheets {
$_[0]->add_stylesheets(qw(mystyle1.css mystyle2.css);
$_[0]->SUPER::stylesheets;
}
If you want to add something to a different layout, you should write a sub
layout and add it to the other layouts.
=head1 SUB LAYOUTS
Layouts can be aggregated, so that common elements can be used in different
layouts. Currently this is used for the L<None|SL::Layout::None> sub layout,
which contains a lot of the stylesheets and javascripts necessary. Another
example is the L<Top|SL::Layout::Top> layout, which is used to generate a
common top bar for all menu types.
To add a sub layout to your layout just overwrite the sub_layout method:
package SL::Layout::MyFinalLayout;
sub init_sub_layout {
[
SL::Layout::None->new,
SL::Layout::MyEvilLayout->new,
]
}
You can also add a sublayout at runtime:
$layout->add_sub_layout(SL::Layout::SideBar->new);
The standard implementation for the callbacks will see to it that the contents
of all sub layouts will get rendered.
=head1 COMBINING SUB LAYOUTS AND OWN BEHAVIOUR
This is still somewhat rough, and improvements are welcome.
For the C<*_content> callbacks this works if you just remember to dispatch to the base method:
sub post_content {
return $_[0]->render_status_bar .
$_[0]->SUPER::post_content
}
For the stylesheet and javascript callbacks things are hard, because of the
backwards compatibility, and the built-in sanity checks. The best way currently
is to just add your content and dispatch to the base method.
sub stylesheets {
$_[0]->add_stylesheets(qw(mystyle1.css mystyle2.css);
$_[0]->SUPER::stylesheets;
}
=head1 GORY DETAILS ABOUT JAVASCRIPT AND STYLESHEET OVERLOADING
The original code used to store one stylehsheet in C<< $form->{stylesheet} >> and
allowed/expected authors of potential C<bin/mozilla/> controllers to change
that into their own modified stylesheet.
This was at some point cleaned up into a method C<use stylesheet> which took a
string of space separated stylesheets and processed them into the response.
A lot of controllers are still using this methods so the layout interface
supports it to change as few controller code as possible, while providing the
more intuitive C<add_stylesheets> method.
At the same time the following things need to be possible:
=over 4
=item 1.
Runtime additions.
$layout->add_stylesheets(...)
Since add_stylesheets adds to C<< $self->{stylesheets} >> there must be a way to read
from it. Currently this is the deprecated C<use_stylesheet>.
=item 2.
Overriding Callbacks
A leaf layout should be able to override a callback to return a list.
=item 3.
Sanitizing
C<stylesheets> needs to retain it's sanitizing behaviour.
=item 4.
Aggregation
The standard implementation should be able to collect from sub layouts.
=item 5.
Preserving of Inclusion Order
Since there is currently no standard way of mixing own content and including
sub layouts, this has to be done manually. Certain things like jquery get added
in L<SL::Layout::None> so that they get rendered first.
=back
The current implementation provides no good candidate for overriding in sub
classes, which should be changed. The other points work pretty well.
=head1 BUGS
None yet, if you don't count the horrible stylesheet/javascript interface.
=head1 AUTHOR
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
=cut
SL/Layout/Dispatcher.pm
}
1;
__END__
=encoding utf-8
=head1 NAME
SL::Layout::Dispatcher - provides layouts by name.
=head1 SYNOPSIS
use SL::Layout::Dispatcher;
$::request->layout(SL::Layout::Dispatcher->new(style => 'login'));
# same as
use SL::Layout::Login;
$::request->layout(SL::Layout::Login->new);
=head1 INTRODUCTION
A layout in kivitendo is anything that should be included into a text/html
response without having each controller do it manually. This includes:
=over 4
=item *
menus
=item *
status bars
=item
div containers for error handling and ajax responses
=item *
javascript and css includes
=item *
html header and body
=back
It does not include:
=over 4
=item *
http headers
=item *
anthing that is not a text/html response
=back
All of these tasks are handled by a layout object, which is stored in the
global L<$::request|SL::Request> object. An appropriate layout object will be
chosen during the login/session_restore process.
=head1 INTERFACE
Every layout must be instantiated from L<SL::Layout::Base> and must implement
the following eight callbacks:
=over 4
=item C<pre_content>
Content that must, for whatever reason, appear before the main content.
=item C<start_content>
An introcutory clause for the main content. Usually something like C<< <div
class='content'> >>.
=item C<end_content>
The corresponding end of L</start_content> like C<< </div> >>
=item C<post_content>
Any extra content that should appear after the main content in the response
source. Note that it is preferred to put extra content after the main content,
so that it gets rendered faster.
=item C<stylesheets>
A list of stylesheets that should be included as a full relative web path. Will
be rendered into the html header.
=item C<stylesheets_inline>
A list of stylesheet snippets that need to be included in the response. Will be
added to the html header.
=item C<javascripts>
A list of javascripts that should be included as a full relative web path.
Note:
There is no guarantee where these will end up in the content. Currently they
will be rendered into the header, but are likely to be moved into the footer in
the future.
=item C<javascripts_inline>
A list of javascript snippets that need to be included in the response.
Note:
These will end up in the footer, so make sure they don't contain
initializations to static javascript includes that may be included earlier.
=back
=head1 RUNTIME INTERFACE
Each layout object can add stylesheets and javascripts at runtime, as long as
its before the actual rendering has begun. This can be used to add special
javascripts only your controller needs.
=over 4
=item C<add_stylesheets>
Adds the list of arguments to the list of used stylesheets.
These will first be searched in the theme folder for the current user, and only
after that be searched from the common C<css/> folder.
Duplicated files will be only included once.
Non-existing files will be pruned from the list.
=item C<use_stylesheet>
Backwards compatible alias for C<add_stylesheets>. Deprecated.
=item C<add_javascripts>
Adds the list of arguments to the list of used javascripts.
Duplicated files will be only included once.
Non-existing files will be pruned from the list.
=item C<use_javascript>
Backwards compatible alias for C<add_javascripts>. Deprecated.
=item C<add_javascripts_inline>
Add a snippet of javascript.
=item C<add_stylesheets_inline>
Add a snippet of css.
=item C<focus>
If set with a selector, the layout will generate javascript to set the page
focus to that selector on document.ready.
=back
=head1 BUGS
None yet :)
=head1 TODO
non existing css or js includes should generate a log entry.
=head1 AUTHOR
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
=cut
SL/Request.pm
Returns the requested content type (either C<html>, C<js> or C<json>).
=item C<layout>
Set and retrieve the layout object for the current request. Must be an instance
of L<SL::Layout::Base>. Defaults to an isntance of L<SL::Layout::None>.
For more information about layouts, see L<SL::Layout::Dispatcher>.
=back
=head1 SPECIAL FUNCTIONS

Auch abrufbar als: Unified diff