[Rt-commit] rt branch, menuing, created. rt-3.8.8-869-g5e85c7e

Jesse Vincent jesse at bestpractical.com
Sat Sep 25 20:14:04 EDT 2010


The branch, menuing has been created
        at  5e85c7ecdc403b192e430f91a060d0d729eb97eb (commit)

- Log -----------------------------------------------------------------
commit 7dadb0afd8540c2528b85c39bca429081a2a524d
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Sat Sep 25 09:20:01 2010 -0400

    replace RT's menuing library (unusued) with one from jifty

diff --git a/lib/RT/Interface/Web/Menu.pm b/lib/RT/Interface/Web/Menu.pm
index 899f209..c0eb7c6 100644
--- a/lib/RT/Interface/Web/Menu.pm
+++ b/lib/RT/Interface/Web/Menu.pm
@@ -47,24 +47,269 @@
 # END BPS TAGGED BLOCK }}}
 
 package RT::Interface::Web::Menu;
-use warnings;
+
 use strict;
+use warnings;
+
+
+use base qw/Class::Accessor::Fast/;
+use URI;
+use Scalar::Util qw(weaken);
+
+__PACKAGE__->mk_accessors(qw(
+    label sort_order link target escape_label class render_children_inline
+    raw_html
+));
+
+=head1 NAME
+
+RT::Interface::Web::Menu - Handle the API for menu navigation
+
+=head1 METHODS
+
+=head2 new PARAMHASH
+
+Creates a new L<RT::Interface::Web::Menu> object.  Possible keys in the
+I<PARAMHASH> are L</label>, L</parent>, L</sort_order>, L</url>, and
+L</active>.  See the subroutines with the respective name below for
+each option's use.
+
+=cut
 
 sub new {
-    my $class = shift;
-    my $self = bless {}, $class;
-    $self->{'root_node'} = RT::Interface::Web::Menu::Item->new();
+    my $package = shift;
+    my $args = ref($_[0]) eq 'HASH' ? shift @_ : {@_};
+
+    my $parent = delete $args->{'parent'};
+    $args->{sort_order} ||= 0;
+
+    # Class::Accessor only wants a hashref;
+    my $self = $package->SUPER::new( $args );
+
+    # make sure our reference is weak
+    $self->parent($parent) if defined $parent;
+
     return $self;
 }
 
 
-sub as_hash_of_hashes {
+=head2 label [STRING]
+
+Sets or returns the string that the menu item will be displayed as.
+
+=cut
+
+=head2 parent [MENU]
+
+Gets or sets the parent L<RT::Interface::Web::Menu> of this item; this defaults
+to null. This ensures that the reference is weakened.
+
+=head2 raw_html [STRING]
+
+Sets the content of this menu item to a raw blob of HTML. When 
+asked or output, rather than constructing a link, Jifty will return 
+this raw content. No escaping is done.
 
+=cut
+
+sub parent {
+    my $self = shift;
+    if (@_) {
+        $self->{parent} = shift;
+        weaken $self->{parent};
+    }
+
+    return $self->{parent};
 }
 
-sub root {
+
+=head2 sort_order [NUMBER]
+
+Gets or sets the sort order of the item, as it will be displayed under
+the parent.  This defaults to adding onto the end.
+
+=head2 link
+
+Gets or set a L<Jifty::Web::Form::Link> object that represents this
+menu item. If you're looking to do complex ajaxy things with menus,
+this is likely the option you want.
+
+=head2 target [STRING]
+
+Get or set the frame or pseudo-target for this link. something like L<_blank>
+
+=cut
+
+=head2 class [STRING]
+
+Gets or sets the CSS class the link should have in addition to the default
+classes.  This is only used if L</link> isn't specified.
+
+=head2 render_children_inline [BOOLEAN]
+
+Gets or sets whether children are rendered inline as a menu "group" instead
+of a true submenu.  Only used when rendering with YUI for now.
+Defaults to false.
+
+Note that YUI doesn't support rendering nested menu groups, so having direct
+parent/children render_children_inline is likely not going to do what you
+want or expect.
+
+=head2 url
+
+Gets or sets the URL that the menu's link goes to.  If the link
+provided is not absolute (does not start with a "/"), then is is
+treated as relative to it's parent's url, and made absolute.
+
+=cut
+
+sub url {
+    my $self = shift;
+    if (@_) {
+        $self->{url} = shift;
+        $self->{url} = URI->new_abs($self->{url}, $self->parent->url . "/")->as_string
+            if defined $self->{url} and $self->parent and $self->parent->url;
+        $self->{url} =~ s!///!/! if $self->{url};
+    }
+    return $self->{url};
+}
+
+=head2 active [BOOLEAN]
+
+Gets or sets if the menu item is marked as active.  Setting this
+cascades to all of the parents of the menu item.
+
+=cut
+
+sub active {
+    my $self = shift;
+    if (@_) {
+        $self->{active} = shift;
+        $self->parent->active($self->{active}) if defined $self->parent;
+    }
+    return $self->{active};
+}
+
+=head2 child KEY [, PARAMHASH]
+
+If only a I<KEY> is provided, returns the child with that I<KEY>.
+
+Otherwise, creates or overwrites the child with that key, passing the
+I<PARAMHASH> to L<RT::Interface::Web::Menu/new>.  Additionally, the paramhash's
+L</label> defaults to the I<KEY>, and the L</sort_order> defaults to the
+pre-existing child's sort order (if a C<KEY> is being over-written) or
+the end of the list, if it is a new C<KEY>.
+
+If the paramhash contains a key called C<menu>, that will be used instead
+of creating a new RT::Interface::Web::Menu.
+
+
+=cut
+
+sub child {
+    my $self  = shift;
+    my $key   = shift;
+    my $proto = ref $self || $self;
+
+    if ( my %args = @_ ) {
+
+        # Clear children ordering cache
+        delete $self->{children_list};
+
+        my $child;
+        if ( $child = $args{menu} ) {
+            $child->parent($self);
+        } else {
+            $child = $proto->new(
+                {   parent     => $self,
+                    label        => $key,
+                    escape_label => 1,
+                    %args
+                }
+            );
+        }
+        $self->{children}{$key} = $child;
+
+        $child->sort_order( $args{sort_order} || (scalar values %{ $self->{children} })  )
+            unless ($child->sort_order());
+
+        # URL is relative to parents, and cached, so set it up now
+        $child->url( $child->{url} );
+
+        # Figure out the URL
+        my $url
+            = (     defined $child->link
+                and ref $child->link
+                and $child->link->can('url') )
+            ? $child->link->url
+            : $child->url;
+
+        # Activate it
+        if ( defined $url and length $url and Jifty->web->request ) {
+
+            # XXX TODO cleanup for mod_perl
+            my $base_path = Jifty->web->request->path;
+            chomp($base_path);
+
+            $base_path =~ s/index\.html$//;
+            $base_path =~ s/\/+$//;
+            $url       =~ s/\/+$//;
+
+            if ( $url eq $base_path ) {
+                $self->{children}{$key}->active(1);
+            }
+        }
+    }
+
+    return $self->{children}{$key};
+}
+
+=head2 active_child
+
+Returns the first active child node, or C<undef> is there is none.
+
+=cut
+
+sub active_child {
+    my $self = shift;
+    foreach my $kid ($self->children) {
+        return $kid if $kid->active;
+    }
+    return undef;
+}
+
+
+=head2 delete KEY
+
+Removes the child with the provided I<KEY>.
+
+=cut
+
+sub delete {
+    my $self = shift;
+    my $key = shift;
+    delete $self->{children_list};
+    delete $self->{children}{$key};
+}
+
+=head2 children
+
+Returns the children of this menu item in sorted order; as an array in
+array context, or as an array reference in scalar context.
+
+=cut
+
+sub children {
     my $self = shift;
-    return $self->{'root_node'};
+    my @kids;
+    if ($self->{children_list}) {
+        @kids = @{$self->{children_list}};
+    } else {
+        @kids = values %{$self->{children} || {}};
+        @kids = sort {$a->{sort_order} <=> $b->{sort_order}} @kids;
+        $self->{children_list} = \@kids;
+    }
+    return wantarray ? @kids : \@kids;
 }
 
 1;
diff --git a/lib/RT/Interface/Web/Menu/Item.pm b/lib/RT/Interface/Web/Menu/Item.pm
deleted file mode 100644
index e5efa29..0000000
--- a/lib/RT/Interface/Web/Menu/Item.pm
+++ /dev/null
@@ -1,87 +0,0 @@
-# BEGIN BPS TAGGED BLOCK {{{
-#
-# COPYRIGHT:
-#
-# This software is Copyright (c) 1996-2010 Best Practical Solutions, LLC
-#                                          <jesse at bestpractical.com>
-#
-# (Except where explicitly superseded by other copyright notices)
-#
-#
-# LICENSE:
-#
-# This work is made available to you under the terms of Version 2 of
-# the GNU General Public License. A copy of that license should have
-# been provided with this software, but in any event can be snarfed
-# from www.gnu.org.
-#
-# This work is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301 or visit their web page on the internet at
-# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-#
-#
-# CONTRIBUTION SUBMISSION POLICY:
-#
-# (The following paragraph is not intended to limit the rights granted
-# to you to modify and distribute this software under the terms of
-# the GNU General Public License and is only of importance to you if
-# you choose to contribute your changes and enhancements to the
-# community by submitting them to Best Practical Solutions, LLC.)
-#
-# By intentionally submitting any modifications, corrections or
-# derivatives to this work, or any other work intended for use with
-# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-# you are the copyright holder for those contributions and you grant
-# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-# royalty-free, perpetual, license to use, copy, create derivative
-# works based on those contributions, and sublicense and distribute
-# those contributions and any derivatives thereof.
-#
-# END BPS TAGGED BLOCK }}}
-
-package RT::Interface::Web::Menu::Item;
-
-
-sub new {
-    my $class = shift;
-    my $self = bless {},$class;
-    $self->{'_attributes'} = {};
-    return($self);
-}
-
-sub label { my $self = shift; $self->_accessor( label => @_) } ;
-sub absolute_url { my $self = shift; $self->_accessor( absolute_url => @_) } ;
-sub rt_path { my $self = shift; $self->_accessor( rt_path => @_) } ;
-sub hilight { my $self = shift; $self->_accessor( hilight => @_);
-              $self->parent->hilight(1);
-            } ;
-sub sort_order { my $self = shift; $self->_accessor( sort_order => @_) } ;
-
-sub add_child {
-}
-
-sub delete {
-}
-
-sub children {
-
-}
-
-sub _accessor {
-    my $self = shift;
-    my $key = shift;
-    if (@_){ 
-        $self->{'attributes'}->{$key} = shift;
-
-    }
-    return $self->{'_attributes'}->{$key};
-}
-
-1;

commit 5e85c7ecdc403b192e430f91a060d0d729eb97eb
Author: Jesse Vincent <jesse at bestpractical.com>
Date:   Sat Sep 25 20:15:54 2010 -0400

    first pass of making the toplevel menu use a new menu object

diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 604080c..acb8ebb 100755
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -65,6 +65,7 @@ package RT::Interface::Web;
 
 use RT::SavedSearches;
 use URI qw();
+use RT::Interface::Web::Menu;
 use RT::Interface::Web::Session;
 use Digest::MD5 ();
 use Encode qw();
@@ -282,6 +283,12 @@ sub MaybeShowNoAuthPage {
     $m->abort;
 }
 
+sub InitializeMenu {
+    $HTML::Mason::Commands::m->notes('menu', RT::Interface::Web::Menu->new());
+
+}
+
+
 =head2 ShowRequestedPage  \%ARGS
 
 This function, called exclusively by RT's autohandler, dispatches
@@ -295,6 +302,8 @@ sub ShowRequestedPage {
 
     my $m = $HTML::Mason::Commands::m;
 
+    InitializeMenu();
+
     SendSessionCookie();
 
     # If the user isn't privileged, they can only see SelfService
@@ -800,6 +809,9 @@ package HTML::Mason::Commands;
 
 use vars qw/$r $m %session/;
 
+sub Menu {
+    return $HTML::Mason::Commands::m->notes('menu');
+}
 
 =head2 loc ARRAY
 
diff --git a/lib/RT/Interface/Web/Menu.pm b/lib/RT/Interface/Web/Menu.pm
index c0eb7c6..ce4248e 100644
--- a/lib/RT/Interface/Web/Menu.pm
+++ b/lib/RT/Interface/Web/Menu.pm
@@ -57,7 +57,7 @@ use URI;
 use Scalar::Util qw(weaken);
 
 __PACKAGE__->mk_accessors(qw(
-    label sort_order link target escape_label class render_children_inline
+    title sort_order link target escape_title class render_children_inline
     raw_html
 ));
 
@@ -70,7 +70,7 @@ RT::Interface::Web::Menu - Handle the API for menu navigation
 =head2 new PARAMHASH
 
 Creates a new L<RT::Interface::Web::Menu> object.  Possible keys in the
-I<PARAMHASH> are L</label>, L</parent>, L</sort_order>, L</url>, and
+I<PARAMHASH> are L</title>, L</parent>, L</sort_order>, L</path>, and
 L</active>.  See the subroutines with the respective name below for
 each option's use.
 
@@ -93,7 +93,7 @@ sub new {
 }
 
 
-=head2 label [STRING]
+=head2 title [STRING]
 
 Sets or returns the string that the menu item will be displayed as.
 
@@ -155,23 +155,23 @@ Note that YUI doesn't support rendering nested menu groups, so having direct
 parent/children render_children_inline is likely not going to do what you
 want or expect.
 
-=head2 url
+=head2 path
 
 Gets or sets the URL that the menu's link goes to.  If the link
 provided is not absolute (does not start with a "/"), then is is
-treated as relative to it's parent's url, and made absolute.
+treated as relative to it's parent's path, and made absolute.
 
 =cut
 
-sub url {
+sub path {
     my $self = shift;
     if (@_) {
-        $self->{url} = shift;
-        $self->{url} = URI->new_abs($self->{url}, $self->parent->url . "/")->as_string
-            if defined $self->{url} and $self->parent and $self->parent->url;
-        $self->{url} =~ s!///!/! if $self->{url};
+        $self->{path} = shift;
+        $self->{path} = URI->new_abs($self->{path}, $self->parent->path . "/")->as_string
+            if defined $self->{path} and $self->parent and $self->parent->path;
+        $self->{path} =~ s!///!/! if $self->{path};
     }
-    return $self->{url};
+    return $self->{path};
 }
 
 =head2 active [BOOLEAN]
@@ -196,7 +196,7 @@ If only a I<KEY> is provided, returns the child with that I<KEY>.
 
 Otherwise, creates or overwrites the child with that key, passing the
 I<PARAMHASH> to L<RT::Interface::Web::Menu/new>.  Additionally, the paramhash's
-L</label> defaults to the I<KEY>, and the L</sort_order> defaults to the
+L</title> defaults to the I<KEY>, and the L</sort_order> defaults to the
 pre-existing child's sort order (if a C<KEY> is being over-written) or
 the end of the list, if it is a new C<KEY>.
 
@@ -222,8 +222,8 @@ sub child {
         } else {
             $child = $proto->new(
                 {   parent     => $self,
-                    label        => $key,
-                    escape_label => 1,
+                    title        => $key,
+                    escape_title => 1,
                     %args
                 }
             );
@@ -234,28 +234,28 @@ sub child {
             unless ($child->sort_order());
 
         # URL is relative to parents, and cached, so set it up now
-        $child->url( $child->{url} );
+        $child->path( $child->{path} );
 
         # Figure out the URL
-        my $url
+        my $path
             = (     defined $child->link
                 and ref $child->link
-                and $child->link->can('url') )
-            ? $child->link->url
-            : $child->url;
+                and $child->link->can('path') )
+            ? $child->link->path
+            : $child->path;
 
         # Activate it
-        if ( defined $url and length $url and Jifty->web->request ) {
+        if ( defined $path and length $path ) {
 
             # XXX TODO cleanup for mod_perl
-            my $base_path = Jifty->web->request->path;
+            my $base_path = '';#Jifty->web->request->path;
             chomp($base_path);
 
             $base_path =~ s/index\.html$//;
             $base_path =~ s/\/+$//;
-            $url       =~ s/\/+$//;
+            $path       =~ s/\/+$//;
 
-            if ( $url eq $base_path ) {
+            if ( $path eq $base_path ) {
                 $self->{children}{$key}->active(1);
             }
         }
diff --git a/share/html/Elements/Menu b/share/html/Elements/Menu
index 9c5f78d..7107599 100755
--- a/share/html/Elements/Menu
+++ b/share/html/Elements/Menu
@@ -45,6 +45,15 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
+<div id="new-menu">
+<pre>
+<ul>
+% for my $child (Menu->children) {
+<li><a href="<%RT->Config->Get('WebPath')%>/<%$child->path%>"><%$child->title%></a></li>
+% }
+</ul>
+</pre>
+</div>
 <ul<% !$level ? ' id="system-menu"' : ''|n %><% $menu_class ? qq[ class="$menu_class"] : ''|n %>>
 <div<% $menu_class ? qq[ class="$menu_class"] : ''|n %>><div class="wrapper">
 <%perl>
diff --git a/share/html/Elements/Tabs b/share/html/Elements/Tabs
index 833ab9c..19955d8 100755
--- a/share/html/Elements/Tabs
+++ b/share/html/Elements/Tabs
@@ -65,44 +65,29 @@ my $basetopactions = {
 	B => { html => $m->scomp('/Elements/SimpleSearch') 
 		}
 	};
-my $basetabs = {     A => { title => loc('Homepage'),
-                           path => 'index.html',
-                         },
-                    Ab => { title => loc('Simple Search'),
-                        path => 'Search/Simple.html'
-                         },
-                    B => { title => loc('Tickets'),
-                        path => 'Search/Build.html'
-                      },
-                    C => { title => loc('Tools'),
-                           path => 'Tools/index.html'
-                         },
-                 };
 
-if ($session{'CurrentUser'}->HasRight( Right => 'ShowConfigTab', 
-				       Object => $RT::System )) {
-    $basetabs->{E} = { title => loc('Configuration'),
-                       path => 'Admin/',
-		     };
-}
+Menu->child( A => title => loc('Homepage'), path => 'index.html' );
+Menu->child( Ab   => title => loc('Simple Search'), path => 'Search/Simple.html' );
+Menu->child( B => title => loc('Tickets'), path => 'Search/Build.html' );
+Menu->child( C => title => loc('Tools'),   path => 'Tools/index.html' );
 
-if ($session{'CurrentUser'}->HasRight( Right => 'ModifySelf', 
-				       Object => $RT::System )) {
-    $basetabs->{K} = { title => loc('Preferences'),
-                       path => 'Prefs/Other.html'
-		     };
+if ( $session{'CurrentUser'}->HasRight( Right  => 'ShowConfigTab', Object => $RT::System )) {
+    Menu->child( E => title => loc('Configuration'), path => 'Admin/' );
 }
 
-if ($session{'CurrentUser'}->HasRight( Right => 'ShowApprovalsTab',
-                        Object => $RT::System )) {
-    $basetabs->{P} = { title => loc('Approval'),
-                        path => 'Approvals/'
-            };
+if ( $session{'CurrentUser'}->HasRight( Right  => 'ModifySelf', Object => $RT::System )) {
+    Menu->child( K    => title => loc('Preferences'), path => 'Prefs/Other.html' );
 }
 
-if (!defined $toptabs) {
-   $toptabs = $basetabs;
+if (
+     $session{'CurrentUser'}->HasRight( Right  => 'ShowApprovalsTab',
+                                        Object => $RT::System )
+   )
+{
+    Menu->child( P    => title => loc('Approval'),
+                 path => 'Approvals/' );
 }
+
 if (!defined $topactions) {
    $topactions = $basetopactions;
 }

-----------------------------------------------------------------------


More information about the Rt-commit mailing list