WIP
Beispiel-App im gitext ablegen, dann die essentiellen Teile hier hereinkopieren.
Goal: Send a Newsletter that is based on a Mailing Template but also contains content that is dynamically gathered and rendered with CSE.
https://gitext.pinuts.de/um-public/tutorial-dynamic-newsletter-content
Mailing Template offerlist-nl
:
Dear {firstname}, your top offers for today: {withcse:renderOfferList:}
cmsbs-conf/cse/plugins/de.pinuts.tutorial/callback/RenderEntryCallback.es6
/// <reference path="../../../.vscode.js"/> import faker from "@de.pinuts.demodata/shared/faker.es6"; function renderOffers(offers) { return `<ul>${offers.map(renderOffer).join('')}</ul>`; } function renderOffer(offer) { return ( `<li style="margin-bottom: 8px"> <strong>${Strings.encodeXml(offer.productName)}</strong><br/> ${Strings.encodeXml(offer.price)} </li>`); } function fakeOffers() { const offers = []; const num = faker.random.number({min: 0, max: 5}); for (let idx = 0; idx < num; idx++) { offers.push({ productName: faker.commerce.productName(), price: faker.commerce.price(10, 100, 2, '€') }); } return offers; } RenderEntryCallback.prototype.renderOfferList = function() { const offers = fakeOffers(); this.templateContext.doSend = offers.length > 0; this.value = renderOffers(offers); return true; }
cmsbs-conf/cse/plugins/de.pinuts.tutorial/shared/SendOfferListNewsletter.es6
/// <reference path="../../../.vscode.js"/> const MAILING_TEMPLATE_NAME = 'offerlist-nl'; const CHANNEL_NAME = 'offerlist'; const NEWSLETTER_TAG = 'offerlist'; function createEventFile() { return `<event archive="true"> <destination> <channel>${Strings.encodeXml(CHANNEL_NAME)}</channel> </destination> <data> <message>${Strings.encodeXml(MAILING_TEMPLATE_NAME)}</message> <email archiveOutgoingEmails="false" obeyPreferHtml="false" sendBothParts="false" trackingMode="Off"></email> </data> <tag>${Strings.encodeXml(NEWSLETTER_TAG)}</tag> </event>`; } export function run() { UM.println('Preparing newsletter...'); const eventFile = createEventFile(); UM.newsletterArchive.send(eventFile); } de.pinuts.tutorial.sendNewsletter = run;
/// <reference path="../../../.vscode.js"/> function createEventFile(channelName, mailingTemplateId, content) { return `<event archive="true"> <destination> <channel>${channelName}</channel> </destination> <global special="content" trim="true"> ${Strings.encodeXml(content)} </global> <data> <message>${mailingTemplateId}</message> <email archiveOutgoingEmails="false" obeyPreferHtml="false" sendBothParts="false" trackingMode="Off"></email> </data> <tag>${NEWSLETTER_TAG}</tag> </event>`; } function renderOfferList(offers) { return `<ul>${offers.map(renderOffer).join('')}</ul>`; } function renderOffer(offer) { const companyPlace = []; if (offer.company) companyPlace.push(Strings.encodeXml(offer.company)); if (offer.city) companyPlace.push(Strings.encodeXml(offer.city)); return ( `<li style="margin-bottom: 8px"> <strong>${Strings.encodeXml(offer.title)}</strong><br/> ${companyPlace.join(', ')} </li>` ); } export function run() { const channelName = NEWSLETTER_LIST_NAME_PREFIX + portal; const mailingTemplateId = MAILING_TEMPLATE_ID_PREFIX + portal; const offers = JobOffer.list({ status: 'p', portal, orderBy: 'jobofferFirstPublishedAt desc', max: 35, publishedAfter: getLastSendDate() }); if (offers.length > 0) { UM.println(`Bereite Newsletter für Portal '${portal}' vor: ${offers.length} Angebote.`); const content = renderOfferList(offers); const eventFile = createEventFile(channelName, mailingTemplateId, content); UM.newsletterArchive.send(eventFile); } else { UM.println(`Keine Angebote in Portal '${portal}'.`); } }
RenderEntryCallback:
/// <reference path="../../../.vscode.js"/> RenderEntryCallback.prototype.nvRenderEncryptAgtnr = function() { const gaEntry = getBeraterForEntry(this.entry); if (gaEntry) { this.value = `agNr=${encodeURIComponent(gaEntry.get('encryptAgtnr'))}`; } else { this.value = `agNr=${encodeURIComponent(nvConfig.generalagenturen.fallback.encryptAgtnr)}`; } return true; }