Template Files

When Meson configures the project, directives in the src/meson.build file cause it to read two template files, treasure.in and config.py.in, fill in the placeholders inside them, and write the resulting treasure and config.py files to the build directory.

Executable Template

The treasure.in file contains a template that will be filled in by the build system, replacing placeholders with information about the application, its installation and its version. The resulting treasure file will be run when the user launches the application.

If you create a new application with GNOME Builder, the template will look very similar to this one. It begins with the line which determines which Python interpreter will be used to run the application:

#!@PYTHON@
# -*- coding: utf-8 -*-

# Copyright (C) 2018 Purism SPC
# SPDX-License-Identifier: GPL-3.0+
# Author: David Boddie <david.boddie@puri.sm>

import gettext
import locale
import os
import signal
import sys

VERSION = '@VERSION@'
pkgdatadir = '@pkgdatadir@'
localedir = '@localedir@'

sys.path.insert(1, pkgdatadir)
signal.signal(signal.SIGINT, signal.SIG_DFL)

After importing the necessary modules, the template defines some strings that contain the version number and the locations of directories that will be needed by the application. The pkgdatadir path is used to ensure that the application’s modules can be imported.

The message catalogs installed with the application – see Translations Directory – can be accessed using functions from the Python gettext module and are used to translate user-visible strings. We use functions from the Python locale module to set the translation domain to ensure that the UI files handled by Gtk.Builder are translated correctly:

# Enable translation to occur in the extension libraries.
locale.bindtextdomain('treasure', localedir)
locale.textdomain('treasure')

# Install a translator for Python code to use throughout the application.
gettext.install('treasure', localedir, names=['ngettext'])

The gettext.install function installs the underscore _() function into the built-in namespace to make it convenient to access translations.

The standard check for the __main__ namespace is used to execute code when the application is run:

if __name__ == '__main__':

    import gi
    from gi.repository import Gio

    res = Gio.Resource.load(os.path.join(pkgdatadir, 'treasure.gresource'))
    # Register the resource globally within the application.
    res._register()

This begins by loading the application resource file and registering it with the application, making its contents available. Then, the main function in the main module is run:

    from treasure import main
    sys.exit(main.main(VERSION))

When the main function returns, the return value is used as the application’s exit code.

Configuration Template

The config.py.in file contains placeholders that will be filled in by the build system. The resulting config.py file will be installed with the other Python modules for the application and used to access application metadata, such as its installation location and version.

VERSION = '@VERSION@'
pkgdatadir = '@pkgdatadir@'
localedir = '@localedir@'

By creating a module like this, we make it possible access this information from any other Python module in the application. This is similar to the config.vapi file that Vala applications use to obtain similar information.