Mailchimp/Mandrill and Handlebars changing preview text - handlebars.js

I'm working with MailChimps Mandrill to send transnational emails with handlebars. The whole setup is done and the emails send absolutely fine - but when they arrive they still have the default Mailchimp template string for the preview text that look like:
|*MC_PREVIEW*|
Is anyone aware of a way to remove this from showing or change it? Currently I have to go into the code of the email in Mandrill and remove the block of code myself - wondering if there is a way to do that from Mailchimps end at all as it's a bit tedious every time an email template is updated and exported back to Mandrill to go in and remove it again.
Thanks in advance!

I've had this issue, and what helped me was first changing the Mandrill default merge tags to Handlebars, then re-exporting the templates from Mailchimp back to Mandrill.
This converts all *|Mailchimp|* style merge tags in the code of the email into {{handlebars}}-style.
Important Edit:
If your Mailchimp templates are using handlebars to define the merge tags, these will get escaped like so:
\{{mergeTag}}
You will either have to manually delete these backslashes to get the tags to work again, OR reformat the merge tags in Mailchimp to be in the *|MAILCHIMP|* style before exporting.
If you choose the latter, when converting a camelCase merge tag to Mailchimp style, just put it in all caps.
E.g. {{mergeTag}} becomes *|MERGETAG|*

We encountered the same issue and wrote a little lambda http endoint that we can trigger via slack integration to fix all our mandrill templates:
const mailchimpFactory = require('#mailchimp/mailchimp_transactional');
const mailchimp = mailchimpFactory(process.env.MAILCHIMP_API_KEY);
function fixTemplate({ name, code }) {
const regex = /\*\|MC_PREVIEW_TEXT\|\*/ig; // regexr.com/69390
const fixedBody = code.replace(regex, '');
console.log(`Updating ${name}`);
return mailchimp.templates.update({
name,
code: fixedBody,
});
}
// removes all mailchimp preview merge variables from all
// templates in mandrill (since we're using handlebars)
async function fixAllTemplates(event) {
const templates = await mailchimp.templates.list();
await Promise.all(templates.map(fixTemplate));
const templateList = templates.map(({ name }) => `\n> ${name}`).join('');
const msg = `*Mandrill Template Fixer:* Updated ${templates.length} templates. ${templateList}`;
console.log(msg);
return { statusCode: 200, body: msg };
}
module.exports = { fixAllTemplates };

Related

nextjs links without strings

Im new to nextjs, and Im checking if it will be good for the app that will have pretty complex and messy internal navigation. Just checked their documentation and I see that they recommend usage
of Link component like this <Link href="/your_path">Path</Link>. A bit scary is that I have to provide 'your_path' as a string so every time i change page file name I have to manually update code that redirects to this page. Is there any solution that allows me to define routing on my own so I can write something like (pseudocode)
routes = [
...
{
page : 'page_name',
path : 'path_to_page'
}
...
]
So instead of using string I can do <Link href="{route.path}">Path</Link> or Im condemned to use this file-system based router with all consequences?
The simple answer is yes!
When you want to change a user route in NextJs you have 2 options,
The first is with the <Link> Element that you can specify a href to where it directs.
And you also have a useRouter hook for more complex routing for example if the user does an action that requires moving him into a different route you can do it internally in your handlers.
For more information about useRouter hook.
What I usually do is storing my routes in an object
const ROUTES = {
HOME: "/",
ABOUT: "/about"
}
and wherever you call routes you just use the object so F.E
With Link tag
<Link href={ROUTES.ABOUT}>ABOUT PAGE</Link>`
with useRouter hook
// Inside a React Component
const router = useRouter();
const handleNavigateToAbout = () => {
router.push(ROUTES.ABOUT);
}
return (
// SOME JSX
<button onClick={handleNavigateToAbout}> Go to about page! </button>
)

SvelteKit: Pass Data From +Layout.svelte To +page.svelte SPA (static) application

I'm struggling with the latest version of SvelteKit, the docs available only works with SSR, and I'm developing SPA app (static page), so, what is the way to pass data from my +layout.svelte to +page.svelte?.
The documentation says that with load function from page.js (I've already set the SSR=false, and I understood that page.js is for SSR), but that doesn't work with SPA, and if I have the load function from the layout it's seems not work.
Aditionaly I want to trigger a function from my +page.svelte that is in the layout page.
Any ideas?
here my try
//+layout.svelte
<script>
export function load() {
return {
data: { title: 'default title' }
};
}
export let data;
</script>
//+page.svelte
<script>
export let data;
console.log(data.title); //undefined
</script>
the docs says that don't use: <script context="module">, and I don't want to use the store becouse I think that sholud be a better way.
Load functions belong in the accompanying files +layout.js/ts, not on the page. They also do not return a property data, everything returned is the data. See the docs.
If SSR is disabled, you can event return a store that could be modified from the page.
To get a store from the data so it can be used with $-syntax, the data property can be destructured on the page:
export let data;
$: ({ title } = data);
You could also create a store and set it as a context in the layout. Pages then can get said context and interact with it. This allows two-way interaction.
Using a store is necessary if the contents require reactivity (i.e. are changed) and the page or layout needs to update.

at Wordpress Gravity Form plugin, how to customize the File Upload UI?

everyone.
The gravity form plugin is using standard File Input Element.
I can make it looks like the custom UI by adding custom css into File label tag and using the gform_field_content filter.
after that, how can I display the imputed file name like the following status?
as you see, the imputed filename Group 386.svg is showing.
how can I do this? or is there any other good way?
Regards
I found the solution myself.
I added the custom style to label by following this guide (W3 Custom File Upload
) https://www.w3schools.com/bootstrap4/bootstrap_forms_custom.asp
after that, I added the js event to display the selected filename like the following.
// contat form, join us form
// customize file upload
jQuery(function () {
jQuery(document).on('gform_post_render', function () {
jQuery('.contact-form__form input[type=file], .join-us__form input[type=file]').on('change', function () {
const fileName = jQuery(this).val().split('\\').pop()
jQuery('label', jQuery(this).parent().parent()).html(fileName)
})
})
})

createPages in Gatsby issues ; duplications and unrendered content

I've had a few errors trying to render single blog posts.
I tried using the page template with /post/{post_name} and I was getting this error:
warn Non-deterministic routing danger: Attempting to create page: "/blog/", but
page "/blog" already exists
This could lead to non-deterministic routing behavior
I tried again with /blog/{post_name}.
I now have both routes, which I'm not sure how to clean up; but more importantly, on those pages, nothing renders, even though there should be an h1 with it's innerhtml set to the node.title and likewise a div for the content.
I've uploaded my config and components to https://github.com/zackrosegithub/gatsby so you can have a look.
Not sure how to fix
I just want to see my content rendered on the screen.
Developer tools don't seem to help when there's no content rendered as I can't find anything to inspect to try to access it another way.
Thank you for your help
Your approach is partially correct. You are using a promise-based approach but when using then() you are already settling and partially resolving it so you don't need to use the callback of resolve(), which may be causing a duplication of the promise function so try removing it.
Additionally, you may want to use a more friendly approach using async/await functions. Something like:
exports.createPages = async ({ graphql, actions, reporter }) => {
const yourQuery= await graphql(
`
{
allWordpressPost {
edges{
node{
id
title
slug
excerpt
content
}
}
}
}
`
if (yourQuery.errors) {
reporter.panicOnBuild(`Error while running GraphQL query.`);
return;
}
const postTemplate = path.resolve("./src/templates/post.js")
_.each(yourQuery.data.allWordpressPost.edges, edge => {
createPage({
path: `/post/${edge.node.slug}/`,
component: slash(postTemplate),
context: edge.node,
})
})
})
// and so on for the rest of the queries
};
In addition, place a console.log(pageContext) in your postTemplate to get what's reaching that point and name the template as:
const Post = ({pageContext}) => {
console.log("your pageContext is", pageContext);
return <div>
<h1>
{pageContext.title}
</h1>
</div>
}
export default Post;

Adding Firebase VAR to website

I setup and account at http://feedthefire.in and on Firebase dot com - to manage feeds I would liek to display on my site. I set everything up and the feeds get pulled into Firebase just like it should, now its time to add it to a web page...nothing, can't get the feeds to pull in from Firebase. I added the firebase.js reference in the header and in the body I placed
<script type="text/javascript">
var ref = new Firebase"'https://aodf.firebaseio.com");
ref.child("meta").once("value", function(snapshot) {
$("#e-title").html(snapshot.val().description);
});
ref.child("articles").limit(3).on("child_added", function(snapshot) {
var article = snapshot.val();
var link = $("<a>", {
"href": article.link,
"target": "_blank"
});
$("#e-list").append($("<li>").append(link.html(article.title)));
});
when you go to http://sandbox.studiorooster.com/ao I should see a list of feeds, but I don't, so I know I am supposed to place something else in the code; I think :)
There are a number of problems in what you posted above, each of which is explained below:
Syntax error on line #2: var ref = new Firebase("https://aodf.firebaseio.com");
You're loading a description on lines #3-5, but never rendering it, because there is no element with id e-title in the page you linked to. Trying adding <h2 id="e-title"></h2> to your template.
Similarly, you are loading a number of articles on lines #6-13, and trying to append each of these items to a list with id e-list, which also does not exist in your template. Try adding <ul id="e-list"></ul> to your template.
Hope that helps!

Resources