Email body policy form should show available token browser

Created on 18 March 2022, over 2 years ago
Updated 22 January 2024, 5 months ago

Problem/Motivation

The description for BodyAdjuster form says:

This field may support tokens or Twig template syntax – please check the supplied default policy for possible values.

We should instead help people out. This issue covers the tokens - see ✨ Email body policy form should show available token browser Active for the variables.

Steps to reproduce

Edit a policy and add a body element

Workaround

  1. Look at the default installed policy - this will often use most of the available tokens
  2. Look at the code in the EmailBuilder. The tokens are normally set with setParam() or this can be overridden with tokenData().

Proposed resolution

1) Add new parameter to the @EmailBuilder annotation: token_types = array of types to show in token browser.
2) Make the EmailBuilder definition available in the form

  • Add MailerPolicy::getBuilderDefinition()
  • Deprecate MailerPolicy::getCommonAdjusters(), as it's easy to get from the above
  • In PolicyEditForm::form(), call $this->entity->getBuilderDefinition() and store the result in the form.

3) Use these annotations in BodyEmailAdjuster::settingsForm(). Create a token browser with '#theme' => 'token_tree_link', and set #token_types based on the token_types annotation.

Example

UserEmailBuilder:

token_types = {"user"}

Remaining tasks

User interface changes

API changes

Data model changes

✨ Feature request
Status

Needs work

Version

1.0

Component

Code

Created by

πŸ‡¬πŸ‡§United Kingdom AdamPS

Live updates comments and jobs are added and updated live.
  • Needs tests

    The change is currently missing an automated test that fails when run with the original code, and succeeds when the bug has been fixed.

Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • πŸ‡©πŸ‡ͺGermany sachbearbeiter

    +1 for this feature ...

  • πŸ‡ΊπŸ‡ΈUnited States thalemn

    +1 for this feature

  • @featuriz did you manage to solve the problem?

  • +1 Π·Π° эту Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    Please no more "+1 for this feature"πŸ˜ƒ. It needs a volunteer to write the code (or to offer sponsorship).

  • Assigned to Abyss
  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    I will try to add the described functionality

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    Great thanks - I added some more information to the Issue Summary.

  • Issue was unassigned.
  • while we are waiting for volunteers, can at least someone explain where to get tokens or twig variables for email body in policy?

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    @Anche Good question - I added a "workaround" heading to the Issue Summary.

  • @AdamPS Thanks! Do I understand correctly that before you get the necessary twig variables for your form, you need to programmatically set them? That is, if you are not good enough in programming, symfony mailer will not help you in any way to send emails in html format?

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    Do I understand correctly that before you get the necessary twig variables for your form, you need to programmatically set them?

    No, the variables will already be set automatically. The purpose of this issue is to inform people using the GUI what variables are available.

  • Assigned to Abyss
  • πŸ‡¬πŸ‡§United Kingdom AdamPS
  • πŸ‡¬πŸ‡§United Kingdom AdamPS
  • AdamPS so how to add tokens to email body ? I am confused.

  • πŸ‡ΊπŸ‡¦Ukraine vlad.dancer Kyiv

    Here is a cheap way to add token browser on mailer policy edit form:

    /**
     * Implements hook_form_FORM_ID_alter().
     */
    function symfony_mailer_form_mailer_policy_edit_form_alter(array &$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id): void {
      if (\Drupal::moduleHandler()->moduleExists('token')) {
        $form['config']['token_browser'] = [
          '#theme' => 'token_tree_link',
          '#token_types' => 'all',
          '#global_types' => FALSE,
          '#dialog' => TRUE,
        ];
      }
    }
    

    I'm not a fan of Token UI but at least then we will have tokens list at the hand.

  • πŸ‡©πŸ‡ͺGermany TomSaw Essen

    Thanks @vlad.dancer, this is simple and does the job for me!

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update 8 months ago
    7 pass
  • @abyss opened merge request.
  • Status changed to Needs work 8 months ago
  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    Thanks it's a good start. Please see the issue summary for the next steps. I guess the MR will only show the global tokens.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update 8 months ago
    26 pass
  • Issue was unassigned.
  • Status changed to Needs review 8 months ago
  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    @AdamPS, I added the token list display in the BodyEmailAdjuster.
    About adding an annotation, it seems impossible at the moment, because Adjusters don't know anything about the place where they are called, namely EmailBuilder. So, we had to abandon this idea.
    If you have any other suggestions, I will be happy to add them.

  • Status changed to Needs work 8 months ago
  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    The annotation is on @EmailBuilder instead of the adjuster. Please check the issue summary. It also explains how to adjust 2 of the email builders. Some of the others will need adjusting too.

    BodyEmailAdjuster will need to find the EmailBuilder that was used. I suggest to alter the code in EmailFactory::initEmail() to save it using $email->setParam('_builder_definition', $builder->getPluginDefinition());
    This will cause an assert which you can fix by changing Email::setParam() and also Email::setParams() like this:
    $this->valid(self::PHASE_BUILD, self::PHASE_INIT);

    That's a very compact answer so if you get stuck please ask

  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    However, in this case, this data will be available only at the stages of building an email, which will no longer be valuable to us.
    The data about the current EmailBuilder is not contained in the settingsForm stage, and if I understood the existing code correctly, it cannot be contained there.
    If I've misunderstood something, please correct me.

    Alternatively, we can store these values in the form_state in the PolicyEditForm and retrieve them from the form_state in the BodyEmailAdjuster.
    In this case, to display the available tokens by type, we can indeed describe token_types, but I don't see how we can use variables in this context.

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    Ha I just realised my answer was wrong, however you beat me to itπŸ˜ƒ. I updated the IS with an explanation as you said.

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    For the variables, I imagined something like on a view. Configure a field, select "Override the output of this field with custom text" and expand the box "REPLACEMENT PATTERNS". I uploaded a screenshot. It's completely separate from the token browser, just a list of variables with a description of each.

  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    If I understood correctly, it doesn't seem logical to do this in BodyBuilder.
    In this case, the user will still have to write a handler for their own twig tokens, which is similar to creating their own token.
    So do you mind if we add only token_types?

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    Yes I would accept a patch for only tokens.

    I would create a follow-on issues for the variables. I don't understand what problems you see for them, please could you explain more?

    For example, in ContactEmailBuilder::build() there is this code:

        $email->setVariable('recipient_name', $recipient->getDisplayName())
          ->setVariable('recipient_edit_url', $recipient->toUrl('edit-form')->toString());
    

    The @EmailBuilder annotation would then have a line for each variable giving a description. This allows the form to tell the user the available variables.

  • Open in Jenkins β†’ Open on Drupal.org β†’
    Core: 9.5.x + Environment: PHP 7.4 & MySQL 5.7
    last update 8 months ago
    26 pass
  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    I'm afraid I misunderstood you a bit.
    In this context, it makes sense to add it.
    Then do we need to add something else in this task?

  • πŸ‡¬πŸ‡§United Kingdom AdamPS

    Great. You can choose: do both token and variables in this issue OR have one issue for each of them. I added some more notes to the IS.

  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    If so, let's split it into two tasks and I'll add this functionality tomorrow.

  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    @AdamPS, could you separate these tasks then?

  • πŸ‡ΊπŸ‡¦Ukraine Abyss

    Updated the title and description as it was misplaced with ✨ Email body policy form should show available token browser Active .

  • πŸ‡§πŸ‡ͺBelgium Mav_fly

    I did the propsed patch but after applying this patch i got the follow error :

    Call to undefined method Drupal\symfony_mailer\Entity\MailerPolicy::getVariables()
    line 30 --> www/modules/contrib/symfony_mailer/src/Form/PolicyEditForm.php.

    When set line 30 in comment $form_state->setValue('variables', $this->entity->getVariables());
    The error disappears, but when you click on available tokens the popup windows appears but it's empty .

    Maybe I forgot something, can anyone help me to solve my problem ?

Production build 0.69.0 2024