[MKDoc-commit] Patch from Sam: Here's a patch adding audience matching to the headlines

chris at mkdoc.demon.co.uk chris at mkdoc.demon.co.uk
Mon Mar 21 09:55:57 GMT 2005


Log Message:
-----------
Patch from Sam:
Here's a patch adding audience matching to the headlines component.

Tags:
----
mkdoc-1-6

Modified Files:
--------------
    mkd/flo:
        Component.pm
    mkd/flo/editor:
        Headlines.pm
    mkd/templates/component/headlines/user:
        en.html
    mkd/templates/editor/headlines:
        en.html

-------------- next part --------------
Index: Component.pm
===================================================================
RCS file: /var/spool/cvs/mkd/flo/Component.pm,v
retrieving revision 1.3.2.35
retrieving revision 1.3.2.36
diff -Lflo/Component.pm -Lflo/Component.pm -u -r1.3.2.35 -r1.3.2.36
--- flo/Component.pm
+++ flo/Component.pm
@@ -226,6 +226,27 @@
     return wantarray ? %hash : \%hash;
 }
 
+# variant of cgi_args which allows for multiple values in a single
+# param (i.e. from a multi-select).  This can probably replace
+# cgi_args but without an automated test suite it's impossible to be
+# sure something won't break.
+sub cgi_args_multi {
+    my $self   = shift;
+    my $cgi    = $self->{cgi} || return;
+    my $prefix = $self->{param_name} . '_';
+
+    my %hash;
+    foreach my $name ($cgi->param) {
+        my $key = $name;
+        next unless $key =~ s/^$prefix//;        
+        my @values = $cgi->param($name);
+        $hash{$key} = @values == 0 ? undef : 
+                      @values == 1 ? $values[0] : 
+                     \@values;
+    }
+
+    return wantarray ? %hash : \%hash;
+}
 
 sub link
 {
Index: Headlines.pm
===================================================================
RCS file: /var/spool/cvs/mkd/flo/editor/Headlines.pm,v
retrieving revision 1.4.2.31
retrieving revision 1.4.2.32
diff -Lflo/editor/Headlines.pm -Lflo/editor/Headlines.pm -u -r1.4.2.31 -r1.4.2.32
--- flo/editor/Headlines.pm
+++ flo/editor/Headlines.pm
@@ -23,6 +23,7 @@
 # -------------------------------------------------------------------------------------
 package flo::editor::Headlines;
 use flo::Record::Editor;
+use flo::Record::Audience;
 use Text::Unidecode;
 use MKDoc::Config;
 use flo::Editor;
@@ -48,12 +49,44 @@
 sub _initialize
 {
     my $self = shift;
-    my $args = $self->cgi_args();
+    my $args = $self->cgi_args_multi();
+
     $self->{title}         = $args->{title}           || '';
     $self->{from_path}     = $args->{'from_path'}     || '';
     $self->{max_headlines} = $args->{'max_headlines'} || '';
     $self->{leaf_only}     = $args->{'leaf_only'}     || '';
     $self->{mode}          = $args->{'mode'}          || 'newest';
+    $self->{audience_on}   = $args->{audience_on}     || 0;
+
+    # set audiences, wrapping a single value in an array ref
+    $self->{audiences} = [];
+    $self->{audiences} = 
+      ref $args->{audiences} ? $args->{audiences} : [ $args->{audiences} ]
+        if $args->{audiences};
+}
+
+# returns an array of audience objects (flo::Record::Audience)
+sub audiences { [ flo::Record::Audience->load( All => 1 ) ] }
+
+# returns true if audience matching is on
+sub audience_on { 
+    my $self = shift;
+    return 1 if $self->{audience_on};
+    return undef;
+}
+
+# returns true if audience matching is off
+sub audience_off { 
+    my $self = shift;
+    return 1 unless $self->{audience_on};
+    return undef;
+}
+
+# returns true if a particular audience is selected
+sub audience_selected { 
+    my ($self, $audience) = @_;
+    return 1 if grep { $_ == $audience->id } @{$self->{audiences}};
+    return undef;
 }
 
 # getter for mode
@@ -96,7 +129,19 @@
     return $self->validate_title() &
            $self->validate_from_path() &
 	   $self->validate_max_headlines() &
-           $self->validate_mode;
+           $self->validate_mode &
+           $self->validate_audiences;
+}
+
+# check audiences values
+sub validate_audiences {
+    my $self = shift;
+
+    if ($self->{audience_on} and not @{$self->{audiences}}) {
+	new MKDoc::Ouch 'component/headlines/audiences_missing';
+	return 0;
+    }
+    return 1;
 }
 
 # check mode value
@@ -359,6 +404,18 @@
     if ($self->leaf_only()) {
         @res = map { my @children = $_->{document}->children_showable(); @children ? () : $_ } @res;
     }
+
+    # limit to particular set of audiences if audience matching is on
+    if ($self->{audience_on} and $self->{audiences}) {
+        my %ok = map { ($_, 1) } @{$self->{audiences}};
+        my @passed;
+        foreach my $row (@res) {
+            my $doc = $row->{document};
+            push @passed, $row
+              if grep { $ok{$_->id} } $doc->audiences;
+        }
+        @res = @passed;
+    }
  
     # limit to max number of headlines
     @res = splice @res, 0, $self->max_default_headlines();
@@ -394,6 +451,18 @@
     {
        @res = map { my @children = $_->children_showable(); @children ? () : $_ } @res;
     }
+
+    # limit to particular set of audiences if audience matching is on
+    if ($self->{audience_on} and $self->{audiences}) {
+        my %ok = map { ($_, 1) } @{$self->{audiences}};
+        my @passed;
+        foreach my $doc (@res) {
+            push @passed, $doc 
+              if grep { $ok{$_->id} } $doc->audiences;
+        }
+        @res = @passed;
+    }
+        
  
     # limit to max number of headlines
     @res = splice @res, 0, $self->max_default_headlines();
@@ -427,6 +496,9 @@
     
     my $mode = $self->{mode};
 
+    # no personalized headlines if audience matching is enabled
+    return [] if $self->{audience_on};
+
     # concoct SQL needed for upcoming or newest mode
     my ($extra_from, $extra_where, $extra_select, $order_by, $group_by);
     if ($mode eq 'upcoming') {
Index: en.html
===================================================================
RCS file: /var/spool/cvs/mkd/templates/component/headlines/user/Attic/en.html,v
retrieving revision 1.1.2.1
retrieving revision 1.1.2.2
diff -Ltemplates/component/headlines/user/en.html -Ltemplates/component/headlines/user/en.html -u -r1.1.2.1 -r1.1.2.2
--- templates/component/headlines/user/en.html
+++ templates/component/headlines/user/en.html
@@ -27,6 +27,7 @@
     lang="en"
     xml:lang="en"
     dir="ltr"
+    petal:condition="false: self/audience_on"
   >
     This list of documents has not been personalized because you didn't set
     <a 
Index: en.html
===================================================================
RCS file: /var/spool/cvs/mkd/templates/editor/headlines/Attic/en.html,v
retrieving revision 1.1.2.13
retrieving revision 1.1.2.14
diff -Ltemplates/editor/headlines/en.html -Ltemplates/editor/headlines/en.html -u -r1.1.2.13 -r1.1.2.14
--- templates/editor/headlines/en.html
+++ templates/editor/headlines/en.html
@@ -16,6 +16,10 @@
                 name_from_path     string:${self/block_name}_from_path;
                 name_leaf_only     string:${self/block_name}_leaf_only;
                 name_mode          string:${self/block_name}_mode;
+                name_audience_on   string:${self/block_name}_audience_on;
+                name_audiences     string:${self/block_name}_audiences;
+                name_max_headlines string:${self/block_name}_max_headlines;
+                name_max_headlines string:${self/block_name}_max_headlines;
                 align              self/align;
                 align_opposite     self/align_opposite;
                 dir                self/direction"
@@ -64,6 +68,10 @@
       xml:lang="en" lang="en" dir="ltr" class="error"
       petal:condition="error/is --component/headlines/mode_invalid"
     >You must choose a mode.</p>
+    <p
+      xml:lang="en" lang="en" dir="ltr" class="error"
+      petal:condition="error/is --component/headlines/audiences_missing"
+    >You must select at least one audience when audience matching is turned on.</p>
   </div>
 
     <p
@@ -253,6 +261,71 @@
       />
     </p>
 
+    <fieldset>
+      <legend>Match audiences</legend>
+      <p>
+        <em
+          class="help"
+          xml:lang="en"
+          lang="en"
+          dir="ltr"
+        >You can restrict the list to display only documents that match one 
+         or more <strong>Audience</strong> types.
+         <br />
+        ( Keep your 'Ctrl' key depressed if you wish to select more than one <strong>Audience</strong> type.)
+        </em>
+        <input 
+          name="audience_on"
+          id="audience_on_yes"
+          type="radio"
+          value="1"
+          petal:attributes="name name_audience_on; id string:${name_audience_on}_yes; checked self/audience_on"
+         />
+         <label 
+          for="audience_on"
+          xml:lang="en"
+          lang="en"
+          dir="ltr"
+         >On</label>
+        <input 
+          name="audience_on"
+          id="audience_on_no"
+          type="radio"
+          value="0"
+          petal:attributes="name name_audience_on; id string:${name_audience_on}_no; checked self/audience_off"
+         />
+         <label 
+          for="audience_on"
+          xml:lang="en"
+          lang="en"
+          dir="ltr"
+          value="0"
+         >Off</label>
+         <br />
+        <label
+          for="audiences"
+          xml:lang="en"
+          lang="en"
+          dir="ltr"
+          petal:attributes="for name_audiences"
+        >Audiences</label>
+        <br />
+        <select 
+          name="audiences"
+          multiple="multiple"
+          id="audiences"
+          petal:attributes="name name_audiences; id name_audiences"
+        >
+          <span petal:repeat="audience self/audiences">
+            <option 
+              petal:content="audience/Label"
+              petal:attributes="value audience/ID; selected self/audience_selected audience"
+            />
+          </span>
+        </select>
+      </p>
+    </fieldset>
+
     <p> 
       <input
         type="submit"


More information about the MKDoc-commit mailing list