X-Git-Url: http://wagnertech.de/git?a=blobdiff_plain;f=SL%2FLayout%2FBase.pm;h=c64a99ab06d3860e0969845e9a43c144aa59dec0;hb=08e48f66590f580cbe2c8e3df76883d88b4c0fef;hp=2312ecfd2606f6ef3f379862339573470c6b0774;hpb=a74bcd6a6787ff29a7e636d027faa3d58b377219;p=kivitendo-erp.git diff --git a/SL/Layout/Base.pm b/SL/Layout/Base.pm index 2312ecfd2..c64a99ab0 100644 --- a/SL/Layout/Base.pm +++ b/SL/Layout/Base.pm @@ -3,11 +3,12 @@ package SL::Layout::Base; use strict; use parent qw(Rose::Object); +use File::Slurp qw(read_file); use List::MoreUtils qw(uniq); use Time::HiRes qw(); use Rose::Object::MakeMethods::Generic ( - 'scalar --get_set_init' => [ qw(menu auto_reload_resources_param) ], + 'scalar --get_set_init' => [ qw(menu auto_reload_resources_param sub_layouts_by_name) ], 'scalar' => qw(focus), 'array' => [ 'add_stylesheets_inline' => { interface => 'add', hash_key => 'stylesheets_inline' }, @@ -19,6 +20,7 @@ use Rose::Object::MakeMethods::Generic ( use SL::Menu; use SL::Presenter; +use SL::System::Process; my %menu_cache; @@ -29,12 +31,44 @@ sub new { } sub init_menu { - Menu->new('crm/update/menu.ini', 'menus/erp.ini'); + SL::Menu->new('user'); +} + +sub init_sublayouts_by_name { + {} +} + +sub webpages_path { + "templates/webpages"; +} + +sub get { + $_[0]->sub_layouts; + return grep { $_ } ($_[0]->sub_layouts_by_name->{$_[1]}); } sub init_auto_reload_resources_param { - return '' unless $::lx_office_conf{debug}->{auto_reload_resources}; - return sprintf('?rand=%d-%d-%d', Time::HiRes::gettimeofday(), int(rand 1000000000000)); + if ($::lx_office_conf{debug}->{auto_reload_resources}) { + return sprintf('?rand=%d-%d-%d', Time::HiRes::gettimeofday(), int(rand 1000000000000)); + } + + if ($::lx_office_conf{debug}{git_commit_reload_resources}) { + my $git_dir = SL::System::Process::exe_dir() . '/.git'; + + return '' unless -d $git_dir; + + my $content = eval { scalar(read_file($git_dir . '/HEAD')) }; + + return '' unless ($content // '') =~ m{\Aref: ([^\r\n]+)}; + + $content = eval { scalar(read_file($git_dir . '/' . $1)) }; + + return '' unless ($content // '') =~ m{\A([0-9a-fA-F]+)}; + + return '?rand=' . $1; + } + + return ''; } ########################################## @@ -69,11 +103,16 @@ sub javascripts_inline { sub init_sub_layouts { [] } +sub init_sub_layouts_by_name { +{} } + ######################################### -# Interface +# Stylesheets ######################################## +# override in sub layouts +sub static_stylesheets {} + sub add_stylesheets { &use_stylesheet; } @@ -81,7 +120,7 @@ sub add_stylesheets { sub use_stylesheet { my $self = shift; push @{ $self->{stylesheets} ||= [] }, @_ if @_; - @{ $self->{stylesheets} ||= [] }; + (map { $_->use_stylesheet } $self->sub_layouts), $self->static_stylesheets, @{ $self->{stylesheets} ||= [] }; } sub stylesheets { @@ -89,7 +128,7 @@ sub stylesheets { my $css_path = $self->get_stylesheet_for_user; return uniq grep { $_ } map { $self->_find_stylesheet($_, $css_path) } - $self->use_stylesheet, map { $_->stylesheets } $self->sub_layouts; + $self->use_stylesheet; } sub _find_stylesheet { @@ -98,12 +137,13 @@ sub _find_stylesheet { return "$css_path/$stylesheet" if -f "$css_path/$stylesheet"; return "css/$stylesheet" if -f "css/$stylesheet"; return $stylesheet if -f $stylesheet; + return $stylesheet if $stylesheet =~ /^http/; # external } sub get_stylesheet_for_user { my $css_path = 'css'; if (my $user_style = $::myconfig{stylesheet}) { - $user_style =~ s/\.css$//; # nuke trailing .css, this is a remnand of pre 2.7.0 stylesheet handling + $user_style =~ s/\.css$//; # nuke trailing .css, this is a remnant of pre 2.7.0 stylesheet handling if (-d "$css_path/$user_style" && -f "$css_path/$user_style/main.css") { $css_path = "$css_path/$user_style"; @@ -113,11 +153,17 @@ sub get_stylesheet_for_user { } else { $css_path = "$css_path/kivitendo"; } - $::myconfig{css_path} = $css_path; # needed for menunew, FIXME: don't do this here return $css_path; } +######################################### +# Javascripts +######################################## + +# override in sub layouts +sub static_javascripts {} + sub add_javascripts { &use_javascript } @@ -125,14 +171,14 @@ sub add_javascripts { sub use_javascript { my $self = shift; push @{ $self->{javascripts} ||= [] }, @_ if @_; - @{ $self->{javascripts} ||= [] }; + map({ $_->use_javascript } $self->sub_layouts), $self->static_javascripts, @{ $self->{javascripts} ||= [] }; } sub javascripts { my ($self) = @_; return uniq grep { $_ } map { $self->_find_javascript($_) } - map({ $_->javascripts } $self->sub_layouts), $self->use_javascript; + $self->use_javascript; } sub _find_javascript { @@ -140,6 +186,7 @@ sub _find_javascript { return "js/$javascript" if -f "js/$javascript"; return $javascript if -f $javascript; + return $javascript if $javascript =~ /^http/; } @@ -177,7 +224,7 @@ SL::Layout::Base - Base class for layouts =head1 DESCRIPTION -For a description about the external interface of layouts in general see +For a description of the external interface of layouts in general see L. This is a base class for layouts in general. It provides the basic interface @@ -187,7 +234,7 @@ and some capabilities to extend and cascade layouts. =head1 IMPLEMENTING LAYOUT CALLBACKS There are eight callbacks (C, C, C, -C, C, C, C, +C, C, C, C, C) which are documented in L. If you are writing a new simple layout, you can just override some of them like this: @@ -252,26 +299,44 @@ For the C<*_content> callbacks this works if you just remember to dispatch to th $_[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; +Stylesheets and Javascripts can be added to every layout and sub-layout at +runtime with L and +L (C and +C are aliases for backwards compatibility): + + $layout->add_stylesheets("custom.css"); + $layout->add_javascripts("app.js", "widget.js"); + +Or they can be overwritten in sub layouts with the calls +L and +L: + + sub static_stylesheets { + "custom.css" + } + + sub static_javascripts { + qw(app.css widget.js) } +Note how these are relative to the base dirs of the currently selected +stylesheets. Javascripts are resolved relative to the C basedir. + +Setting directly with C and C is eprecated. + + =head1 GORY DETAILS ABOUT JAVASCRIPT AND STYLESHEET OVERLOADING -The original code used to store one stylehsheet in C<< $form->{stylesheet} >> and +The original code used to store one stylesheet in C<< $form->{stylesheet} >> and allowed/expected authors of potential C controllers to change that into their own modified stylesheet. This was at some point cleaned up into a method C 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 +A lot of controllers are still using this method so the layout interface +supports it to change as little controller code as possible, while providing the more intuitive C method. At the same time the following things need to be possible: @@ -297,7 +362,7 @@ A leaf layout should be able to override a callback to return a list. Sanitizing -C needs to retain it's sanitizing behaviour. +C needs to retain its sanitizing behaviour. =item 4. @@ -307,7 +372,7 @@ The standard implementation should be able to collect from sub layouts. =item 5. -Preserving of Inclusion Order +Preserving 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 @@ -320,7 +385,12 @@ 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. +* stylesheet/javascript interface is a horrible mess. + +* It's currently not possible to do compositor layouts without assupmtions +about the position of the content. That's because the content will return +control to the actual controller, so the layouts need to know where to split +pre- and post-content. =head1 AUTHOR