[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