Coverage for gws-app/gws/base/template/core.py: 95%
62 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-05 13:35 +0200
1"""Base template object."""
3from typing import Optional
6import gws
7import gws.lib.inifile
8import gws.lib.intl
9import gws.lib.mime
12class Config(gws.ConfigWithAccess):
13 """Template configuration."""
15 mapSize: Optional[gws.UomSizeStr]
16 """Size of the map on the page."""
17 mimeTypes: Optional[list[gws.MimeType]]
18 """Output MIME types of the template."""
19 pageSize: Optional[gws.UomSizeStr]
20 """Page size."""
21 pageMargin: Optional[gws.UomExtentStr]
22 """Page margins in the order top, right, bottom, left."""
23 subject: str = ''
24 """Purpose of the template."""
25 title: str = ''
26 """Template title, shown in the client."""
29class Props(gws.Props):
30 mapSize: Optional[gws.Size]
31 pageSize: Optional[gws.Size]
32 title: str
35DEFAULT_MAP_SIZE = (50, 50, gws.Uom.mm)
36DEFAULT_PAGE_SIZE = (210, 297, gws.Uom.mm)
39class Object(gws.Template):
40 """Base class for templates.
42 Reads the common template options: subject, title, output MIME types, page
43 size, map size and page margins. Subclasses implement rendering; they can use
44 ``prepare_args`` to build the template arguments with the locale, formatters
45 and localized strings, and ``notify`` to report progress.
46 """
48 def configure(self):
49 self.title = self.cfg('title', default='')
50 self.subject = self.cfg('subject', default='')
52 self.mimeTypes = []
53 for p in self.cfg('mimeTypes', default=[]):
54 m = gws.lib.mime.get(p)
55 if not m:
56 raise gws.ConfigurationError(f'invalid mime type {p!r}')
57 self.mimeTypes.append(m)
59 self.mapSize = self.cfg('mapSize') or DEFAULT_MAP_SIZE
60 self.pageSize = self.cfg('pageSize') or DEFAULT_PAGE_SIZE
61 self.pageMargin = self.cfg('pageMargin')
63 def props(self, user):
64 return gws.Data(
65 mapSize=self.mapSize,
66 pageSize=self.pageSize,
67 title=self.title,
68 uid=self.uid,
69 )
71 def _defaultStrings(self):
72 """Return the default localized strings, by language."""
73 def get():
74 return gws.lib.inifile.from_paths(f'{gws.c.APP_DIR}/gws/base/application/templates/strings.ini')
76 return gws.u.get_app_global('gws.base.application.default_strings', get)
78 def prepare_args(self, tri: gws.TemplateRenderInput) -> gws.TemplateArgs:
79 """Build the template arguments from the render input.
81 Adds ``app``, ``subject``, ``locale``, the ``date``, ``time`` and ``number``
82 formatters, the obsolete ``gwsVersion`` and ``gwsBaseUrl``, unless already
83 given in ``tri.args``. The locale is taken from the arguments, the render
84 input, the first application locale or the default locale. ``STRINGS`` is set
85 to the default strings for the locale language, updated with the given ``STRINGS``.
87 Args:
88 tri: Template render input.
90 Returns:
91 Template arguments.
92 """
93 args = gws.u.merge({}, tri.args)
94 args.setdefault('app', self.root.app)
95 args.setdefault('subject', self.subject)
97 locale = args.get('locale') or tri.locale
98 if not locale:
99 ls = self.root.app.localeUids
100 if ls:
101 locale = gws.lib.intl.locale(ls[0], fallback=True)
102 if not locale:
103 locale = gws.lib.intl.default_locale()
105 f = gws.lib.intl.formatters(locale)
107 args.setdefault('locale', locale)
108 args.setdefault('date', f[0])
109 args.setdefault('time', f[1])
110 args.setdefault('number', f[2])
112 s = self._defaultStrings()
113 s = s.get(locale.language) or s['en']
114 s.update(args.get('STRINGS', {}))
115 args['STRINGS'] = s
117 # obsolete
118 args.setdefault('gwsVersion', self.root.app.version)
119 args.setdefault('gwsBaseUrl', gws.c.SERVER_ENDPOINT)
121 return gws.TemplateArgs(args)
123 def notify(self, tri: gws.TemplateRenderInput, message: str):
124 """Send a progress message to the ``notify`` callback of the render input, if any.
126 Args:
127 tri: Template render input.
128 message: Progress message, like ``begin_print``.
129 """
130 if tri.notify:
131 tri.notify(message)