Skip to content
This repository was archived by the owner on Aug 29, 2024. It is now read-only.
Luis García edited this page Sep 22, 2013 · 11 revisions

Hi! This is the wiki for the Scope project, a library for creating code templates in pure Python. This wiki includes several guides for learning about the usage of the project. You can continue reading to know about what the project is, its goal, and directions for you to get more info.

Why another template engine?

Allow me to describe what the goal of the project is. Let's say you want to generate a basic Hello World C++ source file. You could just open a file and use a basic write() function.

with open('hello-world.cpp', 'w') as f:
    f.write('#include <iostream>')
    f.write('int main() {')
    f.write('    std::cout << "Hello World" << std::endl;')
    f.write('}')

You could use multi-line strings but even so this method becomes really hard with large files. In the other hand, there are other utilities that allows you to create a template file and include Python or another language code inside. In that case, those files can become hard to understand and maintain.

Now, let's take a look to Brevé,

html [
    head [
        title [ 'Hello world' ]
    ],
    body [
        span [ 'Hello world' ]
    ]
]

It's simple and very clear, and it keeps being that way for larger templates. It's pure Python code, so you can still use features from Python directly. Now, it's written for HTML generation.

It's now when I introduce Scope, very similar to Brevé, but created with versatility and extensibility in mind. The Hello World example becomes in,

template = cpp.tfile[
    '#include <iostream>'
    cpp.tmethod('int', 'main')[
        'std::cout << "Hello World" << std::endl;'
    ]
]

Also, Scope offers several utilities to handle more complex templates.

You can see a long list of template utilities in the Python website.

Extensibility

Let's take the example from README,

cpp.tfile[
    '#include <string>',

    cpp.tclass(name='App')[
        cpp.tattribute('std::string', '_name'),

        cpp.tmethod('std::string', 'GetName', visibility=cpp.PUBLIC, const=True)[
            'return this->_name;'
        ],

        cpp.tmethod('void', 'SetName', ['const std::string & value'], visibility=cpp.PUBLIC)[
            'this->_name = value;'
        ]
    ]
]

The template is basically a class with a Name property in it. We can write a function that returns the parts of the property,

def my_property(attr_type, attr_name, camel_name):
    getter_name = 'Get{0}'.format(camel_name)
    setter_name = 'Set{0}'.format(camel_name)
    setter_arg = 'const {0} & value'.format(attr_type)

    return scope.span[
        cpp.tattribute(attr_type, attr_name),

        cpp.tmethod(attr_type, getter_name, visibility=cpp.PUBLIC, const=True)[
            'return this->{0};'.format(attr_name)
        ],

        cpp.tmethod('void', setter_name, [setter_arg], visibility=cpp.PUBLIC)[
            'this->{0} = value;'.format(attr_name)
        ]
    ]

Now, with that function we can update our example to a simpler one,

cpp.tfile[
    '#include <string>',

    cpp.tclass(name='App')[
        my_property('std::string', '_name', 'Name')
    ]
]

And even add more properties if needed, with just a single line for each one. That is one of the things that you can do with Scope, keep reading to know more.

What's next?

First be sure to read about the basics. After that, you can see the usage for each language, by now only C++. Or you can even learn about how create support for your own language!

Clone this wiki locally