[prev in list] [next in list] [prev in thread] [next in thread] 

List:       bricolage-devel
Subject:    Re: [Bricolage-Devel] Output Channel Associations
From:       David Wheeler <david () wheeler ! net>
Date:       2002-10-08 22:37:38
[Download RAW message or body]

On Monday, October 7, 2002, at 10:20  PM, David Wheeler wrote:

> Now the behavior starts to change. The enclosed patch adds the ability 
> to select output channels in story and media profiles. It builds on 
> the previous patches implementing the API side of this functionality 
> so that now, in individual stories and media, you can select which 
> output channels a story or media asset will be published to.

Okay, I think this is the last patch for this feature (ignoring likely 
bugs cropping up over the next few weeks). I was beginning to think I'd 
never get it done!

This patch slightly changes last night's by handling checkbox output 
channels in assets more intelligently -- so that the database doesn't 
try to delete and add in the same OC mapping (thereby possibly 
triggering SQL exceptions). It also lists output channels that are part 
of the asset even if they're no longer part of the element on which the 
asset is based.

Other than that, it adds a listing of output channels to the "View" 
profile of stories and media. And of course, it also now has a new 
interface for associating output channels with elements. You can add as 
many as you like, and mark one as primary and any or all of them as 
enabled (meaning that a new asset based on that element will be marked 
to be published to those output channels by default). All of this is 
done through a listManager interface, which offers better flexibility 
and reliability that the old doubleListManager interface did.

Comments welcome. I plan to commit tomorrow.

Regards,

David

-- 
David Wheeler                                     AIM: dwTheory
david@wheeler.net                                 ICQ: 15726394
http://david.wheeler.net/                      Yahoo!: dew7e
                                                Jabber: Theory@jabber.org


["oc_select.txt" (oc_select.txt)]

--- /dev/null	Tue Oct  8 10:44:01 2002
+++ comp/widgets/profile/asset_ocs.mc	Tue Oct  8 15:22:37 2002
@@ -0,0 +1,117 @@
+% if (@$ocs < 4) {
+%    # Output check boxes.
+<table border="0" width="578" cellpadding="0" cellspacing="0">
+  <tr><td align="right" width="125" valign="top">
+    <span class="label">Output Channels:</span>
+  </td>
+  <td width="4"><img src="/media/images/spacer.gif" width="4" height="1" /></td>
+  <td width="449">
+     <& /widgets/profile/hidden.mc, name => "$widget|do_ocs" &>
+%    my %curocs = map { $_->get_id => $_ } $asset->get_output_channels;
+%    foreach my $oc (@$ocs) {
+         <& /widgets/profile/checkbox.mc,
+                 label_after => 1,
+                 checked => delete $curocs{$oc->get_id},
+                 disp => $oc->get_name,
+                 value => $oc->get_id,
+                 name => "$widget|oc",
+          &><br />
+%    }
+%    # Add any remainders from the asset itself.
+%    foreach my $oc (values %curocs) {
+         <& /widgets/profile/checkbox.mc,
+                 label_after => 1,
+                 checked => 1,
+                 disp => $oc->get_name,
+                 value => $oc->get_id,
+                 name => "$widget|oc",
+          &><br />
+%    }
+  </td></tr>
+</table>
+<%perl>;
+} else {
+    # Output double list manager.
+    my $left = [ map { { description => $_->get_name, value => $_->get_id } }
+                 @$ocs ];
+    my $right = [ map { { description => $_->get_name, value => $_->get_id } }
+                  $asset->get_output_channels ];
+    $m->out("<br />\n");
+    $m->comp( "/widgets/doubleListManager/doubleListManager.mc",
+              size         => 4,
+	      leftOpts     => $left,
+	      rightOpts    => $right,
+	      formName     => 'theForm',
+	      leftName     => 'rem_oc',
+	      rightName    => 'add_oc',
+	      leftCaption  => "Available Output Channels",
+	      rightCaption => 'Current Output Channels',
+	    );
+}
+</%perl>
+<%args>
+$widget
+$asset
+$ocs
+</%args>
+<%doc>
+
+=head1 NAME
+
+/widgets/profile/asset_ocs.mc - The Asset Output Channel display component
+
+=head1 VERSION
+
+$Revision: 1.7 $
+
+=head1 DATE
+
+$Date: 2002/06/29 09:08:16 $
+
+=head1 SYNOPSIS
+
+  $m->comp('/widgets/profile/asset_ocs.mc',
+           asset  => $story,
+           widget => $widget,
+           ocs    => \@ocs
+          );
+
+=head1 DESCRIPTION
+
+This component displays form widgets for adding output channels to business
+assets. If the number of possible output channels (passed via the C<$ocs>
+array reference argument) to be displayed is less than four, it will output
+check boxes with all of the output channels. If the number of possible output
+channels is four or more, it will display a double list with four rows of
+output channels visible in each scrollable list.
+
+The arguments (all required) are:
+
+=over 4
+
+=item C<asset>
+
+The asset for which the output channels are to be displayed.
+
+=item C<widget>
+
+The name of the widget for which the output channels are to be displayed
+(either "story_prof" or "media_prof").
+
+=item C<$ocs>
+
+An anonymous array of all of the available output channels to be displayed.
+
+=back
+
+If the fields are checkboxes, there will be a hidden field called
+"$widget|do_ocs" and the checkbox names will be "$widget|oc". These will be an
+array reference if more than one checkbox is checked. If the fields are in the
+form of a double list, the field names will be "add_oc" and "rem_oc". The
+former will be a single ID or array reference of IDs to be added to the
+story. The latter will be a single ID or array reference of IDs to be removed
+from the story.
+
+=pod
+
+</%doc>
? comp/widgets/profile/asset_ocs.mc
Index: comp/admin/profile/element/dhandler
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/admin/profile/element/dhandler,v
retrieving revision 1.9
diff -u -w -r1.9 dhandler
--- comp/admin/profile/element/dhandler	19 Jul 2002 09:46:07 -0000	1.9
+++ comp/admin/profile/element/dhandler	8 Oct 2002 22:25:24 -0000
@@ -43,50 +43,68 @@
 
 # Manage Output Channels if this is a top-level container.
 if (Bric::Biz::ATType->lookup({ id => $comp->get_type__id })->get_top_level) {
-
-    my ($left, $right, $opt) = ([], [], []);
-
-    # Assemble the list of output channels for this instance.
-    foreach my $grp ( $id ? @{$comp->get_output_channels} : () ) {
-	push @$right, { value =>  $grp->get_id, description => $grp->get_name };
-    }
-
-    # Assemble a list of all output channels.
-    foreach my $oc ( Bric::Biz::OutputChannel->list({ active => 1 }) ) {
-	push @$left, { value =>  $oc->get_id, description => $oc->get_name };
-	push @$opt, [ $oc->get_id, $oc->get_name ];
+    my $primid = $comp->get_primary_oc_id;
+    my $oc_sub = sub {
+        my $ocid = $_[0]->get_id;
+        if ($_[1] eq 'primary') {
+            # Output a hidden field for this included OC.
+            $m->scomp('/widgets/profile/radio.mc',
+                      name => 'primary_oc_id',
+                      value => $ocid,
+                      checked => $ocid == $primid,
+                      useTable => 0
+                     );
+        } elsif ($_[1] eq 'enabled') {
+            $m->scomp('/widgets/profile/checkbox.mc',
+                      name => 'enabled',
+                      value => $ocid,
+                      checked => $_[0]->is_enabled,
+                      useTable => 0
+                     );
     }
+    };
 
-    # Load up the double-list manager.
-    $m->comp("/widgets/wrappers/sharky/table_top.mc",
-  	     caption => "Output Channels",
+    $m->comp('/widgets/listManager/listManager.mc',
+	     object => 'output_channel',
+	     userSort => 0,
+	     def_sort_field => 'name',
+	     title => 'Output Channels',
+	     objs => scalar $comp->get_output_channels,
+	     addition => undef,
+	     fields => [qw(name description enabled primary)],
+	     field_titles => { primary => 'Primary', enabled => 'Enabled' },
+	     field_values => $oc_sub,
+	     profile => undef,
+	     select =>  ['Delete', 'rem_oc'],
 	     number  => ++$num
 	    );
 
-    $m->comp( "/widgets/doubleListManager/doubleListManager.mc",
-	      readOnly     => $no_edit,
-	      leftOpts     => $left,
-	      rightOpts    => $right,
-	      formName     => 'cont_profile',
-	      leftName     => 'rem_oc',
-	      rightName    => 'add_oc',
-	      leftCaption  => $no_edit ? undef : "Available Output Channels",
-              showLeftList => !$no_edit || 0,
-	      rightCaption => 'Current Output Channels',
-
-	    );
-
+</%perl>
+<table border=1 cellpadding=2 cellspacing=0 width=580 bordercolor="#cccc99" \
style="border-style:solid; border-color:#cccc99;"> +<tr><td class="medHeader" \
style="border-style:solid; border-color:#cccc99;"><& \
'/widgets/select_object/select_object.mc', +    object => 'output_channel',
+    field  => 'name',
+    exclude => [ $id, map { $_->get_id } $comp->get_output_channels ],
+    no_persist => 1,
+    name   => 'formBuilder|add_oc_id_cb',
+    default => ['' => 'Add Output Channel'],
+    constrain => { active => 1 },
+    js => "onChange='submit()'",
+    useTable => 0,
+&></td></tr>
+</table>
+<br />
+<%perl>;
+    $m->out(qq{<img src="/media/images/spacer.gif" width="578" height="8" />});
     # Now load a select widget so a primary output channel can be selected.
-    $m->comp('/widgets/profile/select.mc',
-	     disp => 'Primary Output Channel',
-	     name => 'primary_oc_id',
-	     options => $opt,
-	     req => 1,
-	     readOnly => $no_edit,
-	     value => $comp->get_primary_oc_id
-	    );
-
-    $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
+#    $m->comp('/widgets/profile/select.mc',
+#	     disp => 'Primary Output Channel',
+#	     name => 'primary_oc_id',
+#	     options => $opt,
+#	     req => 1,
+#	     readOnly => $no_edit,
+#	     value => $comp->get_primary_oc_id
+#	    );
 
 }
 
Index: comp/widgets/formBuilder/callback.mc
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/formBuilder/callback.mc,v
retrieving revision 1.5
diff -u -w -r1.5 callback.mc
--- comp/widgets/formBuilder/callback.mc	4 Dec 2001 18:17:40 -0000	1.5
+++ comp/widgets/formBuilder/callback.mc	8 Oct 2002 22:25:24 -0000
@@ -3,11 +3,9 @@
 </%args>
 <%init>;
 my ($section, $mode, $key) = $m->comp("/lib/util/parseUri.mc");
-# HACK - This should be changed in the class table at some point.
-my $type = $key eq 'element' ? 'element' : $key;
 
 # Get the class name.
-my $class = get_package_name($type);
+my $class = get_package_name($key);
 
 # Instantiate the object.
 my $id = $param->{$key . '_id'};
Index: comp/widgets/formBuilder/element.mc
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/formBuilder/element.mc,v
retrieving revision 1.16
diff -u -w -r1.16 element.mc
--- comp/widgets/formBuilder/element.mc	9 Mar 2002 00:43:01 -0000	1.16
+++ comp/widgets/formBuilder/element.mc	8 Oct 2002 22:25:24 -0000
@@ -26,7 +26,8 @@
 return unless $field eq "$widget|save_cb"
   || $field eq "$widget|add_cb"
   || $field eq "$widget|save_n_stay_cb"
-  || $field eq "$widget|addElement_cb";
+  || $field eq "$widget|addElement_cb"
+  || $field eq "$widget|add_oc_id_cb";
 return unless $param->{$field}; # prevent multiple calls to this file
 
 
@@ -72,7 +73,14 @@
     $comp->set_name($param->{name}) unless $no_save;
     $comp->set_description($param->{description});
     $comp->set_burner($param->{burner}) if defined $param->{burner};
-    $comp->set_primary_oc_id($param->{primary_oc_id}) if exists \
$param->{primary_oc_id}; +
+    # Set the primary output channel ID.
+    if ($param->{primary_oc_id}) {
+        $comp->set_primary_oc_id($param->{primary_oc_id});
+    } elsif ($field eq "$widget|add_oc_id_cb" && ! $comp->get_primary_oc_id) {
+        # Their adding the first one. Make it the primary.
+        $comp->set_primary_oc_id($param->{"$widget|add_oc_id_cb"});
+    }
 
     # Update existing attributes. Get them from the Parts::Data class rather than \
                from
     # $comp->get_data so that we can be sure to check for both active and inactive
@@ -164,15 +172,35 @@
 	$comp->del_data($del);
     }
 
-    # add or delete output channels
-    $comp->add_output_channels( mk_aref($param->{add_oc}) )
-      if $param->{add_oc};
-    $comp->delete_output_channels( mk_aref($param->{rem_oc}) )
-      if $param->{rem_oc};
+    # Delete output channels.
+    if ($param->{rem_oc}) {
+        my $primoc = $comp->get_primary_oc_id;
+        my $del_oc_ids = mk_aref($param->{rem_oc});
+        for (@$del_oc_ids) {
+            $comp->set_primary_oc_id(undef) and last if $_ == $primoc;
+        }
+        $comp->delete_output_channels($del_oc_ids);
+    }
+
+    # Enable output channels.
+    my %enabled = map { $_ => 1 } @{ mk_aref($param->{enabled}) };
+    foreach my $oc ($comp->get_output_channels) {
+        $enabled{$oc->get_id} ? $oc->set_enabled_on : $oc->set_enabled_off;
+    }
+
+    # Add output channels.
+    $comp->add_output_channel($param->{"$widget|add_oc_id_cb"})
+      if $field eq "$widget|add_oc_id_cb";
 
     # delete any selected sub elements
     if ($param->{"element|delete_cb"}) {
 	$comp->del_containers( mk_aref($param->{"element|delete_cb"}) );
+    }
+
+    # Force a primary output channel ID if we don't have one but we have OCs.
+    unless ($comp->get_primary_oc_id) {
+        my $oc = ($comp->get_output_channels)[0];
+        $comp->set_primary_oc_id($oc->get_id) if $oc;
     }
 
     # Save the element.
Index: comp/widgets/media_prof/callback.mc
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/media_prof/callback.mc,v
retrieving revision 1.14
diff -u -w -r1.14 callback.mc
--- comp/widgets/media_prof/callback.mc	18 Sep 2002 20:08:33 -0000	1.14
+++ comp/widgets/media_prof/callback.mc	8 Oct 2002 22:25:25 -0000
@@ -42,6 +42,31 @@
     $media->set_priority($param->{priority})
       if exists $param->{priority};
 
+    # Set output channels.
+    if (exists $param->{"$widget|do_ocs"}) {
+        # Check boxes.
+        my %ocids = map { $_ => 1 } @{ mk_aref($param->{"$widget|oc"}) };
+        # Delete unchecked output channels.
+        foreach my $oc ($media->get_output_channels) {
+            $media->del_output_channels($oc) unless delete $ocids{$oc->get_id};
+        }
+
+        # Add those that are left.
+        $media->add_output_channels
+          (map { Bric::Biz::OutputChannel->lookup({ id => $_ }) } keys %ocids )
+          if %ocids;
+    } else {
+        # Double list. Remove output channels.
+        $media->del_output_channels(@{ mk_aref($param->{rem_oc}) })
+          if defined $param->{rem_oc};
+
+        # Add new output channels.
+        $media->add_output_channels
+          (map { Bric::Biz::OutputChannel->lookup({ id => $_ }) }
+           @{ mk_aref($param->{add_oc}) } )
+           if defined $param->{add_oc};
+    }
+
     # Set the dates.
     $media->set_cover_date($param->{cover_date})
       if exists $param->{cover_date};
Index: comp/widgets/media_prof/edit_meta.html
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/media_prof/edit_meta.html,v
retrieving revision 1.11
diff -u -w -r1.11 edit_meta.html
--- comp/widgets/media_prof/edit_meta.html	28 Aug 2002 20:04:41 -0000	1.11
+++ comp/widgets/media_prof/edit_meta.html	8 Oct 2002 22:25:25 -0000
@@ -118,14 +118,25 @@
    key => 'expire_date',
 &>
 <% $ieSpacer %>
+<%perl>;
+# get output channel info
+my $at = $media->get_element__id;
+my $asset_type = Bric::Biz::AssetType->lookup({id => $at});
+my @ocs = $asset_type->get_output_channels;
+$m->comp('/widgets/profile/asset_ocs.mc',
+         asset  => $media,
+         widget => $widget,
+         ocs    => \@ocs
+        );
 
-% $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
+$m->comp("/widgets/wrappers/sharky/table_bottom.mc");
 
-% $m->comp("/widgets/wrappers/sharky/table_top.mc",
-%	caption => "Upload a file",
-%	number => 2
-%	);
+$m->comp("/widgets/wrappers/sharky/table_top.mc",
+         caption => "Upload a file",
+         number => 2
+        );
 
+</%perl>
 <table width=578 cellpadding=2 cellspacing=0>
 <tr>
   <td width=<% $infoIndent %> valign=top align=right><span class="label">File \
                Path:</span></td>
Index: comp/widgets/media_prof/view_meta.html
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/media_prof/view_meta.html,v
retrieving revision 1.6
diff -u -w -r1.6 view_meta.html
--- comp/widgets/media_prof/view_meta.html	23 Apr 2002 23:45:43 -0000	1.6
+++ comp/widgets/media_prof/view_meta.html	8 Oct 2002 22:25:25 -0000
@@ -89,6 +89,16 @@
   <td width="<% $infoIndent %>" align="right" class="medHeader"><span \
class="label">Priority:&nbsp;</span></td>  <td width="470">&nbsp;<% \
$media->get_priority() %></td>  </tr>
+
+  <tr>
+  <td bgcolor="white"><img src="/media/images/spacer.gif" width="1" height="1" \
/></td> +  </tr>
+
+  <tr>
+  <td class="medHeader"><img src="/media/images/spacer.gif" height="18" width="1" \
/></td> +  <td width="<% $infoIndent %>" align="right" class="medHeader"><span \
class="label">Output Channels:&nbsp;</span></td> +  <td width="470">&nbsp;<% join ', \
', (map { $_->get_name } $media->get_output_channels) %></td> +  </tr>
 </table>
 
 % $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
Index: comp/widgets/story_prof/callback.mc
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/story_prof/callback.mc,v
retrieving revision 1.19
diff -u -w -r1.19 callback.mc
--- comp/widgets/story_prof/callback.mc	26 Sep 2002 00:17:35 -0000	1.19
+++ comp/widgets/story_prof/callback.mc	8 Oct 2002 22:25:25 -0000
@@ -66,6 +66,32 @@
       if exists $param->{"$widget|source_id"};
     $story->set_priority($param->{priority})
       if exists $param->{priority};
+
+    # Set output channels.
+    if (exists $param->{"$widget|do_ocs"}) {
+        # Check boxes.
+        my %ocids = map { $_ => 1 } @{ mk_aref($param->{"$widget|oc"}) };
+        # Delete unchecked output channels.
+        foreach my $oc ($story->get_output_channels) {
+            $story->del_output_channels($oc) unless delete $ocids{$oc->get_id};
+        }
+
+        # Add those that are left.
+        $story->add_output_channels
+          (map { Bric::Biz::OutputChannel->lookup({ id => $_ }) } keys %ocids )
+          if %ocids;
+    } else {
+        # Double list. Remove output channels.
+        $story->del_output_channels(@{ mk_aref($param->{rem_oc}) })
+          if defined $param->{rem_oc};
+
+        # Add new output channels.
+        $story->add_output_channels
+          (map { Bric::Biz::OutputChannel->lookup({ id => $_ }) }
+           @{ mk_aref($param->{add_oc}) } )
+           if defined $param->{add_oc};
+    }
+
     if (($param->{cover_date} || '') ne ($story->get_cover_date || '')) {
         my $old_date = $story->get_cover_date();
         $story->set_cover_date($param->{cover_date});
@@ -165,7 +191,7 @@
     $story ||= get_state_data($widget, 'story');
 
     # Abort this save if there were any errors.
-    return unless &$save_data($param, $widget, $story);
+#    return unless &$save_data($param, $widget, $story);
 
     my $work_id = get_state_data($widget, 'work_id');
 
@@ -348,7 +374,7 @@
     $story ||= get_state_data($widget, 'story');
 
     # Abort this save if there were any errors.
-    return unless &$save_data($param, $widget, $story);
+#    return unless &$save_data($param, $widget, $story);
 
     my $work_id = get_state_data($widget, 'work_id');
 
Index: comp/widgets/story_prof/edit_meta.html
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/story_prof/edit_meta.html,v
retrieving revision 1.13
diff -u -w -r1.13 edit_meta.html
--- comp/widgets/story_prof/edit_meta.html	13 Sep 2002 22:01:50 -0000	1.13
+++ comp/widgets/story_prof/edit_meta.html	8 Oct 2002 22:25:25 -0000
@@ -134,8 +134,13 @@
    key => 'expire_date',
 &>
 
-
-<%perl>
+<% $ieSpacer %>
+<%perl>;
+$m->comp('/widgets/profile/asset_ocs.mc',
+         asset  => $story,
+         widget => $widget,
+         ocs    => \@ocs
+        );
 
 $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
 
@@ -328,7 +333,6 @@
 
 $m->comp("/widgets/wrappers/sharky/table_bottom.mc");
 
-
 $m->comp("/widgets/profile/buttonBar.mc",
          widget      => $widget,
          desks       => $desks,
@@ -337,11 +341,9 @@
 );
 
 </%perl>
-
 <%args>
 $widget
 </%args>
-
 <%init>
 my $story   = get_state_data($widget, 'story');
 my $tile    = $story->get_tile();
Index: comp/widgets/story_prof/view_meta.html
===================================================================
RCS file: /cvsroot/bricolage/bricolage/comp/widgets/story_prof/view_meta.html,v
retrieving revision 1.8
diff -u -w -r1.8 view_meta.html
--- comp/widgets/story_prof/view_meta.html	23 Apr 2002 23:45:43 -0000	1.8
+++ comp/widgets/story_prof/view_meta.html	8 Oct 2002 22:25:25 -0000
@@ -135,6 +135,16 @@
   <td width="470">&nbsp;<% $story->get_published_version %></td>
   </tr>
 
+  <tr>
+  <td bgcolor="white"><img src="/media/images/spacer.gif" width="1" height="1" \
/></td> +  </tr>
+
+  <tr>
+  <td class="medHeader"><img src="/media/images/spacer.gif" height="18" width="1" \
/></td> +  <td width="<% $infoIndent %>" align="right" class="medHeader"><span \
class="label">Output Channels:&nbsp;</span></td> +  <td width="470">&nbsp;<% join ', \
', (map { $_->get_name } $story->get_output_channels) %></td> +  </tr>
+
 </table>
 
 <& '/widgets/wrappers/sharky/table_bottom.mc' &>


-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Bricolage-Devel mailing list
Bricolage-Devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bricolage-devel

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic