I apologize if I overlooked some hidden feature, but I would really like to use something like that:

Let's say I have 3 different taxonomy tags for pulling the content of nodes into the newsletter...
1. news
2. education
3. useful links

In the template I would prefer to organize these entries in sort of groups (with headings), like
News
node1
node2
node3

Education
node4
node5
node6

Useful links
node7

However I can't figure out how to do this with the [repeat] ... [/repeat] tokens.
The order of nodes in the newsletter is always by creation time of content.

Are there any other helper modules available to accomplish the task?
Or do I have to fiddle with the SQL SELECT clause that pulls the nodes from the DB?

EDIT:

I've managed to change the SQL, so the return order is not sorted just by time of creation of content, but instead gives priority to
the taxonomy tag & weight.

Here's the modified code:

  /**
   * Builds a dynamic query
   * that gets the current nodes to be sent with the current newsletter.
   */
  protected function getQuery() {
    $tids = newsletter_get_template_terms($this->template->ntid);
    $tids = array_keys($tids) ? array_keys($tids) : array(0);

    $query = db_select('taxonomy_index', 'tax');
    $query->fields('tax', array('nid'));
    $query->join('newsletter_list', 'list', 'list.nlid = ' . (int) $this->list->nlid);
    $query->join('node', 'node', 'tax.nid = node.nid');
    $query->join('taxonomy_term_data', 'ttd', 'tax.tid = ttd.tid');
    $query->addField('node', 'created', 'created');
    $query->condition('tax.tid', $tids, 'IN');
    $query->where('(list.last_sent <= node.created) OR (list.last_sent IS NULL )');
    if (!$this->manualSendRate && !$this->customSendRate) {
      $query->where('list.send_again = CURDATE() OR list.send_again IS NULL');
    }
    if ($this->customSendRate) {
      $query->range(0, (int) $this->list->send_rate);
    }
    else {
      $query->range(0, (int) variable_get('newsletter_node_limit', 50));
    }
    $query->orderBy('ttd.weight', 'ASC');
    $query->orderBy('created', 'DESC');
    $query->distinct();

    return $query;
  }

Comments

ParisLiakos’s picture

Hmm adding an alter hook there would be a smart thing to do.
This would be fairly easy.
Something like

<?php
drupal_alter
('newsletter_node_query', $query);
?>

or, even better a tag

<?php
->addTag('newsletter_node_query');
?>

Then anyone could overwrite it, without hacking the module

kutulu’s picture

Agreed. Especially when upgrading the module, those hooks & tags should be simpler.

Can you give me a hint on how to separate the content in the email?
Now the nodes are sorted, but there's no spacing between them - i would like to add a heading to each topic/taxonomy group.
Like a picture or maybe only a

...

The whole output should be in a table, which i've already done in the template, but as said i would like to insert topic headers inbetween the listed nodes.

I've also had problems with links appearing relative, even if i set the base_url in the settings. Even when inserting tokens with
[node:url:absolute].

That's why i wrote an override and extra check for links without the base_url in it.

  /**
   * Add the source and nnid to newsletter URLs so we can gather clicks.
   */
  public function addNewsletterUrlQuery($message) {
    if (isset($message['params']['newsletter']->nnid)) {
      //global $base_url;
<strong>      $base_url = 'http://www.example.com';</strong>
      $nnid = $message['params']['newsletter']->nnid;

      $dom = new DomDocument;
      // Convert to html entities to avoid text scrumbling
      // due to encoding especially for non-latin characters.
      $message['body'] = mb_convert_encoding($message['body'], 'HTML-ENTITIES', 'UTF-8');

      @$dom->loadHTML($message['body']);
      $links = $dom->getElementsByTagName('a');

      foreach ($links as $link) {
        $href = $link->getAttribute('href');
        if (strpos($href, $base_url) !== FALSE) {
          $href = drupal_parse_url($href);
          $query = array_merge($href['query'], array('source' => 'newsletter', 'nnid' => $nnid));
  $link->setAttribute('href', url($href['path'], array('query' => $query)));

<strong> if (strpos($link->getAttribute('href'), $base_url) === FALSE) {         
$link->setAttribute('href', $base_url.url($href['path'], array('query' => $query)));
}</strong>
        }
      }

      // Converts back from hmtl entities
      return decode_entities($dom->saveHTML());
    }
    return $message['body'];
  }

I guess this is the part of code i have to alter, to achieve my goal of inserting topics...

kutulu’s picture

Issue summary:View changes

I tried to alter a few lines of code to achieve my goal of grouping content. Filename newsletter.automated.inc.