variable in html code block in visual editor template - mailgun

good day,
I've created a template using the visual editor and have included {{variables}} which I pass through X-Mailgun-Template-Variables header when I call the api and the email renders fine.
But those variables in html blocks, such as the below, do not. Is this expected?
<div>
{{body}}
</div>
The block will not render at all since {{body}} is the only text in it.
I would expect to print on the email the contents of the body variable

Related

Using customGPlusSignIn with data-onsuccess method instead of onclick

I am trying to change the file path of my website after having the user sign in.
Here is my body html code
<body>
<div id="map"></div>
<div id="loginmain">
<div id="center">
<div id="login-center">
<img src="Assets/google.svg">
<a id="customBtn" class="customGPlusSignIn" onclick="document.location='index.html'">Sign In</a>
<script>startApp();</script>
</div>
<p id="help-text">Sign in with your school Google account</p>
</div>
</body>
The intention of the onclick method is to call a separate html page, after the user has successfully signed in to Google. However, using onclick would change the file path regardless of the Google Sign in.
I have tried using data-onsuccess method, however it seems to be a method only for class = "g-signin2".
Instead, I am using class="customGPlusSignIn", and I'm not particularly sure how to change the file path after ensuring that the user has successfully signed in.
For context, the function startApp() is copied over from Google's sign in docs, from the bottommost code cell.
Could anyone help me with this? Thanks

Inner renderings not displaying

In a page, I have a rendering with a placeholder, Offcanvas.cshtml
<div data-ads-offcanvas-id="#Model.Id" class="ads-offcanvas #Html.GetCssStyles()">
#{
<a data-ads-offcanvas-trigger-id="#Model.Id" class="ads-close-button" href="#0">X</a>
#Html.Sitecore().Placeholder(LayoutHelper.GetPlaceholder(Placeholders.AccordionSection, Model.Id))
}
and inside that rendering, I plan to put another rendering with a placeholder named Modal.cshtml
<div data-ads-modal-container="#Model.Id" class="ads-modal-container">
<div class="ads-modal-dialog">
<div class="ads-close-box">
<a data-ads-modal-id="#Model.Id" href="#0">X</a>
</div>
<div class="ads-modal-content">
#Html.Sitecore().Placeholder(LayoutHelper.GetPlaceholder(Placeholders.AccordionSection, Model.Id))
</div>
</div>
So it looks like:
-Offcanvas
+-Modal
++-Text content
When I put text content inside the Modal rendering, the content is not rendered. I'm guessing that it only renders that first few renderings and fail to do so when the renderings became highly nested.
Is there a solution to render components to the very-most child?
Thanks guys!
EDIT:
Here's the code for GetPlaceholder:
public static string GetPlaceholder(string name, Guid id)
{
return $"{name}_{id}";
}
Dynamic placeholders are a bit more complicated than generating a unique placeholder key. The generated key still needs to resolve back to a real placeholder that is defined in Sitecore.
Check out the Integrated Dynamic Placeholder module.
This will provide an Html helper similar to your current implementation:
#Html.Sitecore().DynamicPlaceholder("[Placeholder Name]")

WYSIWYG editor pastes html tags in output textfield

I use this redactor for admin site django-wysiwyg-redactor
But when I enter some text, it pastes it with html tags. When discovering my source code, I noticed that html code that is responsible for my input data, is placed in quotes.
I think you have to use "safe", the built-in template filter to render the html properly in your template. Example:
{{ myTextField|safe }}
Safe in django docs

Template Contexts not recognized from external file (Django)

So, I've been editing a website and have many JavaScript functions that utilize the Contexts that the views.py file passes to the page. Until now, these functions have been contained in the base.html file and so have been loaded onto every page directly. However, to make things cleaner, I copy and pasted all the functions to an external .js file. Now, rather than use the contexts, the functions consider them to be literal strings.
Example:
$('#title').text('{{ event.name }}');
The above line will actually set the text of the element to say "{{ event.name }}" rather than the name of the event. Any ideas on how to fix this? I really don't want to keep these functions in the base file where they can be seen by anyone who inspects the page source.
It doesn't matter if you put your javascript functions in an external file or in your base.html it would still get exposed to the user. Only a minification of the file would actually help to trick the user from seeing the actual values but with javascript all your code is public.
Why you're having this problem is because when you rendered the javascript inline (in your base.html) you had access to the template context.
This is no longer the case and the Django template engine doesn't interpolate your {{ event.name }} anymore.
The problem you're facing as well is a good one. You should never mix and match javascript with Djangos template language or any template language for that matter and the only way of fixing it is to
a) start pulling the values from the DOM ie. render a proper DOM
b) to start to fetch the values from the server, traditionally using AJAX.
And the smallest example that I can muster at the moment is below:
Your view:
def my_django_view(request):
return HttpResponse(json.dumps({'meaningoflife':42}), mimetype='application/json')
Your HTML
<input type="hidden" id="myMeaning" value="{{ meaningoflife }}" />
Your javascript
var meaning = document.querySelector('#myMeaning').value;
alert(meaning); //should alert 42.
In your view you return some form of render_to_response which takes a template argument and a context argument. What the render_to_response function does is read your template, and replace all {{ placeholders }} with the values passed via the context dictionary.
Templates are essentially a complex version of this
"""
<h1>{{ person.name }}</h1>
<p>{{ person.phone_number }}</p>
""".format(person)
The problem is the templating engine does not know files specified by a scripts src attribute is actually a Django template. To fix this don't use the script src attribute. Instead do something like this.
<!--base.html-->
<h1>Site Title</h1>
<p>Some content</p>
<script>
{% include 'jsfile.js' %}
</script>
Using the include statement should do the trick.

How can I make a block of code in a custom tag only run the first time the tag is called?

I'm creating a set of ColdFusion custom tags designed to make reusing certain layout elements easy. I'll be using them in a manner similar to the following:
<cfimport prefix="layout" taglib="commonfunctions/layouttags">
<layout:fadingbox>
This text will fade in and out
</layout:fadingbox>
<layout:stockticker>
This text will scroll across the screen
</layout>
In order for the code these custom tags generates to work, a JavaScript file needs to be linked into the page like so:
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
I'd prefer to include the script from inside the custom tags, instead of making the user include it himself. The issue is that the JavaScript file should only be included once per page. After the first time one of these custom tags is used, I'd like subsequent calls to the same tag on the same page to avoid repeating the <script> tag. It's occurred to me that I could do something like this:
<cfif NOT isDefined("Caller.LayoutTagInitialized")>
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
</cfif>
<cfset Caller.LayoutTagInitialized = 1>
...but it seems inelegant.
I wonder, is there a better way?
How would you implement this?
Edit - Clarification:
In case what I wrote above didn't make sense, here's a more detailed example:
If I have a custom tag like this:
<cfif ThisTag.ExecutionMode EQ "start">
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
<div class="mytag">
<cfelse>
</div>
</cfif>
...and I have CFML markup calling the tag like like this:
<layout:mytag>
One
</layout:mytag>
<layout:mytag>
Two
</layout:mytag>
<layout:mytag>
Three
</layout:mytag>
...I want HTML like the following to be generated:
<!-- Script included only the first time the tag is called -->
<script src="commonfunctions/layouttags/enablingscript.js" type="text/javascript"></script>
<div class="mytag">
One
</div>
<!-- No <script> tag on the second call -->
<div class="mytag">
Two
</div>
<!-- No <script> tag on the third call -->
<div class="mytag">
Three
</div>
Use the Request scope.
Your solution isn't far off.
Sam's right that the executionmode is what you want to use when you're wanting something to come out in the start or end mode of the tag, which is part of what you want.
But then you say you want that script tag put out in the start mode of only the first tag used on the page.
That's where you would use Peter's suggestion of the request scope. Unlike the default (or "variables") scope, the request scope is shared among all custom tags on a given request. You proposed using the caller scope, and that could work, too, unless the caller was another custom tag, in which case the caller scope would only be the local scope in the custom tag. The request scope (which has been around since about CF 4.01) is your best choice.
In that case, your proposed solution was close: in the custom tag, in the start mode, programatically check if you have already created a tracking variable in the request scope when you put the script tag out the first time. If not, put out the script tag and create the tracking variable.
Other than changing your code from using caller to request, I'd also suggest you'd want to put the CFSET inside the IF. No need to execute it again for when the IF test fails.
Custom tags have a built in scope called thistag.
This code will work:
<cfif thisTag.ExecutionMode eq "start">