vdvaxel
vdvaxel

Reputation: 745

How to omit curly braces when using cookiecutter?

I'm building a cookiecutter template in Python, something fairly simple for now, that looks like this:

├── {{ cookiecutter.project_name }}
│    └── test.py
│
└── cookiecutter.json

When I run the cookiecutter command on the command line and point it to this template, it correctly asks me for the project_name input. However, the problem is that in my test.py script, there is a print statement with double curly braces as well, so in the end, the cookiecutter command fails, with the following error:

  File "./test.py", line 73, in template
jinja2.exceptions.TemplateSyntaxError: expected token 'end of print statement', got ':'
  File "./test.py", line 73
    print(('{{"RequestId":"{0}", '

Is there a way to tell cookiecutter to omit certain curly braces?

Upvotes: 4

Views: 3660

Answers (1)

Gino Mempin
Gino Mempin

Reputation: 29660

From cookiecutter's Troubleshooting docs (or from the underlying Jinja Templating docs), to prevent cookiecutter from incorrectly parsing braces { or {{ from the template:

Make sure you escape things properly, like this:

{{ "{{" }}

Or this:

{{ {{ url_for('home') }} }}

See http://jinja.pocoo.org/docs/templates/#escaping for more info.

If the template is like this:

marker = '{{'
print('{{RequestId:{0}, ')
print('The value should be in braces {{{cookiecutter.value}}}')

The braces need to be escaped like this:

marker = '{{ "{{" }}'
print('{{ "{{" }}RequestId:{0}, ')
print('The value should in braces {{ "{" }}{{cookiecutter.value}}{{ "}" }}')

So that it generates properly:

$ cat template/\{\{\ cookiecutter.project_name\ \}\}/test.py
marker = '{{ "{{" }}'
print('{{ "{{" }}RequestId:{0}, ')
print('The value should in braces {{ "{" }}{{cookiecutter.value}}{{ "}" }}')

$ cookiecutter template
project_name [myproject]: 
value [the_value]: 123456

$ cat myproject/test.py
marker = '{{'
print('{{RequestId:{0}, ')
print('The value should in braces {123456}')

Another option is, rather than escaping each { in test.py, you can just tell cookiecutter to skip the entire test.py file by adding it to the Copy without Render list (available from cookiecutter 1.1+):

To avoid rendering directories and files of a cookiecutter, the _copy_without_render key can be used in the cookiecutter.json.

{
   "project_slug": "sample",
   "_copy_without_render": [
       "*.html",
       "*not_rendered_dir",
       "rendered_dir/not_rendered_file.ini"
   ]
}

From the original example, in case you are only templating the folder name and leaving everything in test.py untouched, then cookiecutter.json should be:

{
    "project_name": "myproject",

    "_copy_without_render": [
        "test.py"
    ]
}

Upvotes: 4

Related Questions