Mustache variable for language preference in deepviews? - branch.io

My company is running an email campaign for app downloads using branch.io. As users may open a given link on a desktop OR on their phone we need to support both cases.
We've implemented a branch "Deepview" because we love the ease of the text-to-download feature. The problem is, there doesn't seem any way to provide a localized version of this view, and we support many different languages.
Because I can't run scripts in the custom deep view (branch.io strips them out, I assume for security reasons), and because I don't have access to a language mustache variable, I can't change content by locale.
Is there any way to localize deepviews based on a URL param or (ideally) based on window.navigator.language(s)? If I just had a mustache variable exposed for language_code of the user, everything could work.
Here was my attempt at hacking it in:
.lang-en .phone-number-label:after {
content: "Phone Number";
}
.lang-en .btn-submit-label:after {
content: "Send Me The App";
}
<div class="container lang-en">
<h3 class="phone-number-label"></h3>
<input name="phone" id="phone" placeholder="+1 (123) 123-1234" type="text" class="phone-input"></input>
<button id="phone-submit" type="submit" class="phone-submit">
<span class="btn-submit-label"></span>
</button>
</div>
The 'lang-en' is intended to be generated as follows:
<div class="container lang-{{language_code}}>...</div>
I briefly got this to work by highjacking $og_description from the url:
https://bnc.lt/my-branch-link?$og_description<language_code_provided_as_query_param>
but after awhile, the {{link_data.$og_description}} stopped coming through at all into the mustache template (when passed as a url param). This also is probably not great practice. Let me know if anyone has a solution here, or if branch.io devs are willing to expose this variable in their mustache template data.

I have good news! Branch Deepviews use Handlebars, utilizing this will allow you to set the "Get the App" -- "See this content immediately after install" and other variables with your deep linked values. Let me show you some code and a screenshot from an example that I just built for you.
Code example:
{{#if link_data.cta_text_localized}}{{link_data.cta_text_localized}}{{else}}Get The App{{/if}}
The Handlebars come into play for the "Get the app" Button here:
{{#if link_data.cta_text_localized}}{{link_data.cta_text_localized}}{{else}}Get The App{{/if}}
To spell it out, if the deep link value "cta_text_localized" exists within this link, then use that String for the "Get the App" button, otherwise use "Get the App." You can configure deep link data from the marketing section of your Dashboard, at the bottom of an "add link" dialog, attached screenshot:
Screenshot of my ES customized Deepview, note the altered "Get the App" button:
As you can see, using a liquid tag that grabs text from my deep link value "cta_text_localized" I set the "Get the App" button to a custom String. Using this method you would create a link for every language that you wanted to display, setting your deep link values accordingly, while your template always pulled from the same variable.

Related

How do I mix custom and standard error messages in validations on one form field

I am a beginner with Vuelidate and just completed the Easy Form Validation with Vuelidate video on YouTube. I followed the video carefully and everything seemed to go okay but I've run into a bit of trouble after trying to extend the concepts. I can't find a relevant insight in the Vuelidate docs.
I don't like the default message that appears when the confirm password doesn't match the first password supplied, so I want to provide my own custom message for it but the default messages are fine when the confirm password is not supplied at all or the confirm password is too short. I've written the code as follows and don't see an obvious mistake but when I actually test the code in the browser, I find that it ALWAYS gives me the custom message, even if the required or minLength validations are the ones that are failing. Why is that, and how must I write my code differently to work as intended?
<p>
<input type="password" placeholder="Confirm Password"
v-model="state.password.confirm"/>
<span class="error" v-if="v$.password.confirm.$error">
<span v-if="v$.password.confirm.required | v$.password.confirm.minLength">
{{v$.password.confirm.$errors[0].$message}}
</span>
<span v-else>
{{"Confirm password must match password on previous line"}}
</span>
</span>
</p>
Is it the "or" (|) in the v-if that is the problem? I thought a vertical bar (for "or") or an ampersand (for "and") were allowable in Vue but I may be confusing it with another language. I've just searched for an example containing a vertical bar or ampersand without success; all the examples I found use a single condition but I'm not sure if that's to keep things simple or because v-if can't handle more than one condition.
I'm using Vue3 and VSCode as my IDE.

Must I always use v-html/v-pre for displaying user input? Vue JS

I ran into an issue where Vue threw errors that x wasn't defined if I tried displaying user content such as:
<span><%= field.content %></span>
This is ruby which processes server side, it would output something like: "Hi, it's {{todays_date}} today." which Vue would then process. {{todays_date}} is not intended to be parsed by Vue, but is rather intended as a domain specific language.
I then read up on v-pre and that works to escape the content:
<span v-pre><%= field.content %></span>
However, I now realize that anywhere I'm displaying the user content throughout the entire app could have the same issue. When it breaks, it breaks the entire site.
Note that the ruby syntax is to provide context, but really it could be any database field output that is derived from user input.
What is the best way to handle this? It seems like overkill to use v-pre on every single view where I'm displaying user input.

How to setup a netlify form in Nuxt

When I navigate to a form using vue-router by adding a link with a <router-link> element, the form does not work. When I hit submit I get a 404 response.
However, if I navigate to it using an <a> tag (triggering a page reload) then it works perfectly.
I suspect that this has to do with the page rendering as a SPA and for some reason not loading an important part of the form for Netlify unless the form page is reloaded? Why is this happening and is there an elegant solution to the problem? I could just replace all links to forms with tags but I'm sure that there is a better solution, I just don't understand the problem well enough to find it.
For context, I am using Nuxt. The forms are recognized by Netlify on the backend and can accept submission with the tag link so that is not the problem.
Since you're using Nuxt, you probably should go SSG/full static with target: 'static' (hostable on Netlify-like platforms) or with target: 'server' (hostable on Heroku-like platforms) but at any point, you should have ssr: true (default value). When you do have this, the biggest part is done.
In Nuxt, you should use <nuxt-link> rather than <router-link>, it works exactly the same (takes the same params etc) but it's more specific to Nuxt and SSR/SSG compatible while <router-link> is not. More details here: https://nuxtjs.org/docs/2.x/features/nuxt-components#the-nuxtlink-component
So, with all of this it should already work great. If it's not, I will gladly help you spot the issue if you have a github repo.
An alternative solution can be to use some form without any SSR dependency like Formspree: https://formspree.io/ (works fine with any SPA)
It works great, really simple. But I'd rather invite you to make a proper SSR form since you're using Nuxt.
PS: use <a> tags only for external links aka the ones which do not start with your domain name, nothing else. A follow of this kind of link is like a hard refresh and should be avoided at all costs.
EDIT: how to deploy by cleaning the cache.
EDIT on how to achieve a working form:
<template>
<div>
<form
netlify
action="/"
method="POST"
name="Contact"
>
<input type="hidden" name="form-name" value="Contact" />
<!-- ... -->
</form>
</div>
</template>
As told in the docs:
[...] inject a hidden input named form-name [...] and the hidden form-name input’s value matches the name attribute of form
Working fine. Could add a honeypot to it to make it even more secure!

Work around to POST requirement

I need to be able give users a link to my site with a parameter that will control their experience on the destination page, but, of course, Moqui does not allow parameters to be passed as a GET transaction. What are ways that I can work around that? It needs to be something that can be sent in an email, via sms and audibly.
An error message would be helpful know exactly what you are running into, but it sounds like the constraint to mitigate XSRF attacks.
The error message for this situation explains the issue and the recommended solution: "Cannot run screen transition with actions from non-secure request or with URL parameters for security reasons (they are not encrypted and need to be for data protection and source validation). Change the link this came from to be a form with hidden input fields instead."
You can pass URL parameters to screens to be used in code that prepares data for presentation, but not to transitions for code that processes input. The solution is to use a hidden form with a link or button to submit the form (that can be styled as a link or button or however you want). This is slightly more HTML than a plain hyperlink with URL parameters, but not a lot more and there are examples in various places in the Moqui itself.
If you are using an XML Screen/Form you can use the link element to do this with the #link-type attribute set to "hidden-form" or "hidden-form-link" (which just uses a hyperlink styled widget instead of a button styled one). If the #link-type attribute is set to "auto" (which is the default) it will use a hidden-form automatically if link goes to a transition with actions.
In plain HTML one possible approach looks something like this:
<button type="submit" form="UserGroupMemberList_removeLink_0">Remove</button>
<form method="post" action=".../EditUserGroups/removeGroup" name="UserGroupMemberList_removeLink_0">
<input type="hidden" name="partyId" value="EX_JOHN_DOE">
<input type="hidden" name="userGroupId" value="ADMIN">
</form>
Note that the button element refers to the form to submit, so can be placed anywhere in the HTML file and the form element can be placed at the end or anywhere that is out of the way (to avoid issues with nested forms which are not allowed in HTML).

Change Global Variable onclick/img source update with javascript variable

First off I am completely new to Javascript but I have some HTML/CSS experience. I've been trying to create an html/javascript image gallery for a website; (It would probably be a lot easier to do in PHP but the web coordinator disabled PHP on our server for security reasons).
Anyway What I have is a page showing an Album-list, Album-browser and Photo-viewer in different a div and 2 iframes respectively. I have it set up so that when someone clicks on an album from the album list, a page is opened up in the album browser section (iframe:"browser-frame" showing thumbnails of all the images in the particular album). I've been trying to set it up so that when someone clicks on an image in the album browser the image will appear in the Photo-viewer section (iframe:"viewer-frame" showing the photo itself).
I didn't want the photo's in the viewer-frame to be larger than the set dimensions for the viewer-frame so I created a page for the viewer-frame that puts the image in a div with a class of set dimensions (defined in a stylesheet) as follows:
...<body>
<div class="photoview">
<img id="viewed_image" class="large" src="images/album1/1.jpg" />
</div>
</body>...
I then created a script that updates the image src to a variable:image_to_be_viewed and called it image-changer.js
// JavaScript Document
{
var image_to_be_viewed="images/album1/1.jpg";
document.getElementById("viewed_image").src=image_to_be_viewed;
}
And added a script to the viewer-frame page so it looks like:
...<body>
<div class="photoview">
<img id="viewed_image" class="large" src="images/album1/1.jpg" />
<script src="image-changer.js"></script>
</div>
</body>...
Now I wanted the gallery to work so that in the page loaded in the browser-frame, whenever one clicked on one of the pictures, the value of the global variable 'image_to_be_viewed' would be changed to the source of the clicked image as follows:
<body>
<div class="photobrowse">
<img class="medium" src="images/album1/1.jpg" onClick="image_to_be_viewed='images/album1/1.jpg'"/>
<img class="medium" src="images/album1/2.jpg" onClick="image_to_be_viewed='images/album1/2.jpg'"/>
<img class="medium" src="images/album1/3.jpg" onClick="image_to_be_viewed='images/album1/3.jpg'"/>
</div>
</body>
It doesn't work....
the gallery i'm working on is on http://ptc.tamu.edu/test/gallery_directory/test_gallery.html
everything up to the loading of the selected picture in the viewer frame works (I'm running the onlick event on the default loaded pictures 1,2,3 in the browser-frame page)(default pic's 4 and 5 simply load the image in the iframe but with no way to adjust the size it is too big and gets cut off and i don't want that)
I've been working on for an entire day and I'm sure I'm doing something wrong here but I can't figure out what exactly it is. I have a feeling it has to do with changing the global variable: image_to_be_viewed from the browser-frame page but I wanted to confirm with experts instead of flopping about like a headless fish. I'm going to continue trying to figure this out but i thought maybe having some expert assistance would speed up the process.
What the onclick triggers should be a javascript function call.
e.g. onclick="changeImg('images/album1/1.jpg')"
And the function itself should looks like this
function changeImg (image_to_be_viewed) {
document.getElementById("viewed_image").src = image_to_be_viewed;
}
btw, you probably should learn javascript a little bit more before work on something real. I recommend this book
thank you I got it to work! I figured that the changeImg function was targeting the wrong document/wrong frame and I fixed it by changing the js script to:
function changeImg (image_to_be_viewed) {
window.parent.viewer_frame.document.getElementById("viewed_image").src = image_to_be_viewed;
}