How can I check that a string is valid email address in twig template ?
For example, in this code:
{% set usernameType = (#Check user.username is email#) ? 'email' : 'number' %}
I need if user.username is a valid email address, usernameType set as email, otherwise set as number
Twig is executed at the server side so if you want to validate email you should use javascript at client side like: https://stackoverflow.com/a/46181/4450882
in the server side you should use php or python to make this verification.
php validation: https://www.php.net/manual/fr/filter.examples.validation.php
python validation: https://pypi.org/project/validate_email/
Related
So I am trying to sort out variable scope. Below is a simple snippet of code:
const params = {
versions: versions,
user: user,
statsParams: statsParams,
csrfToken: csurf.createToken(req),
};
res.render("server/edit", params);
return;
Now the values that are in the params object are available in the ejs page for use. What I am seeing is that other variables that precede this code block also seem to be available in the ejs file as well not just the ones passed via the param object. Is this expected behavior? I have looked on the ejs website and it doesn't speak of variable scope.
Brad
What you are doing with your code is rendering the page using ejs and passing the params object to the page. By passing it to the page you can render the page with access to the variables you passed in using the following tags : <%= variable =>
In terms of scope, you have now rendered the page to have access to all the variables you have passed in under the name params during the operation : res.render("server/edit", params);
If you have passed other variables through api calls to your backend you will also be able to access them in their according scope, but unless you include other variables to be passed as parameters you will not be able to access other variables from your backend.
Example :
--> userController.js
var outOfScope = True;
const params = {
versions: versions,
user: user,
statsParams: statsParams,
csrfToken: csurf.createToken(req),
};
res.render("index", params);
return;
--> index.html
...
<h1>Variable</h1>
<p><%= params.user %></p>
...
This will not work
...
<h1>Variable</h1>
<p><%= outOfScope %></p>
...
If you still have issues regarding access to variables you haven't passed it is possible you may have included them from another file by accident (ex. a header that is included).
I hope this helps, but if you are having trouble with specific variables please include them in your question as well as how you are accessing them.
I'm doing some URL verification between a Shopify site and my app. On Shopify, in a .liquid file, I'm creating an HMAC value using Shopify's built in hmac_sha256 string filter. I'm using a secret key and a Twitch user ID which I've stored in a customer tag.
The hash value is passed as a query parameter to my app, which uses the crypto module in node.js to generate a hash and compare it with the hash from the url.
Things get strange here: In the .liquid file, when I type the Twitch ID directly into the string filter, the hash value generated by the .liquid file is the same value my app generates, and everything looks good:
{{ "12345678" | hmac_sha256: "secret_key" }}
However, when I pass the same Twitch ID as a variable into the string filter, the hash value the liquid file generates is different than the first time:
{{ twitchId | hmac_sha256: "secret_key" }}
I've already tried removing whitespace and newline characters from the Twitch ID variable just in case there were any. I don't even have a guess as to what the problem could be. Maybe the variable (which is a string) is encoded differently than when I type it in directly?
For reference, the javascript code checking for matching hashes:
// Get query string params:
const { hash, twitchId } = req.query;
console.log('Twitch ID in query: ' + twitchId);
// Verify user
const generatedUserHash = crypto
.createHmac('sha256', userVerifySecret)
.update(twitchId)
.digest('hex');
console.log('Passed hash: ' + hash + ' Generated hash: ' + generatedUserHash);
if (generatedUserHash == hash) {
return true;
} else {
return false;
}
You need to show how you are assigning the ID to the variable. Without seeing that, there is no way to validate your question.
I did a quick test, and proved I get the same HMAC with a string and a variable, so it must be that you are doing something weird in your assignment:
<h1>{{ "12345678" | hmac_sha256: "secret_key" }}</h1>
{% capture fizz %}12345678{% endcapture%}
<h1>{{ fizz | hmac_sha256: "secret_key"}}</h1>
Produces:
fcfebc0d424982ce8c7a986264beb0d4b1de44507501451e142236404e5b9778
fcfebc0d424982ce8c7a986264beb0d4b1de44507501451e142236404e5b9778
Turns out my variable twitchId was getting instantiated after I was trying to use it in the sha256 filter. I was instantiating it in my theme.liquid file, and I was trying to access it in a liquid file in my app (the request from the Shopify site is responded to with a liquid file).
I guess I wrongly assumed the theme.liquid file is loaded before the file in my response to Shopify. I assumed this because javascript variables I instantiate in my theme.liquid file are available in my response liquid file (I think this has something to do with liquid variables being created server-side and javascript variables being created client-side).
I am now instantiating the twitchId variable in my response liquid file. So that solved it.
I am using the silex framework for my project. I am using the SecurityServiceProvider with a custom user implementation. The login/logout works and I am able to view the correct user information in the symfony profiler (stored as a session attribute). Now I am trying to add the custom user information to the twig environment so that is is accessible from the templates. Here is what I've come up with:
$app['twig'] = $app->share($app->extend('twig', function($twig, $app) {
$token = $app['security']->getToken();
$userInfo = null;
if (null !== $token) {
$userInfo = $token->getUser()->getTwigInfo();
}
$twig->addGlobal('userinfo', $userInfo);
return $twig;
}));
I am trying to extend the environment and it works, however the user information seems to be processed later and my userinfo attribute is always null. I guess that I have to somehow extend the twig environment later but do not know exactly how to do that. Can someone help me?
Silex gives you access to the app instance directly from Twig.
So you could do:
{{ app.security.token ? app.security.token.user.twigInfo : null }}
or
{% set userinfo = app.security.token ? app.security.token.user.twigInfo : null %}
{{ userinfo }}
If you prefer to handle it within your PHP code, then you can create a new definition
$app['userinfo'] = $app->share(function($app) {
$token = $app['security']->getToken();
return (null !== $token) ? $token->getUser()->getTwigInfo() : null;
}));
Then in your Twig template
{{ app.userinfo }}
I wish to have a template render some data which needs to be passed back to the caller of render. For example, I am using a template to generate emails, for which I need a subject as well as the body. I would like to do something like this:
app.render( 'email', function(err,html) {
subject = ?get from template somehow?
postEmail( subject, html, user_addr );
});
That is, I wish for the template to decide what should appear in the subject (preferably without creating another template just for the subject line).
Not sure if you figured this out yet, but you can send back information from Jade by altering the value of the arguments.
email.jade:
- subject.text = "Hi " + user + ", welcome to the site.";
| Subject: #{subject.text}
app.js:
args = { user: 'Test User', subject: { text: '' } };
app.render( 'email', args, function(err,html) {
subject = args.subject.text;
postEmail( subject, html, user_addr );
});
It has to be a nested object (i.e. subject.text instead of simply subject), otherwise you won't get the modified data. Although, if you call templates created with jade.compile() directly, then the nesting appears to be unnecessary. I think express must make a shallow copy of the arguments before sending it to the view engine.
I'm having some strange issues with PHPMailer. I'm trying to send some content which I generate with PHP in HTML and plain text, but the body gets truncated. What's even stranger is that this happens only to the email I generate, if I put in there some generic content in much greater length, it gets sent properly. I must also mention, I did echo the content of both $content and $nohtmlcontent variables and everything is there like it should be, but when I receive email into my mailbox, it's truncated.
My PHP code for creating plain text and HTML email body:
$content="<BODY bgColor=\"#ffffff\"><FONT face=\"Verdana\" size=\"2\">";
$content.="Hello $name.<br /><br />Administrator of $url has created a new account for you.<br /><br />Your new account details:<br />";
$content.=$message."<br /><br />";
$content.="If you see something wrong, please reply with correct details and we will update your account.<br /><br />";
$content.="Have a nice day,<br />$url</FONT></FONT></BODY>";
$nohtmlcontent="Hello $name.\n\nAdministrator of $url has created a new account for you.\n\nYour new account details:\n\n";
$nohtmlcontent.=$usrEmail."\n\n";
$nohtmlcontent.="If you see something wrong, please reply with correct details and we will update your account.\n\n";
$nohtmlcontent.="Have a nice day,\n$url";
All variables are populated with proper data.
My PHPMailer code for sending email:
require_once("class.phpmailer.php");
$mail=new PHPMailer(true);
try {
$mail->AddAddress($email);
$mail->SetFrom('admin#example.com', 'example.com');
$mail->CharSet = 'UTF-8';
$mail->Subject = "New account for you";
$mail->IsHTML(true);
$mail->AltBody = $nohtmlcontent;
$mail->Body = $content;
$mail->Send();
return true;
}catch(phpmailerException $e){
trigger_error("PHPMailer failed: ".$e->errorMessage());
return false;
}
Result:
Hello 12 23.
Administrator of admin.localhost.dev has created a new account for you.
Your new account details:
Username: user1
Password: 123456
E-Mail Address: info#tourazore.com
Subscription Status: Not Verified (you must verify your email address before you can use your account)
Package: Free (limitations: 1 tour, 5 items)
First Name: 12
Last Name: 23
City 34
Country 45
Your verification link: http://admin.localhost.dev/verify-account/882672636ce2ad8c498f75a9b836ff055aecf573/
If you see something wrong, please reply with correct details and we will update you
Expected result:
Hello 12 23.
Administrator of admin.localhost.dev has created a new account for you.
Your new account details:
Username: user1
Password: 123456
E-Mail Address: info#tourazore.com
Subscription Status: Not Verified (you must verify your email address before you can use your account)
Package: Free (limitations: 1 tour, 5 items)
First Name: 12
Last Name: 23
City 34
Country 45
Your verification link: http://admin.localhost.dev/verify-account/882672636ce2ad8c498f75a9b836ff055aecf573/
If you see something wrong, please reply with correct details and we will update your account.
Have a nice day,
admin.localhost.dev
Please notice the extra content in the end.
I have also tried using PHP's function mail() to send the same content, it also gets truncated.
Any ideas?
SOLUTION: The PHP code generated really long line, after adding a few newline characters, the complete content got through.
Also this may not be related but you're using Body and not MsgHTML
$mail->Body = $content;
But it looks like your using HTML expressions in your content.
I'm fairly new to this but from what I've read to use HTML in PHPMailer you should use
$mail->MsgHTML = $content;
Although your text looks likes it is displaying fine and you solved your problem. But I thought I'd share incase it helps.
Some useful info here
https://phpbestpractices.org/
(scroll down to email info)
and here:
https://github.com/PHPMailer/PHPMailer