I'm using this to create teasers:

<?php
  $sql = 'SELECT 
      nid, 
      title, 
      teaser
    FROM 
      {node} n 
    WHERE 
      status = 1 
    ORDER BY 
      changed desc
    LIMIT 0, 1';
    
  $sql = db_rewrite_sql($sql);
  $result = db_query($sql);
  if($node = db_fetch_object($result)) {
    print($node->teaser);
  }
?>

My only problem, is that I want no more than 9 lines of words. I tried $listlength="9"; but it won't work. Any suggestions?

Comments

acp’s picture

Hi,

what you want is a teaser of 9 lines max ? If so, I don't see an easy way of achieving this since it's highly dependent on your fonts settings, your window size, etc. and the result will therefore vary from user to user.

Doesn't a word maximum do the trick ?

prettyeyes’s picture

I want a minimum of nine lines. If that can't be achieved, do you know how can I go about adding the word maximum with this particular code?

acp’s picture

Hello,

the teaser is automatically generated by drupal, therefore you only have to modify your settings to make the changes for your whole site (note though that the teasers of previous articles won't be rewritten until you edit them).

In Drupal 4.7 you have to go to : administrator > settings > post
In previous versions, it should be in : administer > content > configure or something of the sort.

prettyeyes’s picture

I have 4.7, and I don't see any "posts" under settings.

So there isn't a way that I can work with this snippet? All I need is for it to show fewer lines. I would have to HATE to start over again and find something else.

acp’s picture

Strange, I have it and I don't think it's dependant on any module. As for your code it works fine without any changing. However when you use $node->teaser, it's the one created by drupal and the system as it is doesn't recreate all the teasers if the length is changed. Doing this by hand is really too painfull, especially if you have a great deal of content. A script might do the trick though...

If you really don't find the posts, look at your 'variable' table in your DB, there should be an entry like :
`teaser_length` with a value like this `s:3:"400";` (without the backquote, but the semi-colon is there).
The 400 is the length. Allowed values are from 200 to 2000 by increasing by 200 everytime, or unlimited (which isn't what you want and I don't know how the variable in the DB is set. By the way if your length is greater or equal to 1000, replace the 3 in the value by a 4 since it's the length of the string holding the teaser's length value... (I hope that was clear)

I might take a look on how to update all teasers tomorrow, if you're interested (that might be actually usefull). I guess that if you search someone has maybe already posted something.

acp

prettyeyes’s picture

Thanks, that will be much appreciated!

I looked in my MYSQL database, but couldn't find it. I might have been looking in the wrong place.

acp’s picture

Hi, I'm checking it now. However the fact that you don't find the teaser length worries me a bit. Are you sure you have the 4.7 version of Drupal, because the code I'm writing will probably not work on older versions...

drupal777’s picture

something was posted http://drupal.org/node/67879 but it was just a discussion, not code.

I'll hold off because you sound like you might know what you are talking about, and I'm just guessing!

But I think it would be quite useful. A little late for Renaee, but that is the way things go.

acp’s picture

Hello there,

I got something working with my installation (Drupal 4.7.2). Since it's apparently something that is being asked for, I raised an issue providing this solution (although it doesn't seem very clean to me, but it's a start). It worked fine for me, HOWEVER (!!!) please be carefull when using it.

I strongly suggest that you backup your database and keep a copy of the old node.module file before attempting anything. If your data is too important, don't even bother and wait at least for the (eventual :)) validation of my code by the Drupal team.

You have been warned :).

Here is the link to the issue, with the patch : http://drupal.org/node/71412

acp

acp’s picture

The whole thing came up as a module finally, here is the code :

<?php

/**
 * Implementation of hook_help().
 *
 * Throughout Drupal, hook_help() is used to display help text at the top of
 * pages. Some other parts of drupal pages get explanatory text from these hooks
 * as well. We use it here to provide a description of the module on the
 * module administration page.
 */
function teaser_management_help($section) {
  switch ($section) {
    case 'admin/modules#description':
      // This description is shown in the listing at admin/modules.
      return t('Allows the regeneration of teasers (usefull after a modification of the length for instance)');
  }
}

function teaser_management_form_alter($form_id, &$form) {

  $nodes_count = _teaser_management_nodes_count();

  switch ($form_id) {
    case 'node_configure':
      foreach(array_keys($form) as $form_elt) {
        if ($form_elt == 'teaser_length') {
          $form_cpy[$form_elt] = $form[$form_elt];
          $form_cpy['teaser_management'] = array(
            '#type'        => 'fieldset',
            '#title'       => t('Extended teaser management'),
            '#collapsible' => TRUE,
            '#collapsed'   => FALSE
          );
          $form_cpy['teaser_management']['update_teasers'] = array(
            '#type'          => 'checkbox',
            '#title'         => t('Update trimmed posts'),
            '#default_value' => 0,
            '#description'   => t('Check this in order to trim your posts upon submission of this page, based on the criteria chosen below.')
          );
          $form_cpy['teaser_management']['range_definition'] = array(
            '#type'        => 'fieldset',
            '#title'       => t('Range definition'),
            '#collapsible' => FALSE,
            '#description' => t('You can define a range of nodes\' teasers to modify (min. start is 0, max. end is the number of nodes). The range is not related to the nodes\' id, but rather to the way they are stored in your database. You currently have ' . $nodes_count . ' nodes in your database.')
          );
          $form_cpy['teaser_management']['range_definition']['update_range_teasers_start'] = array(
            '#type'          => 'textfield',
            '#title'         => t('Range start'),
            '#default_value' => variable_get('update_range_teasers_start', 0),
            '#size'          => 5,
            '#maxlength'     => 5
          );
          $form_cpy['teaser_management']['range_definition']['update_range_teasers_end'] = array(
            '#type'          => 'textfield',
            '#title'         => t('Range end'),
            '#default_value' => variable_get('update_range_teasers_end', 50),
            '#size'          => 5,
            '#maxlength'     => 5
          );
          $form_cpy['teaser_management']['update_teasers_method'] = array(
            '#type'          => 'radios',
            '#title'         => t('How to update teasers'),
            '#default_value' => variable_get('update_teasers_method', 0),
            '#options'       => array(
                                  t('Using range definition'),
                                  t('Only promoted nodes (those shown on your website\'s frontpage)')
                                ),
            '#description'   => t('You can choose which method of updating to apply.')
          );
        }
        else {
          $form_cpy[$form_elt] = $form[$form_elt];
        }
      }
      $form = $form_cpy;

      if (variable_get('update_teasers', 0)) {
        variable_set('update_teasers', 0);
        $limit = array(variable_get('update_range_teasers_start', 1), variable_get('update_range_teasers_end', 50));
        _teaser_management_trim(variable_get('update_teasers_method', 0), $limit);
      }
      break;
  }
}

function _teaser_management_nodes_count() {
  $sql = 'SELECT count(nid) num FROM {node}';

  $result = db_query($sql);
  $nodes_count = db_fetch_array($result);

  return $nodes_count['num'];
}

function _teaser_management_trim($promoted_only, &$limit) {

  $sql = 'SELECT nid FROM {node} LIMIT %d, %d';
  if ($promoted_only) {
    $sql .= ' WHERE promote = %d';
    array_push($limit, 1);
  }

  $result = db_query($sql, $limit);

  while ($node_id = db_fetch_object($result)) {
    $node = node_load($node_id->nid);
    if (!isset($node->teaser))
      continue;
    $node->teaser = isset($node->body) ? node_teaser($node->body, isset($node->format) ? $node->format : NULL) : '';
    $node_query = 'UPDATE {node_revisions} SET `teaser` = \'%s\' WHERE nid=\'%d\'';

    $query_values = array($node->teaser, $node->nid);
    db_query($node_query, $query_values);
  }
}

?>

You should name it teaser_management.module and enable it. In order to use it, you go to administer > settings > post. It should normally appear there. If you want your posts to be trimmed next time you click on the submit button on the bottom of the page, check the "Update trimmed posts" box. You then must choose a range of nodes to trim. Attention, this has nothing to do with the nodes id, it's just passed as a LIMIT parameter to the database (for the time being, I'll make some basic verifications afterwards). Finally you choose the action to take.
Either you choose to trim all nodes in the range you defined (don't make it too big, especially if your website is not hosted on your computer because the script will most probably be stopped before it could have finished; you can make steps of 30, that's should be reasonable enough).
The second possible action is to only trim the nodes that are promoted, that is showed on your frontpage. Since I don't see another place where teasers might be used, that should be enough I think. But I'm most probably wrong :).

Anyway, I think I'll keep working on this module a bit. Any feedback is welcomed.

Btw, let me repeat once more : I strongly suggest that you backup your database and keep a copy of the old node.module file before attempting anything. If your data is too important, don't even bother and wait at least for the (eventual :)) validation of my code by the Drupal team. Won't be held responsible for any problem this code might cause ;).

acp

Kimeros’s picture

Thank you very much for writing this.

I had over 2000 entries, I used this module on my site and it worked perfectly.

(And, yes, I took at backup first just incase ;-))

acp’s picture

Hi, thanks for the feedback. Did you do everything at once, or tried by defining some ranges ?

kkobashi’s picture

If you look in the file node.module you will see the function:

  function node_teaser($body, $format = NULL)

A few lines down you will see:

  $size = variable_get('teaser_length', 600);

The line after that is:

  $delimiter = strpos($body, '<!--break-->');

And further down where it truncates to 600 characters in the event the break tag doesn't exist or exceeds the size:

  return truncate_utf8($body, $size);

A "line" depends on the size of the font width as well as the width of the container it sits in. Font widths vary according to the font family. Certaintly, a line of forty 12pixel "i"s will look differently if rendered with courier than using arial (one would give you 480pixels in line width, the other way less than that).

Assuming you can fill the 9 "lines" with enough content, why not just set the teaser length to be of the max characters that can fit on a "line":

maxChars = containerWidthInPixels/widthofFixedCharacter;
teaserChars = 9 lines * maxChars;

Then go into the style.css file and set the node text font size to 12 and font family to courier. Also, you would have to set the node's content width to 480pixels.

Kerry Kobashi

acp’s picture

Added as a module of a greater project : http://drupal.org/project/tweakbox
Other modules will be added in the future (when needed :) )...

If problems, features, errors, etc. need to be reported, please use the project page...

Thanks in advance

acp

DL’s picture

can you also use this to tweak teaser length inside taxonomy blocks or just plain blocks?

acp’s picture

Hello,

from the quick look up I did, the taxonomy block module allows you to define the teaser length right by itself. Since it isn't a node, it isn't handled by this module (apparently they use their own teaser function too).

DL’s picture

thanks for the reply. yup they do but the min number is 200, I was trying to look for something more flexible, I tried the superteaser but I can't seem to make things work.

acp’s picture

Hi,

one way, the best in my opinion, would be to talk about it with the author(s) of this particular module. From what I understand they don't use the node_teaser function of drupal core, and there is no way to easily replace the teasers they generate unless they give the possibility, like for instance image module which allows additionnal functionnalities to be added by writing extensions.

Another way is to modify the module itself so that it does the job you want it too, but first you need to know php and how drupal works (a bit) and second, you'll have to manually apply all modifications made on the module since the day you created your personnal "fork"...