What is GoodNewsSubscription?

Basically GoodNewsSubscription is a Snippet to process newsletter subscription forms. After a subscriber successfully submits the subscription form, a MODX user is created automatically and additional GoodNews user meta data is saved to a custom database table. Depending on your Snippet properties the subscriber is also assigned to GoodNews mailing groups and categories (predefined or by manual selection of the subscriber).

Since version 1.4.1-pl GoodNewsSubscription Snippet can be used as a simple newsletter subscription form only but also as a full MODX user registration form!

Using as a newsletter subscription form

In this case a subscriber doesn't have to choose a username or a password - those credentials will be set automatically based on the subscribers email address and a random password.
A susbcriber will never need to know his MODX user credentials! Updating the subscribers profile or unsubscription will be handled through a secure link from within a newsletter with an aditional and unique secure ID parameter.

Using as a full MODX user registration form

If you need to provide a full MODX user registration form, including the possibillity to allow the user to subcribe to your newsletter system at the same time, simply add a username and password field to your subscription form and GoodNews will do the rest for you.

How to use the Snippet

You need to place the GoodNewsSubscription Snippet in the Resource where your subscription/registration form resides. The Snippet provides a feature to double opt-in a subscriber. The double opt-in feature requires the subscriber to aknowledge/finish the signup process by clicking an activation link in an automatically generated email.

Default properties for the Snippet

The GoodNewsSubscription Snippet implements the following properties (many of them are equivalent to the properties you can find in the well known Register Snippet of the Login add-on):

Property Description Default
activation Whether or not to require activation for subscription. 1=true
activationttl Number of minutes until the activation email expires. 180 (3 hours)
activationEmail Send either to user's email address or this specified activation email address.
activationEmailSubject The subject of the activation email. lexicon string
activationEmailTpl The template for the activation email. sample.GoodNewsActivationEmailTpl
activationEmailTplAlt If set, will use this template instead of $activationEmailTpl (e.g. for plaintext mails).
activationEmailTplType The type of tpl provided for the activation email. modChunk
activationResourceId The Resource ID where the GoodNewsConfirmSubscription Snippet is located.
submittedResourceId If set, will redirect to the specified Resource after the user submits the subscription form.
unsubscribeResourceId The ID of the resource for one-click unsubscription.
profileResourceId The ID of the resource for editing the mailing profile.
sendSubscriptionEmail Wether or not to send user an email after successful subscription. 1 (= true)
subscriptionEmailSubject The subject of the subscription email (only needed if sendSubscriptionEmail = 1 and activation = 0). lexicon string
subscriptionEmailTpl The template for the subscription email (only needed if sendSubscriptionEmail = 1 and activation = 0). sample.GoodNewsSubscriptionEmailTpl
subscriptionEmailTplAlt If set, will use this template instead of subscriptionEmailTpl, e.g. for plaintext mails (only needed if sendSubscriptionEmail = 1 and activation = 0).
subscriptionEmailTplType The type of tpl provided for the subscription email (only needed if sendSubscriptionEmail = 1 and activation = 0). modChunk
reSubscriptionEmailSubject The subject of the renewal email. lexicon string
reSubscriptionEmailTpl The template for the renewal email. sample.GoodNewsReSubscriptionEmailTpl
reSubscriptionEmailTplAlt If set, will use this template instead of reSubscriptionEmailTpl (e.g. for plaintext mails).
reSubscriptionEmailTplType The type of tpl provided for the renewal email. modChunk
errTpl Chunk for error output. <span class="error">[[+error]]</span>
useExtended Whether or not to set any extra fields in the form to the users extended field. 0 (= false)
excludeExtended A comma-separated list of fields to exclude from setting as extended fields.
emailField The name of the field to use for the new User's email address. email
usernameField The name of the field to use for the new User's username (only needed if snippet is used as a user registration form). username
passwordField The name of the field to use for the new User's password (only needed if snippet is used as a user registration form). password
persistParams A JSON object of parameters to persist across the register process.
preHooks A comma-separated list of 'hooks' (Snippets), that will be executed before the user is subscribed but after validation.
postHooks A comma-separated list of 'hooks' (Snippets), that will be executed after the user is subscribed.
submitVar The name of the form submit button that triggers the submission. goodnews-subscription-btn
successMsg If page redirects to itself, this message will be set to a placeholder.
usergroups A comma-separated list of MODX user group names or IDs to add the new subscriber to.
usergroupsField The name of the field to use for the new subscribers usergroups. usergroups
validate A comma-separated list of fields to validate.
grpFieldsetTpl Chunk name for GoodNews group fieldset. sample.GoodNewsGrpFieldsetTpl
grpFieldTpl Chunk name for GoodNews group checkbox element. sample.GoodNewsGrpFieldTpl
grpNameTpl Chunk name for GoodNews group name element. sample.GoodNewsGrpNameTpl
grpFieldHiddenTpl Chunk name for GoodNews group input hidden element. sample.GoodNewsGrpFieldHiddenTpl
catFieldTpl Chunk name for GoodNews category checkbox element. sample.GoodNewsCatFieldTpl
catFieldHiddenTpl Chunk name for GoodNews category input hidden element. sample.GoodNewsCatFieldHiddenTpl
groupsOnly Whether or not the output should only contain GoodNews groups. 0 = false
includeGroups Comma separated list of GoodNews group ids to be used for output. 0 = use all groups
defaultGroups Comma separated list of GoodNews group ids which should be preselected as hidden fields. 0 = none
defaultCategories Comma separated list of GoodNews category ids which should be preselected as hidden fields. 0 = none
sort Field to sort by for GoodNews groups/categories. name
dir Sort direction for GoodNews groups/categories. ASC
grpCatPlaceholder The placeholder to set the generated GoodNews groups/categories tree to. grpcatfieldsets
placeholderPrefix The prefix to use for all placeholders set by this Snippet.

Field Validators

Field Validators in GoodNewsSubscription follow the same syntax as the validators of the FormIt add-on. You can use the methods described there to use them in your GoodNewsSubscription setup.

Post-Validation

After the form has been validated, the GoodNewsSubscription Snippet can do the following:

  • Assign subscribers to GoodNews mailing groups and categories
  • Send an activation email (for double opt-in).
  • Redirect to a specific Resource (e.g. Subscription finished page).
  • or display a success message.
  • Send a subscription/registration success email.
  • Additionally assign the subscriber to one or more MODX usergroups.

Assigning Subscribers to MODX User Groups (optional)

Assigning susbcribers to MODX usergroups follows the same syntax as in the FormIt add-on. You can use the methods described there to use them in your GoodNewsSubscription setup.

Please don't confuse MODX user groups with GoodNews groups or categories! The former are used by MODX to define permissions, the latter for GoodNews subscriptions and fields of interests.

Sending an Activation Email for double opt-in

GoodNewsSubscription (by default) requires subscribers to activate their subscription before they can receive newsletters. The Snippet creates the modUser object and sets its active field to 0. The subscriber gets an email with an URL to activate the subscription. Once a subscriber clicks the activation link, the account is set to active, and he will be able receive newsletters.

To enable this, you will need to create an activation page by creating a new Resource, and putting the GoodNewsConfirmSubscription Snippet inside of it. GoodNews comes with preinstalled, ready to use Resources regarding the activation.

Next, you'll need to specify an email template Chunk to use for the email being sent to subscribers. GoodNews comes with a preinstalled sample Chunk of an email template: sample.GoodNewsActivationEmailTpl.

An example GoodNewsSubscription Snippet call with activation required would look like this:

[[!GoodNewsSubscription?
    &submittedResourceId=`34`
    &activationResourceId=`35`
    &activationEmailTpl=`sample.GoodNewsActivationEmailTpl`
    &activationEmailSubject=`Thank you for joining our newsletter service at [[++site_name]]`
    &sendSubscriptionEmail=`1`
    &unsubscribeResourceId=`42`
    &profileResourceId=`43`
    &subscriptionEmailSubject=`Your subscription to our newsletter service at [[++site_name]] was successful!`
    &reSubscriptionEmailSubject=`Renewal of your newsletter subscription at [[++site_name]]!`
    &validate=`
        email:email:required,
        gongroups:required,
        nospam:blank`
    &groupsOnly=`1`
    &gongroups.vTextRequired=`Please choose at least one mailing group.`
]]

This setup will send a subscriber an email with the content specified in the sample.GoodNewsActivationEmailTpl Chunk with the specified subject line. After the email is sent, the subscriber will be redirected to a Resource with ID 34 where he gets the hint to activate his subscription by clicking the link inside the received email. The activation link in the email will redirect the subscriber to the Resource with ID 35 where the subscription is activated automatically.

Activation can be turned off by setting &activation=`0`. But this will mean anyone - including spambots - can subscribe with each email address.

The &activationEmailTpl property can be a Chunk name by default. You can change the type of the field by setting &activationEmailTplType to one of the following values:

  • modChunk - The default. A name of a Chunk.
  • file - Specify a filename with an absolute path. You can use {core_path}, {base_path} or {assets_path} as placeholders for this value.
  • inline - Specify the html straight in the property value.

You can set the time-to-live for an activation email, as well. This will restrict the number of minutes until the activation window expires. You can do this by setting the value in the &activationttl property. It defaults to 180 minutes.

How are GoodNews groups and categories handled?

The GoodNewsSubscription Snippet will output the selectable mailing groups and categories checkbox fields (or hidden fields) automatically based on your Snippet properties. To define which group and category fields will be available in the subscription form, the following parameters are available:

  • &groupsOnly - Whether or not the output should only contain GoodNews groups. Defaults to 0 = false
  • &includeGroups - Comma separated list of GoodNews group ids to be used for output. Defaults to 0 = use all groups
  • &defaultGroups - Comma separated list of GoodNews group ids which should be preselected as hidden fields. Defaults to 0 = none
  • &defaultCategories - Comma separated list of GoodNews category ids which should be preselected as hidden fields. Defaults to 0 = none

The &groupsOnly parameter can be used to limit the output to GoodNews groups only. No HTML for category fields will be generated.

With the &includeGroups parameter, you can define a comma separated list of GoodNews group IDs which will be exclusively used for output. All other available groups will be excluded from output.
Please note that the output will also contain all categories related to the specified groups. This behaviour can be prevented by aditionally using the &groupsOnly=`1` parameter.

The parameters &defaultGroups and &defaultCategories, which both will take comma separated lists of IDs, will tell the snippet to output group and category fields as hidden form fields. In this case the subscriber can't select which groups or categories he will be assigned to and he will only have to enter his email address in the subscription form.

Looking at the GoodNews groups and categories parameters, the following setup will render a list of selectable groups (checkbox fields) with IDs 3, 36, 40, 48. The related categories will be excluded from output because of the &groupsOnly=`1` parameter.

[[!GoodNewsSubscription?
    &submittedResourceId=`34`
    &activationResourceId=`35`
    &activationEmailTpl=`sample.GoodNewsActivationEmailTpl`
    &activationEmailSubject=`Thank you for joining our newsletter service at [[++site_name]]`
    &validate=`
        email:email:required,
        nospam:blank`
    &includeGroups=`3,36,40,48`
    &groupsOnly=`1`
]]

The final HTML (groups/category fields) will then be written to a placeholder. The name of this placeholder can be defined with the property &grpCatPlaceholder (defaults to grpcatfieldsets).

Based on the philosophy on how GoodNews handles mailing groups and categories, a general rule of the GoodNewsSubscription Snippet is, that if your output contains selectable groups and categories. The group fields will not be rendered as checkbox fields. In this case only the child categories will be selectable. If a subscriber selects a category, internally the parent group will also be selected.

Here is a sample content (HTML) of the +grpcatfieldset placeholder based on the single property &includeGroups=`40,48` (please note how the group fields are rendered as labels):

<fieldset class="grpfieldset">
    <p class="grpfield">
        <label class="cblabel">Global News <span class="desc">(Description for group Global news)</span></label>
    </p>
	<p class="catfield">
        <input type="checkbox" name="goncategories[]" value="4" id="goncategory4">
        <label for="goncategory4" class="cblabel">Breaking News <span class="desc">(lorem ipsum dolor)</span></label>
    </p>
</fieldset>
<fieldset class="grpfieldset">
    <p class="grpfield">
        <label class="cblabel">Software <span class="desc">(Lorem ipsum dolor)</span></label>
    </p>
    <p class="catfield">
        <input type="checkbox" name="goncategories[]" value="44" id="goncategory44">
        <label for="goncategory44" class="cblabel">Business Software <span class="desc">(Lorem ipsum dolor sit amet.)</span></label>
    </p>
	<p class="catfield">
        <input type="checkbox" name="goncategories[]" value="36" id="goncategory36">
        <label for="goncategory36" class="cblabel">Games <span class="desc">(Description for category)</span></label>
    </p>
	<p class="catfield">
        <input type="checkbox" name="goncategories[]" value="37" id="goncategory37">
        <label for="goncategory37" class="cblabel">iPhone Apps <span class="desc">(Description for category)</span></label>
    </p>
</fieldset>

Sample Subscription Form

For a sample and universal GoodNews subscription form please have a look at the code below. This code is conceived to automatically handle hidden and/or selectable GoodNews groups and categories output.

<div class="main">
    <h2>Subscribe to our newsletter</h2>
    <p>
        Sign up for our occasional newsletter and get news and updates 
        delivered to your inbox. And don't worry, you can unsubscribe instantly 
        or change your preferences at any time.
    </p>
    <form id="profileform" class="gon-form" action="[[~[[*id]]]]" method="post">
        <input type="hidden" name="nospam" value="[[!+nospam]]">
        [[!+error.message:notempty=`
            <p class="errorMsg">[[!+error.message]]</p>
        `]]
        <fieldset>
            <legend>Personal Data</legend>
            <p class="fieldbg[[!+error.email:notempty=` fielderror`]]">
                <label for="email">
                    E-Mail Address
                    [[!+error.email]]
                </label>
                <input type="email" name="email" id="email" value="[[!+email]]" placeholder="Please enter your e-mail address" required>
            </p>
            <p class="fieldbg[[!+error.fullname:notempty=` fielderror`]]">
                <label for="fullname">
                    First and Last Name (optional)
                    [[!+error.fullname]]
                </label>
                <input type="text" name="fullname" id="fullname" value="[[!+fullname]]" placeholder="Please enter your first and last name">
            </p>
        </fieldset>
        [[!+fields_hidden:is=`1`:then=`[[!+grpcatfieldsets]]`:else=`
            <fieldset>
                <legend>Newsletter Topics</legend>
                <p class="fieldbg">
                    <label class="singlelabel">
                        Please choose the newsletter topics you are interested in.
                        [[!+error.gongroups]]
                        [[!+error.goncategories]]
                    </label>
                    <input type="hidden" name="gongroups[]" value="">
                    <input type="hidden" name="goncategories[]" value="">
                </p>
                [[!+grpcatfieldsets]]
            </fieldset>
        `]]
        <p>
            <button type="submit" role="button" name="goodnews-subscription-btn" value="Subscribe" class="button green">Subscribe now</button>
        </p>
    </form>
</div>

Please note, the hidden input fields with empty values in line 39 and 40 of the above HTML code. Since HTML does not send values for unchecked checkbox fields, the "required" validation on checkboxes wouldn't be possible. You'll need to add those "hidden" fields (same name as the checkbox with an empty value) before, so that at least an empty value is sent.

If you use the &defaultGroups or &defaultCategories properties, the GoodNewsSubscription Snippet automatically sets a special placeholder +fields_hidden=`1`. This placeholder can be used to modify the output (please have a look at the HTML code above).

The Chunks for mailing group and category output

GoodNews comes with a bunch of predefined and ready to use Chunks for processing the groups categories output. Normally you don't have to change these Chunks but if you need to, please have a look at the default properties table above on how to set and use these.