Hi Laura,

(I'm posting this for someone else who asked for it in another discussion..)

I'm a good bit away from finishing it..and will have to move on to something else now..so here it is as if you want to play around with it:

Notes: I was using this in a flexiMAX.module test page where $bodytext = theflexiMAX field for the main body text.....but have modified it so it works with some dummy text and without flexiMAX...easier for you to play around with.

hope that makes sense and is of use. The same principle could be applied to a lengthy blog or other..

/**
* This php snippet splits $body into multiple columns.
* to specify how many columns you want change the
* $columns value.
*
*
* Dublin Drupaller
* please email me any nifty updates.
* http://drupal.org/user/8625/contact
*
* */

print "<table border=\"0\" cellpadding=\"8\"><tr>"; // start the table adjust cellpadding to suit
// Dummy text to play around with the Snippet
$bodytext = array("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut.
Labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
");

$text = implode(",", $bodytext); //prepare bodytext
$columns = 3;  // number of columns

$length = strlen($text); //determine the length of the text
$length = ceil($length/$columns); //divide length by number of columns
$words = explode(" ",$text); // prepare text for word count and split the body into columns
$c = count($words);
$l = 0;
for($i=1;$i<=$columns;$i++) {
    $new_string = "";
    echo "<td style=\"text-align:justify\" valign=\"top\">";
    for($g=$l;$g<=$c;$g++) {
        if(strlen($new_string) <= $length || $i == $columns)
            $new_string.=$words[$g]." ";
        else {
            $l = $g;
            break;
            }
        }
    print $new_string;
    print "</td>";
}
print "</tr></table>"; // complete the table

I tested the snippet before posting it..works fine..

Dub

Comments

laura s’s picture

Any reason why this wouldn't work on node.tpl.php?

Laura
===
pingVisionrare patternscattered sunshine

_____ ____ ___ __ _ _
Laura Scott :: design » blog » tweet

Dublin Drupaller’s picture

A quick guess would be that you need to extract the main $body from the $content.. i.e. in the node.tpl.php file..here is a $content variable..without searching on here, I don't know off the top of my head how to get at the $body of the $content..if you know what I mean.

I think $content is an array which contains other bits apart from the $body.

   <div class="content"><?php print $content?></div>

I was playing around with a flexiMAX(flexinode).tpl.php file...so it was very simple for me to point to a specific field and say "columnise that text"..

$bodytext = array($node->flexinode_9);
// Insert the rest of the snippet here

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

Dublin Drupaller’s picture

Laura...

Just tested it with a test node-blog.tpl.php file and it works fine, here's an example on my test site. I was using and playing around with flexiMAX(flexinode).module..maybe this is easier for you to work from (Assuming you're using a phptemplate based theme):

  1. copy the following code into a new text file called node-blog.tpl.php
  2. upload it to your phptemplate /themes/themename/ folder
  3. all your blogs will now have the main body "columnised" bby default
  4. increase or decrease the $columns value as desired

Note: I haven't tested it fully with images and complex html $bodytext. An image within a column does tend to knock the columns off balance a bit at the moment.

<?php  $columns = 3; // number of columns ?>

<div class="node<?php print ($sticky) ? " sticky" : ""; ?>">
  <?php if ($page == 0): ?>
    <h2><a href="/<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2>
  <?php endif; ?>
  <?php print $picture ?>
  <div class="info"><?php print $submitted ?></div>
  <div class="content">
<?php
print "<table border=\"0\" cellpadding=\"8\"><tr>";
  $bodytext = array("$content");
  $text = implode(",", $bodytext); //prepare bodytext
  $length = strlen($text); //determine the length of the text
  $length = ceil($length/$columns); //divide length by number of columns
  $words = explode(" ",$text); // prepare text for word count and split the body into columns
  $c = count($words);
  $l = 0;
  for($i=1;$i<=$columns;$i++) {
    $new_string = "";
    print "<td style=\"text-align:justify\" valign=\"top\">";
  for($g=$l;$g<=$c;$g++) {
    if(strlen($new_string) <= $length || $i == $columns)
    $new_string.=$words[$g]." ";
    else {
      $l = $g;
    break;
      }
     }
    print $new_string;
    print "</td>";
  }
  print "</tr></table>"; // complete the table
?> 

  </div>
<?php if ($links): ?>
    <?php if ($picture): ?>
      <br class='clear' />
    <?php endif; ?>
  <div class="links"><?php print $links ?></div>
<?php endif; ?>
<div class="terms">( categories: <?php print $terms ?> )</div>
</div>

Hope that's of use..

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

laura s’s picture

Thanks for testing and posting. I might just try this out on a blog site.

Laura
===
pingVisionrare patternscattered sunshine

_____ ____ ___ __ _ _
Laura Scott :: design » blog » tweet

jvincher’s picture

Based on Dub's snippet, I used a node-blog.tpl.php with a 2 column body. It works like a champ, all blog posts automatically receive the desired formatting.

-jv

Dublin Drupaller’s picture

Here's an updated version of that snippet

The difference is that the teasers are *NOT* columnised...only when the blog node is in full view does it columnise the main body text...

here is is:

<?php  $columns = 3; // number of columns ?>

<div class="node<?php print ($sticky) ? " sticky" : ""; ?>">
  <?php if ($page == 0): ?>
    <h2><a href="/<?php print $node_url ?>" title="<?php print $title ?>"><?php print $title ?></a></h2>
  <?php endif; ?>
  <?php print $picture ?>
  <div class="info"><?php print $submitted ?></div>
  <div class="content">
    <?php if (!$page == 0): ?>
<?php
print "<table border=\"0\" cellpadding=\"8\"><tr>";
  $bodytext = array("$content");
  $text = implode(",", $bodytext); //prepare bodytext
  $length = strlen($text); //determine the length of the text
  $length = ceil($length/$columns); //divide length by number of columns
  $words = explode(" ",$text); // prepare text for word count and split the body into columns
  $c = count($words);
  $l = 0;
  for($i=1;$i<=$columns;$i++) {
    $new_string = "";
    print "<td style=\"text-align:justify\" valign=\"top\">";
  for($g=$l;$g<=$c;$g++) {
    if(strlen($new_string) <= $length || $i == $columns)
    $new_string.=$words[$g]." ";
    else {
      $l = $g;
    break;
      }
     }
    print $new_string;
    print "</td>";
  }
  print "</tr></table>"; // complete the table
?> 
<?php endif; ?>
<?php if ($page == 0): ?>
  <?php print $content ?>
  <?php endif; ?>
  </div>
<?php if ($links): ?>
    <?php if ($picture): ?>
      <br class='clear' />
    <?php endif; ?>
  <div class="links"><?php print $links ?></div>
<?php endif; ?>
<div class="terms">( categories: <?php print $terms ?> )</div>
</div>

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

jvincher’s picture

Dub,

Only thing I noticed is that if you have long paragraphs in the node body and choose a a "2 column display", it widens the column that contains the long paragraph. I have not tested it with more than 2 columns but in this setup, he columns are no longer of equal width.

-jv

Dublin Drupaller’s picture

I wonder if making the table column widths equal to 50% will do the trick for you for a 2 col page.

Alternatively it might be better to do it using DIVs instead of tables..

I don't have time to play with it at the mo..so please post back up here if you work out what's knocking the column width off. I notice when an image is in the columns it also knocks it off balance..so it still needs a bit of work.

It seems to work well with just plain text though.

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

liza’s picture

Is this for 4.6? Could you please post more background information on this? Thanks.

Dublin Drupaller’s picture

Hi Liza,

Some background info:

Preamble

I hate scrolling.

I think it is more distracting than turning a page and I wanted to investigate a better way of displaying long passages of text on a screen...

The most eye-friendly layout that most are familiar with is newspapers and magazines, which have used the trick of splitting article text into columns, making the page prettier to look at and ultimately making it easier to read.

If you click through to my Test bed example where I'm playing around with it...it should make more visual sense than just a snippet.

As you can see it's working quite well and I think for blogs and most nodes, a 2-column bodytext is acceptable..once you go to 3 or 4 columns in a non-newspaper/magazine context, I think it loses it's value and actually looks very scrunched up.

The next stage is to paginate very long articles. i.e. instead of scrolling, which I think is distracting, the user simply clicks on [PREVIOUS] - [ NEXT] where the full page isn't loaded again, but, the body text jumps to the next bit...not unlike how Sumah Shah has done with how his codex thing works.

he uses Javascript...I'm not planning to. With the next version of Drupal 4.7 there is some ajax features included and if I can't use those, I will just use a simple DIV which is paginated using very basic and simple principles. The key is to avoid a full page reload to move to the next page, without having to use javascript..

Usage

Instead of creating a new module, I was planning on unleashing it as a simple snippet that could be used in a flexinode.tpl.php file or a blog.tpl.php file.

I mentioned the snippet in another post and Laura nudged me to share it...so I pasted it above as a standard PHP page snippet so others could play around with it.

To play around with using a normal Drupal Page (PHP Input filter):

  1. go to CREATE CONTENT -->> PAGE
  2. Give the article a title
  3. Paste the full snippet into your page
  4. change the dummy text to something else if you want and change the $columns value to increase or decrease the number of columns you want.
  5. select PHP as the Input Filter
  6. Save your page

To insert it into a flexinode-n.tpl.php file...change the lines that define the $bodytext, i.e.

$bodytext = array("Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut.
Labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
Labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.
");

To this:

// change the flexinode field name to match 
// the flexinode field you want to columnise
$bodytext = array($node->flexinode_9);
// Insert the rest of the snippet here

Hope that makes sense..it will work with Drupal 4.6 and pretty much any recent version of Drupal...

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

jvincher’s picture

Dub,

This is great, very useful and I couldn't agree more with your assessment that columns are way prefered over long pieces of text that require vertical scrolling.

Two things here:

- I see you use the regular, non-column display for your teaser. Maybe a silly question but how did you get the teaser to look normal while the body has columns? I assumed that, since the teaser is typically the first 200,400 or 600 characters of that same body, you'd need the excerpt module to differentiate the look of the two?

- The ability to paginate is critical. If you have long articles, columns will help but in this setup you would just create a number of even yet potentially still very long columns. Any thoughts as to how to indicate (I assume based on a desired "column lenght") that pagination (prev, next etc) is required?

Thanks for the good work. These snippets are extremely useful.

-jv

Dublin Drupaller’s picture

Hi Visserj

A simple IF statement in the node-blog.tpl.php file does the trick.

Here's the full ammended node-blog.tpl.php that automatically creates a normal teaser (no columns) and a multicolumn main body.

http://drupal.org/node/38235#comment-70376

The plan with Pagination is to try and achieve something like what Sumah Shah has donewith his codex thing.

he uses javascript..which is fine..but I'd prefer not to have to use such heavy JS and keep it very simple - to avoid issues and that delay that you get when you first look at a page on his site. That's very disconcerting. Some light JS might be needed..but nothing as serious as what he uses.

There are a number of options..and one of those is to split the page into seperate hidden DIV elements and simply jump to anchors within the DIV. Or Using an ajax widget..or using a light piece of javascript similar to that used by tabbed navigations.

If you have any simple ideas on that front..please post up here or email me.

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

RK-2’s picture

Hi Dub,

Thanks for supplying us the code. I know Sumah's solution with JS. It works fine on both IE and FF but the delay it has to print the text (with IE) is indeed very worrying...

Can't we think of a workaround to hide the DIV tag first and then show it a few secs later?

But I agree, it would be better to use a light piece of JS that is also used with tabbed navigations.

Are you going to keep working on your code? I hope so!

I really want to use the code in a new website I am going to launch soon :)

RK

Dublin Drupaller’s picture

I'm working on something else at the moment, but, yeah, I plan to revisit the pagination thing.

Someone has unleashed a paging.module which looks good..the only drawback is you have to insert the page breaks manually..i.e.

first page here.
<!-- page -->
second page here.

I'm going to jump back to the DIV pagination thing..and one idea I had bubbling..was to split the text by character count..i.e.

  1. Do a check on the length of the $content
  2. every x amount of words insert a #page [n] anchor tag where n=page number
  3. insert the appropriate next/previous links
  4. render the page in a non-scrolling DIV with a HEIGHT that fits the screen (the other pages are hidden)

Doing it that way, it will "jump" to the next page (anchor), but, it is actually already loaded..so there's no need for a page refresh.

I hope that makes sense..Drupal 4.7 will have some ajax and javascript stuff built in...so there maybe other approaches in implementing an automated pagination thing. The paging.module is great by the way if you're looking for a right here right now solution.

Dub

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

venkat-rk’s picture

Hi Dub,

Are you aware of the dashboard module that makes two, three and even four column layouts possible?
http://drupal.org/node/35094

Just wanted to flag it for your attention, in case you had missed it.

Dublin Drupaller’s picture

HI Ramdak.

yeah, I saw the dashboard.module...it's a great module but it's not the same thing.

The snippet above columnises a piece of content...the dashboard.module puts content blocks into columns. There's a big difference.

If you look at the new example on my test bed site...i.e. a variation of your Dashboard.module example...Fettucine in Tomato Cream Sauce it should be self explanatory how it's different..

Dub

p.s. thanks for the email!

Currently in Switzerland working as an Application Developer with UBS Investment Bank...using Drupal 7 and lots of swiss chocolate

puregin’s picture

Nice work, though I expect this approach would run into trouble with content containing tables, lists, and other markup.

Perhaps there's a good HTML tokenizer in PHP that could be adapted to this? Or a DOM based solution? By the way, this is the same issue that the teaser-generation runs into.

--
puregin

RK-2’s picture

Hi Dub,

I used your code.... Thanks for that!

But my array also contains <br /> tags. How can I deal with those? They are seen by the code as normal text.

Besides that, on my website I would like to have 2 columns of text, with the first column longer than the second.

The code splits the text in half, as in 50/50.... how can I get something like this:

[ header ]

text text text text text text text text text text
text text text text text text text text text text
text text text text text text text text text text
text text text text text text text text text text
text text text text text text text text text text
text text text text text text text text text text
text text text text text
text text text text text [ link ]
text text text text text [ link ]
text text text text text

LanceLight’s picture

This is a version that I use that uses CSS Div's instead of Tables. Its a little more versitile than the above snippet as well. Improvements are always welcome. It takes into account 2 br combinations as well as deals with p tags

//Released by Ryan Coulombe under the GPL 2.0
//    http://crystaldawn.net

//Usage:
echo newspapercolumns("Your string variable should go here");

function strsplit($str, $l=1) 
{
   //If you run PHP5, you could replace this crap with something simple like str_split($str, 1);  PHP3/4 dont
   //have this type of function, although I wish it did.
   do {
      $ret[]=substr($str,0,$l); 
      $str=substr($str,$l); 
      }
   while($str != "");
   return $ret;
}

function newspapercolumns($str) 
{

//This function *could* take an argument called columns IE newspapercolumns($str, $num_columns)
//but I chose not to do this because my particular setup requires uneven column heights/widths.  I
//can only assume that others would run into the same problem so I've left it the way I use it myself
//so that you can modify each column individually.

//This function also accomodates <br> and <p>.  Since these characters take up more space than a normal
//character (each takes up the width of a column), they need to be accounted for.  I could not find any
//function on the web that does newspaper columns and also accounts for this weirdness so I had to
//whip up my own.  It's not the best code on the planet but it definatly gets the job done.  Its just
//not very human readable code..

//Get the size of our string that came in
$total_size = strlen($str);

//Setup a our columns
//My particular setup requires that the 1st/2nd columns be the same height while the 3rd is much smaller.
//If you want all 3 to be of equal size, simply change total_size * 3/7 to 2/3 and change the 3rd column to 
//be the $col3_max_chars = $col2_max_chars;
$col1_max_chars = ceil($total_size * 3/7);
$col2_max_chars = $col1_max_chars;
$col3_max_chars = $total_size - ($col1_max_chars *2);

 //Split the string into an array thats usable.  There is probably a better way to do this, but I didnt
 //feel like coming up with one myself so I swiped it from someone else
 $str = strsplit($str);
 
 //Initialize the position variable
 $position = 0;
 
 //The br/p weight should be equal to the total width of a column (which is 47 chars for me)
 //This will vary for you depending on the width you set for each column as well as the font size you are using.
 //To find out how many chars this is, simply copy/paste a complete lorum impsum row from your text and paste it into an
 //editor that can tell you how many chars are in that line (IE: OpenOffice Writer or MS Word).  It should count spaces
 //as well.
 
 $br_weight = 47;
 
 //Initialize the column variable with 1 not 0
 $current_column = 1;
 
 //Loop through each character in our string array and assign it to a column.
 foreach ($str AS $character)
 {
   //Increment the position variable
    $position++;
    
    /*********************  Column 1  *********************/
   if ($current_column == 1)
   {
      //Ignore \n characters since they are not displayed in browser space anyways.
      if ($character == "\n") { continue; }
   
      //If this is the first trip through for column 1, we setup the DIV
      if ($counter == 0)
      {
      $col1 = "<div style='float:left; width:230px;  text-align:justify; margin-left:10px;'>\n";
      $counter++;
      }
      
      //Add <br> and <p> allowances since they take up more space than a single char
      if 
      (
         ($character == '<') && (stristr($str[$position], 'p')) && ($str[$position+1] == '>')
      )
      {
       //if we've found a <p> reduce the column max by.the weight we gave <br>/<p>  This helps keep our text in the div on our page
       $col1_max_chars -= $br_weight;
      }
      if 
      (
         (($character == '<') && ($str[$position] == 'b') && ($str[$position+1] == 'r') && ($str[$position+2] == '>')) &&
         ( 
            (($str[$position+3] == '<') && (stristr($str[$position], 'b')) && ($str[$position+5] == 'r') && ($str[$position+6] == '>')) ||
            (($str[$position+3] == "\n") && ($str[$position+4] == '<') && (stristr($str[$position+5], 'b')) && (stristr($str[$position+6], 'r')) && ($str[$position+7] == '>'))
         )
      )
      {
      //if we've found TWO <br>'s reduce the column max by.the weight we gave <br>/<p>  This helps keep our text in the div on our page
       $col1_max_chars -= $br_weight;
      }
      //END <br><p> allowance code
      
   //Fill the first column with our character
   $col1 .= $character;
   
   //Increment the $char_counter variable so we can move to the next character in our string array on the next loop.
   $char_counter++;
   
      //If we are at the maximium height for the first column, we end it here and increment the $current_column variable to start
      //the loop working on the 2nd column. 
      if ((strlen($col1) >= $col1_max_chars) && ($col1[strlen($col1)-1] == ' '))
      {
      $current_column++;
      $col1 .= '</div>';
      }
      
      //Sanitize the variables so they can be re-used in the other columns
      $num_brs = 0;
      $num_ps = 0;
      $num_crs = 0;
      $add_extra_space_for_br = 0;
      
      //Stop the code here and start the loop again.  This prevents the code from trying to build the other columns before it's time.
      continue;
   }
   
    /*********************  Column 2  *********************/
   if ($current_column == 2)
   {
   if ($character == "\n") { continue; }
      if ($counter == 1)
      {
      $col2 = "<div style='float:left; width:230px;  text-align:justify; margin-left:10px;'>\n";
      $counter++;
      }
      
      //Add <br> and <p> allowances since they take up more space than a single char
      if 
      (
         ($character == '<') && (stristr($str[$position], 'p')) && ($str[$position+1] == '>')
      )
      {
       $col2_max_chars -= $br_weight;
      }
      if 
      (
         (($character == '<') && ($str[$position] == 'b') && ($str[$position+1] == 'r') && ($str[$position+2] == '>')) &&
         ( 
            (($str[$position+3] == '<') && (stristr($str[$position], 'b')) && ($str[$position+5] == 'r') && ($str[$position+6] == '>')) ||
            (($str[$position+3] == "\n") && ($str[$position+4] == '<') && (stristr($str[$position+5], 'b')) && (stristr($str[$position+6], 'r')) && ($str[$position+7] == '>'))
         )
      )
      {
       $col2_max_chars -= $br_weight;
      }
      
   $col2 .= $character;
   $char_counter++;
      if ((strlen($col2) >= $col2_max_chars) && ($col2[strlen($col2)-1] == ' '))
      {
      $current_column++;
      $col2 .= '</div>';
      }
   $num_brs = 0;
   $num_ps = 0;
   $num_crs = 0;
   $add_extra_space_for_br = 0;
   continue;
   }
 
     /*********************  Column 3  *********************/
   if ($current_column == 3)
   {
   if ($character == "\n") { continue; }
      if ($counter == 2)
      {
      $col3 = "<div style='float:left; width:230px;  text-align:justify; margin-left:10px;'>\n";
      $counter++;
      }
      
      //Add <br> and <p> allowances since they take up more space than a single char
      if 
      (
         ($character == '<') && (stristr($str[$position], 'p')) && ($str[$position+1] == '>')
      )
      {
       $col3_max_chars -= $br_weight;
      }
      if 
      (
         (($character == '<') && ($str[$position] == 'b') && ($str[$position+1] == 'r') && ($str[$position+2] == '>')) &&
         ( 
            (($str[$position+3] == '<') && (stristr($str[$position], 'b')) && ($str[$position+5] == 'r') && ($str[$position+6] == '>')) ||
            (($str[$position+3] == "\n") && ($str[$position+4] == '<') && (stristr($str[$position+5], 'b')) && (stristr($str[$position+6], 'r')) && ($str[$position+7] == '>'))
         )
      )
      {
       $col3_max_chars -= $br_weight;
      }
   $col3 .= $character;
   $char_counter++;
      if ((strlen($col3) >= $col3_max_chars) && ($col3[strlen($col3)-1] == '.'))
      {
      $current_column++;
      $col3 .= '</div>';
      }
   $num_brs = 0;
   $num_ps = 0;
   $num_crs = 0;
   $add_extra_space_for_br = 0;
      continue;
   }
 }

   //Fill up the $text variable, clean it up, and return it.
 $text = $col1;
 $text .= $col2;
 
 //In some cases the 3rd column will come back without the div attached to it.  We check for this sillyness and fix it.
 if (!strstr($col3, '</div>')) { $col3 .= '</div>'; }
 $text .= $col3;
 
 //Send off our nice shiny new newspaper lookin text block
 return $text;
}
clivesj’s picture

Hello LanceLight,
your code works beautifully for me but could you explain a bit on the $br_weight value. I have been tweeaking it for my setup but no matter what value I choose the last par of the content (how much will depent on the length of the text) will not be displayed.

As I understand the br_weight corrects a certain amount of characters, but how is this done while each line consumes a diggerent amount of characters, depending on the font-type (non monospace) usewd?

regards,

sisyphus’s picture

Does this work in Drupal 5?

pcs305’s picture

Drupal 5 compat?

janwari’s picture

Just wanted to share the code im using to split the $body text into different parts depending on the paragraph after which you want to split the text.

$paragraphs = preg_split( '/<p.*?>/', $node->content[body]['#value'], -1, PREG_SPLIT_NO_EMPTY );
		$i=0;
	foreach ($paragraphs as $key => $value) {
		$paragraphs[$i] = '<p>';
		$paragraphs[$i] .= $value;
		$i++;
	}

$TotalNumberOfParagraphs = count($paragraphs);
$afterparagraph = $field_split_paragraph_number[0]['value'];
$imagewidgetafterparagraph = $field_image_widget_number[0]['value'];
$TextBeforeParagraphSplit = "";
$TextAfterParagraphSplit = "";

for($paragraphcount = 0; $paragraphcount < $afterparagraph; $paragraphcount++){
 	$TextBeforeParagraphSplit .= $paragraphs[$paragraphcount]; 
		if($paragraphcount == ($imagewidgetafterparagraph-1)) {
			$TextBeforeParagraphSplit .= ImageWidget($field_images);
		}
} 

for($paragraphcount = $afterparagraph; $paragraphcount <= $TotalNumberOfParagraphs; $paragraphcount++){ 
	$TextAfterParagraphSplit .= $paragraphs[$paragraphcount]; 
		if($paragraphcount == ($imagewidgetafterparagraph-1)) {
			$TextAfterParagraphSplit .= ImageWidget($field_images);
		}
} 

if($afterparagraph == "") { $TextBeforeParagraphSplit = $TextAfterDetails; }

$TextAfterParagraphSplit and $TextBeforeParagraphSplit contains the number of paragraphs after and before the split. This can be used inside the node-type.tpl.php file to place it anywhere on the page. In addition you can also place a ImageWidget at any location on the page by just specifying the paragaph after which you want to place the ImageWidget

clivesj’s picture

Hello Janwari,
can you confirm this will only work if you have a body consisting of more paragraphs?
If there is one large text in only one paragraph the text will not be split (within the paragraphs). Is this correct?
Regards

janwari’s picture

As you can see in the first line, we are splitting the whole $body text by using the < p > tags as delimiters. Therefore if your $body contains only one paragraph, executing preg_spilt is unnecessary.

If you want to split $body which is a single paragraphs then you could use substr instead.

avolve’s picture

Just a couple Q's (i am not that well versed in theme functions)

This function will divide columns with the same number of paragraphs?

To use this, i would replace $content with two separate divs in the node-type.tpl.php containing $TextAfterParagraphSplit and $TextBeforeParagraphSplit and theme via css to achieve the two columns?

Does this work with D6 or only D5?

thx

avolve designs | ethical by design

avolve’s picture

bumping this to see if anyone has tested this for D6??

avolve designs | ethical by design

merakli’s picture

Wondering if anyone did such customizations on D6, I plan to use blog content type as regular columns on a magazine website.