===========================================================
Learn the Basics of Cookiecutter by Creating a Cookiecutter
===========================================================

The easiest way to understand what Cookiecutter does is to create a simple one
and see how it works.

Cookiecutter takes a source directory tree and copies it into your new
project. It replaces all the names that it finds surrounded by *templating
tags* ``{{`` and ``}}`` with names that it finds in the file
``cookiecutter.json``. That's basically it. [1]_

The replaced names can be file names, directory names, and strings inside
files.

With Cookiecutter, you can easily bootstrap a new project from a standard
form, which means you skip all the usual mistakes when starting a new
project.

Before you can do anything in this example, you must have Python installed on
your machine. Go to the `Python Website <https://www.python.org/>`_ and follow
the instructions there. This includes the ``pip`` installer tool. Now run:

.. code-block:: bash

	$ pip install cookiecutter

Your First Cookiecutter
-----------------------

To get started, create a directory somewhere on your computer. The name of
this directory will be the name of your Cookiecutter template, but it doesn't
constrain anything else---the generated project doesn't need to use the
template name, for example. Our project will be called ``HelloCookieCutter1``:

.. code-block:: bash

    $ mkdir HelloCookieCutter1
    $ cd HelloCookieCutter1

Inside this directory, we create the directory tree to be copied into the
generated project. We want to generate a name for this directory, so we put
the directory name in templating tags:

.. code-block:: bash

	$ mkdir {{cookiecutter.directory_name}}
	$ cd {{cookiecutter.directory_name}}

Anything inside templating tags can be placed inside a *namespace*. Here, by
putting ``directory_name`` inside the ``cookiecutter`` namespace,
``cookiecutter.directory_name`` will be looked up from the ``cookiecutter.json``
file as the project is generated by Cookiecutter.

Now we are inside the directory tree that will be copied. For the simplest
possible Cookiecutter template, we'll just include a single file. Again, we
want the file name to be looked up from ``cookiecutter.json``, so we name it
appropriately:

.. code-block:: bash

	$ touch {{cookiecutter.file_name}}.py

(``touch`` creates an empty file; you can just open it up in your editor). Now
edit the file so it contains:

.. code-block:: python

	print("Hello, {{cookiecutter.greeting_recipient}}!")

To finish, we create the ``cookiecutter.json`` file itself, so that
Cookiecutter can look up all our templated items. This file goes in our
``HelloCookieCutter1`` directory, and contains all the names we've used:

.. code-block:: json

	{
	    "directory_name": "Hello",
	    "file_name": "Howdy",
	    "greeting_recipient": "Julie"
	}

Now we can actually run Cookiecutter and create a new project from our
template. Move to a directory where you want to create the new project. Then
run Cookiecutter and hand it the directory where the template lives. On my
(Windows, so the slashes go back instead of forward) machine, this happens to
be under the ``Git`` directory:

.. code-block:: bash

	$ cookiecutter C:\Users\bruce\Documents\Git\HelloCookieCutter1
	directory_name [Hello]:
	file_name [Howdy]:
	greeting_recipient [Julie]:

Cookiecutter tells us what the default name for each item is, and gives us the
option of replacing that name with something new. In this case, I just pressed
``Return`` for each one, to accept all the defaults.

Now we have a generated directory called ``Hello``, containing a file
``Howdy.py``. When we run it:

.. code-block:: bash

	$ python Howdy.py
	Hello, Julie!

Voila! Instant generated project!

**Note**: The project we've created here happens to be Python, but
Cookiecutter is just replacing templated items with names it looks up in
``cookiecutter.json``, so you can produce projects of any kind, including
projects that aren't programs.

This is nice, but what if you want to share your Cookiecutter template with
everyone on the Internet? The easiest way is to upload it to a version control
repository. As you might have guessed by the ``Git`` subdirectory, this
example is on GitHub. Conveniently, Cookiecutter can build a project directly
from an internet repository, like the one for this very example. For variety,
this time we'll replace the values from ``cookiecutter.json`` with our own:

.. code-block:: bash

	$ cookiecutter https://github.com/BruceEckel/HelloCookieCutter1
	Cloning into 'HelloCookieCutter1'...
	remote: Counting objects: 37, done.
	Unpacking objects:  21% (8/37)
	remote: Total 37 (delta 19), reused 21 (delta 3), pack-reused 0
	Unpacking objects: 100% (37/37), done.
	Checking connectivity... done.
	directory_name [Hello]: Fabulous
	file_name [Howdy]: Zing
	greeting_recipient [Julie]: Roscoe

	$ cd Fabulous

	$ python Zing.py
	Hello, Roscoe!

Same effect, but this time produced from the Internet! You'll notice that even
though it says ``Cloning into 'HelloCookieCutter1'...``, you don't see any
directory called ``HelloCookieCutter1`` in your local directory. Cookiecutter
has its own storage area for cookiecutters, which is in your home directory
in a subdirectory called ``.cookiecutters`` (the leading ``.`` hides the directory
on most operating systems). You don't need to do anything with this directory
but it can sometimes be useful to know where it is.

Now if you ever find yourself duplicating effort when starting new projects,
you'll know how to eliminate that duplication using cookiecutter. But even
better, lots of people have created and published cookiecutters, so when you
are starting a new project, make sure you look at the `list of pre-defined
cookiecutters 
<https://cookiecutter.readthedocs.io/en/latest/readme.html #categories-of-cookiecutters>`_ 
first!

.. [1] 	You can also run *hooks* before and/or after generation, but that's
		more complex than what we want to cover here.
