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

Tero Lompolo
Tero Lompolo
15,180 Points

Create a macro named hide_email with Flask - no idea how to solve this challenge

Build a Social Network with Flask has this challenge "Create a macro named hide_email. It should take a User as an argument. Print out the email attribute of the User in the following format: t***@example.com for the email test@example.com. This will require splitting the email string and using a for loop." How you solve this?

lunch.py
from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    class User:
        email = None
    user = User()
    user.email = 'kenneth@teamtreehouse.com'
    return render_template('user.html', user=user)
templates/macro.html
{% macro hide_email(User) %}
{% set x,y = User.email.split('@') %}
{% set str1 = x[0]+"*"*4+"@"+y %}
{{ str1 }}
{% endset %}
{% endset %}
{% endmacro %}
Kenneth Love
Kenneth Love
Treehouse Guest Teacher

You're really close. You don't use {% endset %} with {% set %} when you're just setting variables. That's for when you're creating HTML chunks as variables. Drop both of your {% endset %} tags and fix your * output (there should be the same number of stars, minus one, as the characters in the username part of the email address) and you'll pass.

8 Answers

Tero Lompolo
Tero Lompolo
15,180 Points

Some reason it didn't accept (len(x)-1) in {% set str1= x[0]+''(len(x)-1)+'@'+y %}. So, I just replaced it by 6 and it did pass. I'll leave it to that because I got that {% set ****** %} without {% endset %}. Thanks.

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

len() doesn't exist in Jinja2 templates but |count does...

Chris Grazioli
Chris Grazioli
31,225 Points

I'm going back through this challenge and try to do everything all over again before I do the final tacocat challenge. I'm vaguely familiar with "SET", did this work for you. Its seems like the asterisks would need to be dependent on the length of the string before the @

Chris Grazioli
Chris Grazioli
31,225 Points
{% macro hide_email(User) %}
  {% x,y = User.email.split('@') %}
  {% hidden_email = x[0]+"*"*len(x-1)+"@"+y %}
    {{ print hidden_email }}
{% endmacro %}

still working out the kinks,

Chris Grazioli
Chris Grazioli
31,225 Points

Kenneth Love --Now I'm Getting a little frustrated:

{% macro hide_email(User) %}
  {% x,y = User.email.split('@') %}
  {% hidden_email= x[0]+'*'*(len(x)-1)+'@'+y %}
  <p>{% hidden_email %}</p>
{% endmacro %}

I tested the hidden_email formula using http://www.pythontutor.com and it works fine, but for some reason I can't get the grader to except it?

Chris Grazioli
Chris Grazioli
31,225 Points

even when I don't screw up

{% macro hide_email(User) %}
  {% x,y = User.email.split('@') %}
  {% hidden_email= x[0]+'*'*(len(x)-1)+'@'+y %}
  <p>{{ hidden_email }}</p>
{% endmacro %}
Kenneth Love
Kenneth Love
Treehouse Guest Teacher

{% x %} isn't a valid tag. Neither is {% hidden_email %}.

Chris Grazioli
Chris Grazioli
31,225 Points

Kenneth Love - So I can't use variables I create like x or hidden_email here? Why? What would you do in place..? The

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

You can create variables for a short span of time with the {% with %} tag. You can also use {% set %} like in the OP's example.

Chris Grazioli
Chris Grazioli
31,225 Points

Its very frustrating trying to use programming elements that don't exist. Is there some sort of documentation on what jinja2's template engine lacks... (for the next time I have to re-invent the wheel) How would you do this with a loop?

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

Well, read the documentation I linked. It's not the best, but it shows you how to create variables and add a bit of power to your templates.

But, on that note, Jinja2 templates (and Django templates, which Jinja2 is based off of) are purposefully weak. They're not meant to be used for actual programming, that should be done in Python before the template is ever rendered. In fact, I'd say doing problems like in this code challenge is about as far as you should ever go in a template. Anything more complicated than this should be handled outside of a template.

While this might sound and feel like a limitation and shortcoming, I think it's actually one of the best decisions a templating engine can make. Enforce a strong separation of concerns between what you do in a template and what you do in a view/controller.

Chris Grazioli
Chris Grazioli
31,225 Points

How do you do this with a for loop?

can you explain why my way doesn't work. All I'm doing is giving a variable a name hidden_email. Are you not allowed to do this in a macro. where can I find documentation on this .

@Tero Lompolo you aren't using a for loop, just a split and then cheating the asterisks into place

Kenneth Love , how about a more detailed explanation

Kenneth Love
Kenneth Love
Treehouse Guest Teacher

You cannot create raw variables inside of a Jinja2 template. You can create variables for a context scope in them, using {% with %} or you can create them with {% set %}.

What you're doing, with {% hidden_email %} is using a tag named hidden_email, which doesn't exist. At least, that's how Jinja2 understands it. Jinja2 doesn't allow you to arbitrarily create variables with the equals sign in templates. This is a good thing as it could horrifically bloat the memory requirements of your templates.

Chris Grazioli
Chris Grazioli
31,225 Points

jacinator - had a good example in another post

{%macro hide_email(user) %}
{{ user.email[0] }}{% for _ in user.email.split('@')[0][1:] %}*{% endfor %}@{{ user.email.split('@')[1] }}
{%endmacro%}

I'm still going to have to look into {% with %} and {% set %}, the whole jinja2 syntax is weird to me and their docs suck!

Small hint for those using len(), in Jinja2 you need to use |length instead. For example len("four") won't work, but if you use "four"|length it will give you a value of 4.