4
votes

I have an input that holds the code for a coupon. Users can fill in a custom code, but I'd like to give them a default code. I have the following code now:

<input type="text" name="code" value="{{ form.code|default(RANDOM_CODE) }}">

And I want to replace RANDOM_CODE by a random string.

I don't think that is relevant to the question, but form.code contains the original coupon code. I use the same form for editing.

According to Twig docs, it's possible to generate random numbers using random(), or even get a random char from within a string using random('abcdefgh...'), but I'd like to generate a random string with a specific length.

I know that I can do that using at least two approaches:

  1. generating a default random code in the controller and then passing it to the view; or
  2. creating a Twig extension with a function to generate the random string for me.

Knowing that I'm curious if there is a way to generate a random string using only Twig's built-in functions.

4
I think it is possible to create variables with Twig. You could randomize multiple characters, using a loop, by generating a single random character each time and appending. Would this work? - Ismael Miguel
@rnevius, yes. And I said that in my question. - Gustavo Straube
@IsmaelMiguel, it seems that will work. I could use a for loop giving a range, like {% for i in 0..10 %} to create a string with 10 characters in length, for instance. But using this approach I'll need to add a random('abcdefghi...') inside the loop. I was thinking in something more compact, but I'm almost sure it's not possible. - Gustavo Straube
Sounds like you have a plan! - Ismael Miguel
I do this pretty often by simply appending a random number to a prefix. E.g.: {% set code='prefix-' ~ random() %}. Do length by using a range. 10 characters? 'prefix-' is 7, need 3 more... random([100..999]) - random number with 3 digits. - mindfullsilence

4 Answers

13
votes

This code will generate a 10 character password in base64 (A to Z in lower and uppercase, 0 to 9, and dash and underscore). This also makes it url friendly. You can change the parameters to your liking if you like.

{% set randomPassword = [] %}
{% set alpha = 'abcdefghijklmnopqrstuvwxyz' %}
{% set numbers = '0123456789' %}

{% for i in 1..10 %}
    {% set randomCharacter = random(alpha ~ alpha|upper ~ numbers ~ '-_') %}
    {% set randomPassword = randomPassword|merge([randomCharacter]) %}
{% endfor %}
{% set randomPassword = randomPassword|join %}


{{ randomPassword }}
1
votes

Agreeing with @Fluffy that you shouldn't do it in twig : your coupon code being a data, that will be handled in php, it must be generated in php.

I however got a use case for generating an unique id directly in the template : when only the template is concerned.

I got a form with inputs. I need an id on my inputs, but only to refer them from inside the same template, in the "for" attribute of a label.

As it was generated in a loop, I went up with a simple :

{% set domid='msg' ~ loop.index %}
1
votes

Twig Native:

{{ random() }}

Visit below link for twig docs. [Check This]: https://twig.symfony.com/doc/3.x/functions/random.html

0
votes

What about this "unique id":

{% set uid = "now"|date('Uv') %}

Use a unix timestamp U with miliseconds v if u iteratively generate them u might add more entropy by concatinating a random()