Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python

Dont understand how should i replace part of email in for loop in jinja2/flask macro ?

In this challenge i need to create a macro for use in flask template to replace part of email string with '*'. But i can't figure out how should i do it inside a for loop.

Any tip are appreciated and reference to documentation where I can read about this and solve the challenge by myself.

lunch.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    class User:
        email = None
    user = User()
    user.email = 'test@example.com'
    return render_template('user.html', user=user)
templates/macro.html
{% macro hide_email(user) %}
{% for mail in user.email.split('@') %}

{% endmacro %}

2 Answers

Hi, Dzumret Pelivani !

The way to replace is:

for letter in word:
    letter can become anything  ;)

Does it help?

Thank you for your answer Alexey . I am familiar with loop through letters of a word.

But I don't understand how should i do it in a "macro.html".

In the challenge I have to solve the problem with for loop and a split. How do I transfer code bellow to Jinja2 syntax and macro ? Or is there any other simpler solution that I can not see.

# split the email in two
name, domain = 'test@example.com'.split('@')

# list to hold the new name with '*' 
new_name = list()

for index in range(0, len(name)):
    if index == 0:
        new_name += name[index]
    else:
        new_name += '*'

# join the new_name with rest of address parts and print out
email = ''.join(new_name) + '@' + domain
print(email)

You can transfer it by using {%%} around keywords like for, and {{}} around variables or data what you want to see on page.

Example (using your code):

{% set name, domain = 'test@example.com'.split('@') %} # this is not visible on page
{{ name }} #   would print "test" on the page.

if you want to assign variables you have to use set keyword. But you don't have to assign them. Look:

{{user.email.split('@')[0]}}  # Would print name
{{"@"}} # Would print @
{{user.email.split('@')[1]}}  # Would print domain

Actually this will print full email address to the page!

What you need is: print first letter, print stars for each letter in name except [0], print @ and print domain.

example that prints first letter and stars:

{{user.email[0]}}
{%- for letter in user.email.split('@')[0][1:] -%}
{{'*'}}
{%- endfor -%}

So if email was "test@teamtreehouse.com" it would return t*** to the template.

Add @ and domain and wrap it all to

{% macro hide_email(user) %}
{# HERE #}
{% endmacro %}

PS The reason to use '-' in {%- for ... -%} is to remove whitespaces. jinja2 DOCS

Thanks a lot Alexey. Now i understand more of how Jinja2 syntax works.

And here is solution:

{% macro hide_email(user) %}

{{ user.email[0] }}

{%- for letter in user.email.split('@')[0][1:] -%}
    {{ '*' }}
{%- endfor -%}

{{ user.email[user.email.index('@'):]  }}

{% endmacro  %}

PS. Thanks for {%- -%} whitespace ignore

Cool. This challenge took me a loong time too))

My thanks to Alexey for {%- -%} as well. That was annoying to get over.