Allow customizing landing page after double opt-in confirmation

When someone confirms opt-in, they end up on a barebones landing page with a single sentence (“You have confirmed that your email address … has been opted in” from public/legacy/include/EntryPointConfirmOptIn.tpl).

It would be nice to be able to configure an alternate landing page URL, which could be styled to fit the website that the sign-up form is on. If SuiteCRM needs to do some processing first, it could send the user to its own landing page with an immediate redirect to the configured URL.

This has come up before in general discussion, for example:

That’s a good idea :bulb:

If you change this file, does it work? Do you get what you intended?

It’s a core change, but if it works, it’s easy to add a simple change to make this customizable outside the core, in an upgrade-safe way.

Create the file the below location:

custom/include/EntryPointConfirmOptIn.tpl

Maybe try out code with CSS. If it is not working, then you need to find how to link external CSS.

{if $FOCUS}
    <div class="email-confirmation">
        <div class="confirmation-message">
            You have successfully confirmed that your email address "<strong>{$FOCUS->email_address}</strong>" has been opted in.
        </div>
    </div>
{else}
    <div class="email-error">
        <div class="error-message">
            We were unable to confirm your email address. Please try again later.
        </div>
    </div>
{/if}

<style>
    .email-confirmation, .email-error {
        font-family: Arial, sans-serif;
        border-radius: 5px;
        padding: 20px;
        margin: 20px 0;
        text-align: center;
    }

    .confirmation-message {
        background-color: #dff0d8;
        color: #3c763d;
        border: 1px solid #d6e9c6;
    }

    .error-message {
        background-color: #f2dede;
        color: #a94442;
        border: 1px solid #ebccd1;
    }

    .confirmation-message strong {
        font-weight: bold;
    }
</style>

@rsp I don’t think that will work, the code including that template doesn’t seem to be looking at the custom dir. That’s what I mentioned that we would have to change, but it’s an easy change.

But of course this is only worthwhile if the change solves the original problem.

That’s an improvement, thanks. Changing that template does change the landing page.

It’s not as helpful as a redirect to a specified URL, because (like many sites) mine is generated, meaning I don’t have HTML I can simply copy into the template. Also my generated CSS files have random names for cache busting, so I can’t easily link to one, and I can’t put a style tag in the template because it has to be in the head section.

It would be a big step forward though. I can make a copy of the CSS at a stable name, and I can extract chunks of HTML from a generated page to make it reasonably identical. The only downside is that it wouldn’t be auto-generated when something changes, so I’d have to remember to update the template anytime I changed some CSS or navigation or whatnot. With some effort I might even be able to make it generate the template for me, and then I just have to deploy it. But a URL would be easier :slight_smile:

Changing this to custom code requires a few steps but is certainly possible. The most common customization techniques (copying the file to custom dir and changing it there; or having a chance to redefine methods of the object by extending it) won’t work in this case, this code is not very well done for customization purposes, IMHO.

But it starts with a couple of entry-points (see line 64):

Note that line 98 also uses the same handler for another task related to Opt In.

You can create your own entry-points (upgrade-safe) by using this technique:

Now you can emulate the existing code in your own custom area. I think you’ll have to repeat all the code, but it’s not too much.

So, copy that one into custom dir, and make your custom entry-point reference it.

And then

Also copy that one into custom, and make the connector file reference it.

Note how the constructor directs the call to different places according to the operation being handled.

I think the one you want is methodConfirmOptInUser. Funny that they made this private, the dev clearly wasn’t thinking in terms of extensibility… and the tpl doesn’t even check for a possible custom file… when it was so obvious that people would want to customize this.

So you can change all that to fit your needs, not use the tpl at all, etc.

Good luck, and please come back and tell us how it went.