Name

div-organize —

ATTRIBUTES

Attribute Pos. Req. Default Description

DESCRIPTION

BEHAVIOR

This tag does not appear to be affected by, or affect, the rest of Interchange.

EXAMPLES

No examples are available at this time. We do consider this a problem and will try to supply some.

NOTES

AVAILABILITY

div-organize is available in Interchange versions:

5.8.0, 5.9.0 (git-head)

SOURCE

Interchange 5.9.0:

Source: dist/strap/config/div_organize.tag
Lines: 339


UserTag div-organize Order         cols
UserTag div-organize attrAlias     columns cols
UserTag div-organize Interpolate
UserTag div-organize addAttr
UserTag div-organize hasEndTag
UserTag div-organize Documentation <<EOD

=head1 div-organize

[div-organize <options>]
  [loop ....] <div> [loop-tags] </div> [/loop]
[/div-organize]

Takes an unorganized set of div cells and organizes them into
rows based on the number of columns; it will also break them into
separate divs.
All of this assumes using bootstrap 3 and higher classes of: "row" for rows, 
and "col-xx-6" for two col for example, "col-xx-4" for 3 column combined with
option of cols=3.

If the number of cells are not on an even modulus of the number of columns,
then "filler" cells are pushed on.

Parameters:

=over 4

=item cols (or columns)

Number of columns. This argument defaults to 2 if not present.

=item rows

Optional number of rows. Implies "table" parameter.

=item table

If present, will cause a surrounding <div> </div> pair with the attributes
specified in this option. ie for bootstrap you might use table="class='container'"

=item caption

Table <CAPTION> container text, if any. Can be an array.

=item div

Attributes for div table cells. Can be an array. ie could be col-md-6 if using 2 col

=item row_attr

Attributes for div table rows. Can be an array. typically would be class="row"

=item columnize

Will display cells in (newspaper) column order, i.e. rotated.

=item pretty

Adds newline and tab characters to provide some reasonable indenting.

=item filler

Contents to place in empty cells put on as filler. Defaults to C<&nbsp;>.

=item filler_class

Class to place in empty cells put on as filler. Defaults to C<filler_class>.
With bootstrap you may want this to be the same as target divs to keep columns straight ie 
col-md-6 for 2 col display

=item min_rows

On small result sets, can be ugly to build more than necessary columns.
This will guarantee a minimum number of rows -- columns will change
as numbers change. Formula: $num_cells % $opt->{min_rows}.

=item limit

Maximum number of cells to use. Truncates extra cells silently.

=item embed

If you want to embed other divs inside, make sure they are called with
lower case <div> elements, then set the embed tag and make the cells you wish
to organize be <DIV> elements. To switch that sense, and make the upper-case
or mixed case be the ignored cells, set the embed parameter to C<lc>.

  [div-organize embed=lc]
  <div>
    <TABLE>
      <TR>
      <TD> something 
        <DIV> something </DIV>
      </TD>
      </TR>
    </table>
  </div>
  [/div-organize]

or

  [div-organize embed=uc]
  <DIV>
    <div>
      something
    </div>
  </DIV>
[/div-organize]

=back

Need to experiment with this stuff, for div only.
Also note, we should update current table organize with Bootstrap
class considerations

The C<row_attr>, C<td>, and C<caption> attributes can be specified with indexes;
if they are, then they will alternate according to the modulus.

The C<td> option array size should probably always equal the number of columns;
if it is bigger, then trailing elements are ignored. If it is smaller, no attribute
is used.

For example, to produce a table that 1) alternates rows with background
colors C<#EEEEEE> and C<#FFFFFF>, and 2) aligns the columns RIGHT CENTER
LEFT, do:

      [div-organize
          cols=3
          pretty=1
    filler_class='col-md-4'
          ]
          [loop list="1 2 3 1a 2a 3a 1b"] <div class="col-md-4"> [loop-code] </div> [/loop]
      [/div-organize]

which will produce:

      <div class="row">
              <div class="col-md-4">1</div>
              <div class="col-md-4">2</div>
              <div class="col-md-4">3</div>
      </div>
      <div class="row">
              <div class="col-md-4">1a</div>
              <div class="col-md-4">2a</div>
              <div class="col-md-4">3a</div>
      </div>
      <div class="row">
              <div class="col-md-4">1b</div>
              <div class="col-md-4">&nbsp;</div>
              <div class="col-md-4">&nbsp;</div>
      </div>

If the attribute columnize=1 is present, the result will look like:

      <div class="row">
              <div class="col-md-4">1</div>
              <div class="col-md-4">1a</div>
              <div class="col-md-4">1b</div>
      </div>
      <div class="row">
              <div class="col-md-4">2</div>
              <div class="col-md-4">2a</div>
              <div class="col-md-4">&nbsp;</div>
      </div>
      <div class="row">
              <div class="col-md-4">3</div>
              <div class="col-md-4">3a</div>
              <div class="col-md-4">&nbsp;</div>
      </div>

See the source for more ideas on how to extend this tag.

=cut

EOD
UserTag div-organize Routine <<EOR
sub {
my ($cols, $opt, $body) = @_;
$cols = int($cols) || 2;
$body =~ s/(.*?)(<div)\b/$2/is
  or return;
my $out = $1;
$body =~ s:(</div>)(?!.*</div>)(.*):$1:is;
my $postamble = $2;

my @cells;
if($opt->{cells} and ref($opt->{cells}) eq 'ARRAY') {
  @cells = @{$opt->{cells}};
}
elsif($opt->{embed}) {
  if($opt->{embed} eq 'lc') {
    push @cells, $1 while $body =~ s:(<div\b.*?</div>)::s;
  }
  else {
    push @cells, $1 while $body =~ s:(<DIV\b.*?</DIV>)::s;
  }
}
else {
  push @cells, $1 while $body =~ s:(<div\b.*?</div>)::is;
}

while ($opt->{min_rows} and ($opt->{min_rows} * ($cols - 1)) > scalar(@cells) ) {
  $cols--;
  last if $cols == 1;
}

if(int($opt->{limit}) and $opt->{limit} < scalar(@cells) ) {
  splice(@cells, $opt->{limit});
}

for(qw/ table/) {
  $opt->{$_} = defined $opt->{$_} ? " $opt->{$_}" : '';
}

##Left off here
my @div;

if(! $opt->{div}) {
  @div = '' x $cols;
}
elsif (ref $opt->{div} ) {
  @div = @{$opt->{div}};
  push @div, '' while scalar(@div) < $cols;
}
else {
  @div = (" $opt->{div}") x $cols;
}

##Have not touched

my %attr;
for(qw/caption row_attr pre post/) {
  if( ! $opt->{$_} ) {
    #do nothing
  }
  elsif (ref $opt->{$_}) {
    $attr{$_} = $opt->{$_};
  }
  else {
    $attr{$_} = [$opt->{$_}];
  }
}
##Have not touched

my $pretty = $opt->{pretty};

my @rest;
my $rows;

my $rmod;
my $tmod = 0;
my $total_mod;

$opt->{filler} = '&nbsp;' if ! defined $opt->{filler};

my $td_beg;
my $td_end;

if($rows = int($opt->{rows}) ) {
  $total_mod = $rows * $cols;
  @rest = splice(@cells, $total_mod)
    if $total_mod < @cells;
  $opt->{table} = ' ' if ! $opt->{table};
}

my $joiner = $opt->{joiner} || ($pretty ? "\n\t\t" : "");
while(@cells) {
  if ($opt->{columnize}) {
    my $cell_count = scalar @cells;
    my $row_count_ceil = POSIX::ceil($cell_count / $cols);
    my $row_count_floor = int($cell_count / $cols);
    my $remainder = $cell_count % $cols;
    my @tmp = splice(@cells, 0);
    my $index;
    for (my $r = 0; $r < $row_count_ceil; $r++) {
      for (my $c = 0; $c < $cols; $c++) {
        if ($c >= $remainder + 1) {
          $index = $r + $row_count_floor * $c + $remainder;
        }
        else {
          $index = $r + $row_count_ceil * $c;
        }
        push @cells, $tmp[$index];
        last if $r + 1 == $row_count_ceil and $c + 1 == $remainder;
      }
    }
  }

  my $fclass = $opt->{filler_class} || 'filler_class';
  while (scalar(@cells) % $cols) {
    push @cells, qq|<div class="$fclass">$opt->{filler}</div>|;
  }

  #$out .= "<!-- starting table tmod=$tmod -->";
  if($opt->{table}) {
    $out .= "<div$opt->{table}>";
    $out .= "\n" if $pretty;
  }
  $rmod = 0;
  while(@cells) {
    $out .= "\t" if $pretty;
    $out .= qq{<div};
    if($opt->{row_attr}) {
      my $idx = $rmod % scalar(@{$attr{row_attr}});
      $out .= " " . $attr{row_attr}[$idx];
    }
    else {
      $out .= ' class="row"';
    }
    $out .= ">";
    $out .= "\n\t\t" if $pretty;
    my @op =  splice (@cells, 0, $cols);
    if($opt->{div}) {
      for ( my $i = 0; $i < $cols; $i++) {
        $op[$i] =~ s/(<div)/$1 $div[$i]/i;
      }
    }
    @op = map { s/>/>$td_beg/; $_ }       @op  if $td_beg;
    @op = map { s/(<[^<]+)$/$td_end$1/; $_ } @op  if $td_end;

    $out .= join($joiner, @op);
    $out .= "\n\t" if $pretty;
    $out .= "</div>";
    $out .= "\n" if $pretty;
    $rmod++;
  }
  if($opt->{table}) {
    $out .= "</div>";
    $out .= "\n" if $pretty;
  }
  if(@rest) {
    my $num = $total_mod < scalar(@rest) ? $total_mod : scalar(@rest);
    @cells = splice(@rest, 0, $num);
  }
  $tmod++;
}
return $out . $postamble;
}
EOR

AUTHORS

Interchange Development Group

SEE ALSO

DocBook! Interchange!