How to accès HTML data-attribute with Twig? - twig

Not sure if this is possible, but I've a link with data-attributes 'data-form-recipient' set by Json objects :
<a class="callback-form" href="#location-form" id="contact-us-recipient" data-form-recipient="${myCustomLayers.properties.locationRecipient}">
When trying to get the data from this with JS, It looks all good and gives me the email addresses I want ->
var elem = document.getElementById('contact-us-recipient');
var recipient= elem.getAttribute('data-form-recipient');
console.log(recipient)
Thing is, I need to access it with Twig because this is for a Freeform dynamicNotification (Craft 3), in this context :
{% set form = craft.freeform.form("contactLocation", {
dynamicNotification: { recipients: [
recipient
], template: "locationContactTmp" }
}) %}
Where 'recipient' must be my data-form-recipient value. Is this possible and how?
Thanks

Related

Access an API from Angular

I'm trying to use an API for the first time. Here is how I currently call it :
url = 'https://data.economie.gouv.fr/api/records/1.0/search/?dataset=prix-carburants-fichier-instantane-test-ods-copie&q=aire+sur+l%27adour&lang=fr&facet=id&facet=adresse&facet=ville&facet=prix_maj&facet=prix_nom&facet=com_arm_name&facet=epci_name&facet=dep_name&facet=reg_name&facet=services_service&facet=horaires_automate_24_24&refine.ville=Aire-sur-l%27Adour';
datas = [];
constructor(private http: HttpClient){
this.http.get(this.url).toPromise().then((data: any) => {
this.datas = data
})
}
And HTML :
<pre class="text-white">
{{ datas | json }}
</pre>
The result shows a JSON like this :
Now, how do I access it? I already tried things like :
let data of datas :
data.records
data[0][records]
etc
Here an example, where json property rappresents your entire object:
<span *ngFor="let element of json.records">
{{element.datasetid }}
{{element.geometry }}
{{element.recordid }}
</span>
Here, Please try to create a new method and use async/await.
Create a new method something like this -
public async getData()
{
await this.http.get(this.URL)
.toPromise()
.then(response => this.datas = response['records'])
.catch(err => { console.log ('error');
});
}
Now, You can call this method from your constructor something like this -
constructor(private http: HttpClient) {
this.getData()
}
Now, You should use *ngFor directive to iterate over the datas as it is an array so you can use this data to develop HTML.
<div *ngFor="let data of datas">
{{data?.fields?.id}}
</div>
In this way, you can use this .
let me know if you need any further help on this .
please find the working link of stackblitz- https://stackblitz.com/edit/angular-dukmlc?file=src/app/app.component.ts
Thank you.

How to set a condition in a setHTML block ? (Mapbox popup)

I'm using mapbox-gl-js on a craftcms website.
This is a script block inside a Twig template.
I'm rendering markers with data via a geoJSON with some properties ->
"properties": {
...
"phoneNumber": locationPhone[k],
"faxNumber": locationFax[k],
...
}
On click, markers displays an Info-box with some data from the geoJSON via setHTML
new mapboxgl.Popup()
.setHTML(`
...
<li class="phoneNumber">
<span class="green">Tel.</span> <span class="display-phone">${myCustomLayers.properties.phoneNumber}</span>
</li>
So at this point, we have (php?) variables in a setHTML in a script tag in a Twig template.
How could I set a condition around
<li class="phoneNumber">
</li>
so this 'li' would only be displayed if locationPhone[k] or ${myCustomLayers.properties.phoneNumber} is set ?
I've gone so far with limited knowledge, I fear I've done it wrong and can't check for this property now.
Edit : If anybody needs this, those variables provided by ARCGIS are geoJson objects, they can be accessed like this :
if (myCustomLayers.properties.faxNumber === undefined) {
document.getElementsByClassName("faxNumber")[0].style.display = "none";
}
if (myCustomLayers.properties.phoneNumber === undefined) {
document.getElementsByClassName("phoneNumber")[0].style.display = "none";
}
console.log(myCustomLayers.properties.phoneNumber)
Finally sorted it out. Thanks

Node JS: given a html string, how can I get the content inside of all <script> tags, manipulate and replace it?

Overview:
I am working on a project that has dozens of .Liquid (Shopify) snippets with <script> tags inside of them containing JS code.
They're similar to HTML, they look something like this:
{% assign variable = 'test' %}
<p>hey {{variable}}</p>
<script>console.log("hey")</script>
{% schema %}
{
...json stuff
}
{% endschema %}
Issue:
Basically what I wanna do is get the content inside <script>, manipulate it and replace with the new manipulated one.
I managed to do this using cheerio, but it ends up messing up the Liquid variables since it doesn't recognize them.
My previous code was looking something like this:
let html = cheerio.load(code, { _useHtmlParser2: true });
const { data: js } = html("script").get()[0].children[0];
html("script").get()[0].children[0].data = await minifyJS(js);
const result = html.html();
Expected Behavior:
I need to:
Find all script tags in a HTML string;
Get the code inside of the <script> tag;
Manipulate this code (minify, essentially);
Replace it with the now minified code.
I am trying to avoid using regex, but I can't foresee any other solutions.
Any suggestion is greatly appreciated.
Thank you!
To get the content inside tags you can use Regular Expressions
<script(.|\n)*?<\/script>
This is just the regex
let str = <Whatever string or data you want to extract script tags>;
let result = let result = str.match(/<script(.|\n)*?<\/script>
/g);
console.log(result);
in result you will get the content inside the script tag

Djoser override activation email with template

I've been scouring for more information about how to do this, but there seems to be little to no documentation help.
Essentially want I want to do is make a new template for the activation email so the link can start with localhost:3000 instead of localhost:8000 (I'm using Vue for the frontend post request that's why)
I managed to find this: https://github.com/sunscrapers/djoser/blob/master/djoser/templates/email/activation.html
but when I added it to my own project, the default Djoser template is still being used.
This is how my settings.py looks like:
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
My activation URL which works if the 8000 is replaced by 3000 manually:
'ACTIVATION_URL': 'registration/activate/{uid}/{token}',
templates/email/activation.html:
{% block subject %}
{% blocktrans %}Account activation on {{ site_name }}{% endblocktrans %}
{% endblock subject %}
{% block text_body %}
{% blocktrans %}You're receiving this email becaus!!!!!!e you need to finish activation process on {{ site_name }}.{% endblocktrans %}
{% trans "Please go to the following page to activate account:" %}
{{ http }}://{{ localhost:3000 }}/{{ {% url 'registration/activate' uidb64=uid token=token %} }}
{% trans "Thanks for using our site!" %}
I suppose you need to override email.ActivationEmail, for example to core/email.py
from djoser import email
class ActivationEmail(email.ActivationEmail):
template_name = 'email/activation.html'
and add it to your settings.py
DJOSER = {
'EMAIL': {
'activation': 'core.email.ActivationEmail'
}
}
Here are emails which can be overwritten link
You can configure the DOMAIN and SITE_NAME in the settings.py file instead of changing the template.
Just put DOMAIN = ('localhost:3000') and SITE_NAME = ('YOUR_SITE_NAME')
DOMAIN = ('localhost:3000')
SITE_NAME = ('YOUR_SITE_NAME')
DJOSER = {
...
}
Source: https://stackoverflow.com/a/62586798/6568539 (I found that we don't need to use "config" as mentioned in this answer)
Without changing the Djoser email classes and settings.py, You can override the html templates in your project's template directory using the concepts here
You just simply have to create a new folder named email in your 'templates' folder and in it create html files with the exact names for the email templates that you would want to customize/override.
For example if you want to customize the password reset email, your custom file path should resemble this :
projectName/templates/email/password_reset.html
Here is a full list of all the Djoser email templates that you can customize
I found this closed thread and it did do the job of allowing me to render out a custom template. Might want to check this
the answer from Pavlo Naumenko works for me too so thanks a lot. But just a small note: I have to change the name of the file (I couldn't use "activation.html" on my own template). If I use it, django keeps sending the default template. Don't know why.
In case someone happens that too. I was using django 3.2.3 with djoser 2.1.0
it's working! I've just changed activation.html file in
~/.local/lib/python3.5/site-packages/djoser/templates/email
without any other changes

Twig include with rerender

I want to include some template and append on button click (by js), and I need each included template to have a unique id.
Here is the logic where I appending the templates:
<button type="submit" id="addTranslationFields">Add translations</button>
// and js
$('#addTranslationFields').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
let part = `{% include 'translationPart.twig' with {'languages': languages,}%}`;
$('.table tbody').append(part);
});
Here is the how I generate uuid in the translationPart.twig
{% set uuid = uuid() %}
{{ uuid }}
The issue is that UUID is the same for all of the created templates. I understand why it's happening, it's b-z twig generated server-side and at the moment of generation it sees only one include. But is there some option to rerender included template for each new included copy? Or maybe some other way to set different UUIDs for each of the included templates.
Updated
uuid() is a custom twig function
$twig->addFunction(
new TwigFunction(
'uuid',
static function(): string {
return Uuid::uuid4()->toString();
}
)
);
You can achieve this via ajax calls, or string replacement.
String replacement
Twig template (translationPart.twig)
{% set uuid = '#_SOME_STRING_TO_REPLACE_#' %}
{{ uuid }}
Javascript
<button type="submit" id="addTranslationFields">Add translations</button>
// and js
$('#addTranslationFields').on('click', function (event) {
event.preventDefault();
event.stopPropagation();
let generatedUuid = generateUuidByJavascript();
let part = `{% include 'translationPart.twig' with {'languages': languages,}%}`.replace('#_SOME_STRING_TO_REPLACE_#', generatedUuid);
$('.table tbody').append(part);
});
Uuidjs can be used for generating uuid.

Resources