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

1"""Base template object.""" 

2 

3from typing import Optional 

4 

5 

6import gws 

7import gws.lib.inifile 

8import gws.lib.intl 

9import gws.lib.mime 

10 

11 

12class Config(gws.ConfigWithAccess): 

13 """Template configuration.""" 

14 

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.""" 

27 

28 

29class Props(gws.Props): 

30 mapSize: Optional[gws.Size] 

31 pageSize: Optional[gws.Size] 

32 title: str 

33 

34 

35DEFAULT_MAP_SIZE = (50, 50, gws.Uom.mm) 

36DEFAULT_PAGE_SIZE = (210, 297, gws.Uom.mm) 

37 

38 

39class Object(gws.Template): 

40 """Base class for templates. 

41 

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 """ 

47 

48 def configure(self): 

49 self.title = self.cfg('title', default='') 

50 self.subject = self.cfg('subject', default='') 

51 

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) 

58 

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') 

62 

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 ) 

70 

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') 

75 

76 return gws.u.get_app_global('gws.base.application.default_strings', get) 

77 

78 def prepare_args(self, tri: gws.TemplateRenderInput) -> gws.TemplateArgs: 

79 """Build the template arguments from the render input. 

80 

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``. 

86 

87 Args: 

88 tri: Template render input. 

89 

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) 

96 

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() 

104 

105 f = gws.lib.intl.formatters(locale) 

106 

107 args.setdefault('locale', locale) 

108 args.setdefault('date', f[0]) 

109 args.setdefault('time', f[1]) 

110 args.setdefault('number', f[2]) 

111 

112 s = self._defaultStrings() 

113 s = s.get(locale.language) or s['en'] 

114 s.update(args.get('STRINGS', {})) 

115 args['STRINGS'] = s 

116 

117 # obsolete 

118 args.setdefault('gwsVersion', self.root.app.version) 

119 args.setdefault('gwsBaseUrl', gws.c.SERVER_ENDPOINT) 

120 

121 return gws.TemplateArgs(args) 

122 

123 def notify(self, tri: gws.TemplateRenderInput, message: str): 

124 """Send a progress message to the ``notify`` callback of the render input, if any. 

125 

126 Args: 

127 tri: Template render input. 

128 message: Progress message, like ``begin_print``. 

129 """ 

130 if tri.notify: 

131 tri.notify(message)