Skip sending newsletter nodes do not have body content, i.e. the {{ issue }} is blank.

Created on 15 August 2025, 2 months ago

This request is not new. The use case is common and it's a generally expected featured for a Newsletter.

Create a View and embed the view into the body field of the newsletter issue node. On some days there is no new content to go out, so the newsletter does not need to be sent. However, what happens is a email with no body content is sent (what is the use case for this?).

Rules, Business Rules and ECA do not integrate with simplenews, nor simplenews_scheduler, and there appears to be no progress on those front going forward.

So then, it comes down to either Symfony Mailer (only supported html mail option) or this module to prevent emails from being sent when the {{ issue }} token does not render any html output. Seems like this module should take care of this.

Thank you!

✨ Feature request
Status

Active

Version

4.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States drupgirl

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @drupgirl
  • πŸ‡ΊπŸ‡ΈUnited States drupgirl
  • πŸ‡ΊπŸ‡ΈUnited States drupgirl

    For others who need this, it is sorted through with the following, along with a companion View with your IDs and display names.

    1. Use the dev version with the MR in the related issue.
    2. Create your views and note their machine name and display machine names. You need these to build keyword arrays.
    3. Create a custom module simplenews_issue_check.module that hooks into hook alter provided by the patch. (Nice work. Thank you.)
    
    <?php
    
    use Drupal\node\NodeInterface;
    use Drupal\views\Views;
    use Drupal\Core\Render\RendererInterface;
    use Drupal\Core\Logger\LoggerChannelFactoryInterface;
    
    /**
     * Implements hook_simplenews_scheduler_edition_node_alter().
     *
     * Allows modules to alter the edition node before it is saved.
     *
     * @param \Drupal\node\NodeInterface $edition_node
     *   The cloned edition node object.
     * @param \Drupal\node\NodeInterface $template_node
     *   The original Simplenews template node.
     * @param array $context
     *   An associative array of additional context information.
     *   This is passed by reference, allowing modules to add or modify
     *   values within it.
     */
    function simplenews_issue_check_simplenews_scheduler_edition_node_alter(NodeInterface &$edition_node, NodeInterface $template_node, array &$context) {
    
      // You can also inspect or modify the $edition_node and $template_node objects here if needed.
      if ($edition_node->bundle() == 'simplenews_issue') {
    
        $logger = \Drupal::logger('simplenews_issue_check');
        // $logger->info('HERE "%edition_title"', ['%edition_title' => $edition_node->getTitle()]);
    
        // Get body text - should use this to auto set $views_id and $display_id.
        if ($edition_node->hasField('body') && !$edition_node->get('body')->isEmpty()) {
          $body_value = $edition_node->get('body')->value;
          $trimmed_body = substr($body_value, 0, 100);
          $logger->notice('First 100 characters of body field for node @nid: @trimmed_body', [
            '@nid' => $edition_node->id(),
            '@trimmed_body' => $trimmed_body,
          ]);
        }
    
        // Replace 'my_custom_view' with your View's machine name.
        // $view_id = 'units_3_priority_program';  // Start with a test case. Proof of concept.
        // Replace 'my_view_display' with your View display's machine name.
        // $display_id = 'block_3pp_created'; // Test Result here should be: Has No results
        // $display_id = 'block_3pp_updated'; // Test Results here should be: Has results
    
        // Make Dynamic - This should come via an interface.
        $programs = ['units_3_priority_program', 'units_dmh_dds_program'];
        $foundprogram = false;
        foreach ($programs as $program) {
          if (strpos($trimmed_body, $program) !== FALSE) {
            $view_id = $program;
            $foundprogram = TRUE;
            break;
          }
        }
    
        $displays = ['block_3pp_created', 'block_3pp_updated', 'block_3pp_deadline', 'block_dmh_dds_created', 'block_dmh_dds_updated', 'block_dmh_dds_deadline'];  // This should first filter through being if type $program, and then can be if contains updated, deadline, created.
        $founddisplay = false;
        foreach ($displays as $display) {
          if (str_contains(haystack: $trimmed_body, needle: $display)) {
            $display_id = $display;
            $founddisplay = true;
            break;
          }
        }
    
        if ( $foundprogram && $founddisplay) { // Some of the logic below should be contained/combined here. Useful condition.
          $logger->notice('View: @viewid, @displayid', [
            '@viewid' => $view_id,
            '@displayid' => $display_id,
          ]);
        }
    
        // $view = views_get_view('$view_id');
        $view = Views::getView($view_id);
        if (!$view) {
          // View does not exist.
          $logger->warning('View ID: Program DNE');
          return;
        }
    
        $view->setDisplay($display_id);
        // Set arguments if needed
        // $view->set_arguments(['arg1', 'arg2']);
    
        $view->execute();
    
        if (empty($view->result)) {
          // The view has no results.
          \Drupal::messenger()->addStatus('Skip sending newsletter, the view has no results.');
          $logger->warning('The view has no results.');
          // Handle empty case: return early, set a flag, etc.
          // Set a variable in the context array to TRUE.
          $context['skip_edition'] = TRUE;  // This comes via the patch. Huzzah!
    
          // Optionally save it, but not send and rename node. Businesses would more than likely like to save the node first and then not send. Then they have a visual record. Renaming makes sense here.
          // $edition_node->setTitle('Altered title for not sent edition: ' . $edition_node->getTitle());
    
        } else {
          // The view has results.
          \Drupal::messenger()->addStatus('View has results.');
          $logger->warning('Send Newsletter Issue.');
          // Optionally render the view.
          // $render_array = $view->render();
    
        }
    
      }
    }
    
    
Production build 0.71.5 2024