Skip to content

Commit d0066ec

Browse files
authored
Merge pull request #7 from mtrezza/add-placeholders-to-placeholder-callback
- made placeholders available in placeholder callback
2 parents cf89f18 + 3d225aa commit d0066ec

File tree

4 files changed

+49
-8
lines changed

4 files changed

+49
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
### 🧬 Improvements
77
- Added locale to placeholder callback. [#6](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/6). Thanks to [mtrezza](https://github.com/mtrezza).
8+
- Added current placeholders to placeholder callback. [#7](https://github.com/mtrezza/parse-server-api-mail-adapter/pull/7). Thanks to [mtrezza](https://github.com/mtrezza).
89

910
# 1.0.1
1011
[Full Changelog](https://github.com/mtrezza/parse-server-api-mail-adapter/compare/1.0.0...1.0.1)

README.md

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,9 @@ const server = new ParseServer({
9999
// A callback that makes the Parse User accessible and allows
100100
// to return user-customized placeholders that will override
101101
// the default template placeholders. It also makes the user
102-
// locale accessible, if it was returned by the `localeCallback`.
103-
placeholderCallback: async ({ user, locale }) => {
102+
// locale accessible, if it was returned by the `localeCallback`,
103+
// and the current placeholders that will be augmented.
104+
placeholderCallback: async ({ user, locale, placeholders }) => {
104105
return {
105106
phone: user.get('phone');
106107
};
@@ -149,12 +150,13 @@ There are different files for different parts of the email:
149150
Placeholders allow to dynamically insert text into the template file content. The placeholders are filled in according to the key-value definitions returned by the placeholder callback in the adapter configuration.
150151

151152
This is using the [mustache](http://mustache.github.io/mustache.5.html) template syntax. The most commonly used tags are:
152-
- `{{double-mustache}}`
153+
- `{{double-mustache}}`: The most basic form of tag; inserts text as HTML escaped by default.
154+
- `{{{triple-mustache}}}`: Inserts text with unescaped HTML, which is required to insert a URL for example.
153155

154-
The most basic form of tag; inserts text as HTML escaped by default.
155-
- `{{{triple-mustache}}}`
156-
157-
Inserts text with unescaped HTML, which is required to insert a URL for example.
156+
By default, the following placeholders are available in the password reset and email verification templates:
157+
- `appName`: The app name as defined in the Parse Server configuration.
158+
- `username`: The username of the user who requested the email.
159+
- `link`: The URL to the password reset or email verification form.
158160

159161
# Localization
160162

spec/ApiMailAdapter.spec.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,41 @@ describe('ApiMailAdapter', () => {
466466
expect(apiCallback.calls.all()[0].args[0].payload.text).not.toContain(templatePlaceholder);
467467
});
468468

469+
it('overrides the template placeholder with the email placeholder', async () => {
470+
const adapter = new ApiMailAdapter(config);
471+
const apiCallback = spyOn(adapter, 'apiCallback').and.callThrough();
472+
const email = {
473+
templateName: 'customEmailWithPlaceholderCallback',
474+
recipient: '[email protected]',
475+
direct: true,
476+
placeholders: {
477+
appName: "EmailPlaceholder"
478+
}
479+
}
480+
const template = config.templates[email.templateName];
481+
const templatePlaceholder = template.placeholders.appName;
482+
const emailPlaceholder = email.placeholders.appName;
483+
spyOn(template, 'placeholderCallback').and.callFake(async () => {
484+
return {};
485+
});
486+
487+
await adapter._sendMail(email);
488+
expect(apiCallback.calls.all()[0].args[0].payload.text).toContain(emailPlaceholder);
489+
expect(apiCallback.calls.all()[0].args[0].payload.text).not.toContain(templatePlaceholder);
490+
});
491+
492+
it('makes placeholders accessible in placeholder callback', async () => {
493+
const adapter = new ApiMailAdapter(config);
494+
const templateName = 'customEmailWithPlaceholderCallback';
495+
const template = config.templates[templateName];
496+
const email = { templateName, link, appName, user };
497+
const placeholderCallback = spyOn(template, 'placeholderCallback').and.callThrough();
498+
499+
await adapter._sendMail(email);
500+
expect(placeholderCallback.calls.all()[0].args[0].placeholders.link).toBe(link);
501+
expect(placeholderCallback.calls.all()[0].args[0].placeholders.appName).toBe(appName);
502+
});
503+
469504
it('makes user locale accessible in placeholder callback', async () => {
470505
const adapter = new ApiMailAdapter(config);
471506
const apiCallback = spyOn(adapter, 'apiCallback').and.callThrough();

src/ApiMailAdapter.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,9 +228,12 @@ class ApiMailAdapter extends MailAdapter {
228228

229229
// If placeholder callback is set
230230
if (placeholderCallback) {
231+
232+
// Copy placeholders to prevent any direct changes
233+
const placeholderCopy = Object.assign({}, placeholders);
231234

232235
// Add placeholders from callback
233-
let callbackPlaceholders = await placeholderCallback({ user, locale });
236+
let callbackPlaceholders = await placeholderCallback({ user, locale, placeholders: placeholderCopy });
234237
callbackPlaceholders = this._validatePlaceholders(callbackPlaceholders);
235238
Object.assign(placeholders, callbackPlaceholders);
236239
}

0 commit comments

Comments
 (0)