Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: README.md

Issue 29628724: Issue 5521 - Restructure CMS documentation to make it easier to use and extend (Closed) Base URL: https://hg.adblockplus.org/cms
Patch Set: Add initial API docs Created Dec. 13, 2017, 11:08 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | docs/api/filters.md » ('j') | docs/content/includes.md » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # CMS # 1 # CMS #
2 2
3 We use this CMS for [adblockplus.org](https://github.com/adblockplus/web.adblock plus.org/) 3 We use this CMS for [adblockplus.org](https://github.com/adblockplus/web.adblock plus.org/)
4 and related websites. It converts a directory with content data into static 4 and related websites. It converts a directory with content data into static
5 files. You are free to use it for other projects but please keep in mind that we 5 files. You are free to use it for other projects but please keep in mind that we
6 make no stability guarantees whatsoever and might change functionality any time. 6 make no stability guarantees whatsoever and might change functionality any time.
7 7
8 ## How to use ## 8 ## Getting started ##
9 9
10 ### Running the test server ### 10 The easiest way to get started is to run a test server. The test server will
11 11 convert your content directory on the fly, your changes will become visible
12 The test server will convert your content directory on the fly, your changes 12 immediately. To run it you need:
13 will become visible immediately. To run it you need:
14 13
15 * Python 2.7 14 * Python 2.7
16 * [Jinja2](http://jinja.pocoo.org/) and 15 * [Jinja2](http://jinja.pocoo.org/) and
17 [Markdown](https://pypi.python.org/pypi/Markdown) modules (can be installed by 16 [Markdown](https://pypi.python.org/pypi/Markdown) modules (can be installed by
18 running `easy_install Jinja2 Markdown` from the command line) 17 running `easy_install Jinja2 Markdown` from the command line)
19 * A current copy of the 18 * A current copy of the
20 [cms repository](https://github.com/adblockplus/cms/) (can be 19 [cms repository](https://github.com/adblockplus/cms/) (can be
21 [downloaded as ZIP file](https://github.com/adblockplus/cms/archive/master.zip ) 20 [downloaded as ZIP file](https://github.com/adblockplus/cms/archive/master.zip )
22 or cloned via `git clone https://github.com/adblockplus/cms.git`) 21 or cloned via `git clone https://github.com/adblockplus/cms.git`)
23 22
24 Optionally, the [Werkzeug](http://werkzeug.pocoo.org/) module can be installed 23 Optionally, the [Werkzeug](http://werkzeug.pocoo.org/) module can be installed
25 as well, this will provide some developer features. 24 as well, this will provide some developer features.
26 25
27 Run the `runserver.py` script from your content directory, e.g.: 26 Run the `runserver.py` script from your content directory, e.g.:
28 27
29 python ../cms/runserver.py 28 python ../cms/runserver.py
30 29
31 Alternatively, the content directory could also be specified as command line 30 Alternatively, the content directory could also be specified as command line
32 parameter of `runserver.py`. This will start a local web server on port 5000, 31 parameter of `runserver.py`. This will start a local web server on port 5000,
33 e.g. the page the page `pages/example.md` will be accessible under 32 e.g. the page the page `pages/example.md` will be accessible under
34 `http://localhost:5000/en/example`. 33 `http://localhost:5000/en/example`.
35 34
36 Note that the test server is inefficient and shouldn't be run in production. 35 Note that the test server is inefficient and shouldn't be run in production.
37 There you should generate static files as explained below. 36 There you should generate static files as explained below.
38 37
39 ### Generating the standalone test server ### 38 ## Documentation ##
40 39
41 The standalone test server is a single binary, without any further dependencies. 40 - How to use
42 It can be copied to another system and will no longer require Python or any of 41 - [Running the test server](docs/usage/test-server.md)
43 its modules. In order to generate the standalone test server you need all the 42 - [Generating the standalone test server](docs/usage/standalone-test-server. md)
44 prerequisites required to run the test server and 43 - [Generating static files](docs/usage/generate-static-files.md)
45 [PyInstaller](https://github.com/pyinstaller/pyinstaller/wiki). PyInstaller can 44 - [Syncing translations](docs/usage/syncing-translations.md)
46 be installed by running `easy_install pyinstaller`. 45 - Content structure
47 46 - [Configuration (`settings.ini`)](docs/content/settings.md)
48 Run the following command from the directory of the `cms` repository: 47 - [Custom Jinja2 global functions and variables (`globals`)](docs/content/gl obals.md)
49 48 - [Custom Jinja2 filters (`filters`)](docs/content/filters.md)
50 pyinstaller runserver.spec 49 - [Localization files (`locales`)](docs/content/locales.md)
51 50 - [Page layout templates (`templates`)](docs/content/templates.md)
52 If successful, this will put the standalone test server into the `dist` 51 - [Various include files (`includes`)](docs/content/includes.md)
53 directory. 52 - [User-visible pages (`pages`)](docs/content/pages.md)
54 53 - [Static content (`static`)](docs/content/static.md)
55 ### Generating static files ### 54 - API
56 55 - [Variables](docs/api/variables.md)
57 On your production server you should convert the content directory into static 56 - [Custom filters](docs/api/filters.md)
58 files. To do that you need: 57 - [Global functions](docs/api/functions.md)
59
60 * Python 2.7
61 * [Jinja2](http://jinja.pocoo.org/) and
62 [Markdown](https://pypi.python.org/pypi/Markdown) modules (can be installed by
63 running `easy_install Jinja2 Markdown` from the command line)
64 * A current copy of the
65 [cms repository](https://github.com/adblockplus/cms/) (can be
66 [downloaded as ZIP file](https://github.com/adblockplus/cms/archive/master.zip )
67 or cloned via `git clone https://github.com/adblockplus/cms.git`)
68
69 Run the following command from the directory of the `cms` repository:
70
71 python -m cms.bin.generate_static_pages www_directory target_directory
72
73 Here `www_directory` should be replaced by the path to your content directory.
74 `target_directory` is the path where static files will be placed.
75
76 Note: Localized versions of pages will only be generated when their translations
77 are at least 30% complete. (Measured by comparing the total number
78 of translatable strings on a page to the number of strings that have been
79 translated for a given locale.) This is different from the test server which
80 will include less complete translations.
81
82 ### Syncing translations ###
83
84 Before syncing translations ensure the following:
85
86 - The `crowdin-project-name` setting has been set in the site's configuration.
87 - The `urllib3` Python module is installed.
88
89 Now to sync with Crowdin type the following:
90
91 python -m cms.bin.translate www_directory crowdin_project_api_key [logging_l evel]
92
93 The script might take a while to run, it does the following things:
94
95 1. Requests information about your Crowdin project
96 2. Checks all local locales are supported by Crowdin and enabled for your projec t
97 3. Renders all pages in your default language and extracts all page strings
98 4. Creates any required directories in your Crowdin project
99 5. Uploads any new page strings and updates any existing page strings
100 6. Uploads any pre-existing translation files for any newly uploaded pages
101 7. Requests Crowdin generate a fresh translations export archive
102 8. Downloads the archive of translations and extracts it replacing all local
103 translation files
104
105 Notes:
106
107 - You have to use the Crowdin project's API key, not your account API key
108 - You should probably enable "Skip untranslated strings" under your
109 project settings.
110 - Translations are only _uploaded_ for new files. If you are syncing with
111 Crowdin for the first time, and you have existing translation files pay
112 attention to any warnings. If there are any problems it is recommended
113 you re-create another fresh Crowdin project and try again. (Otherwise
114 translations for the pages already uploaded could be lost!)
115 - If you are running the script from a cronjob or similar you will probably
116 want to set the logging level to `ERROR` or similar
117
118 ## Content structure ##
119
120 Currently, the following directories of your content directory will be
121 considered:
122
123 * `filters`: Custom Jinja2 filters
124 * `globals`: Custom Jinja2 global functions and variables
125 * `includes`: Various include files
126 * `locales`: Localization files
127 * `pages`: User-visible pages
128 * `static`: Static content
129 * `templates`: Page layout templates
130
131 There should also be a `settings.ini` file with configuration.
132
133 All of these are explained in more detail below.
134
135 ### Configuration (settings.ini) ###
136
137 The following sections can be defined in `settings.ini`:
138
139 * `[general]`: following settings should be listed here:
140 * `defaultlocale`: The fallback locale, to be used whenever no localized
141 page/strings can be found for a locale.
142 * `defaultpage`: the default page which is displayed by the server if the URL
143 doesn't contain a page name. Note that while the test server will consider
144 that setting automatically, the real server might need to be configured
145 accordingly.
146 * `crowdin-project-name`: The Crowdin project name, this must be set for if
147 you intend to use the cms.bin.translate script to update the Crowdin
148 translations.
149 * `[langnames]`: defines the language names correspoding to particular language
150 codes.
151 * `[rtl]`: any language codes listed here are treated as right-to-left languages .
152 The values of the settings are ignored.
153 * `[locale_overrides]`: every entry defines that a page should use a different
154 locale file, not the one matching its name (to be used when multiple pages
155 share localization data).
156
157 ### Localization files ###
158
159 The language-specific data is stored in the `locales` directory. Each language
160 (identified by its locale code) is given a subdirectory here. The `.json` files
161 contain localizable strings using the following format:
162
163 {
164 "stringid": {
165 "message": "Translated string",
166 "description": "Optional string description"
167 },
168 ...
169 }
170
171 Any other files are considered localizable files and will be available on the
172 server unchanged. This is useful for images for example: a language-dependent
173 image can be placed into the `locales/en` directory and a German version
174 of the same image into the `locales/de` directory. E.g. the file
175 `locales/en/foo.png` will be available on the server under the URL `/en/foo.png` .
176
177 ### Pages ###
178
179 The pages are defined in the `pages` directory. The file extension defines the
180 format in which a page is specified and won't be visible on the web server.
181 The page name is prepended by the locale code in the URL, e.g. `pages/foo.md`
182 can be available under the URLs `/en/foo` and `/de/foo` (the English and German
183 versions respectively). Regardless of the format, a page can define a number of
184 settings using the following format:
185
186 setting = value
187
188 Note that the settings have to placed at the beginning of the file, before the
189 actual content. The following settings can be changed:
190
191 * `template`: This defines the template to be used for this page (without the
192 file extension). By default the `default` template is used for all pages.
193 * `title`: The locale string to be used as page title. By default the `title`
194 string is used.
195 * `noheading`: Setting this to any value will make sure no heading is displayed.
196 By default a `<h1>` tag with the page title is added above the content.
197 * `notoc`: Setting this to any value will prevent a table of contents from being
198 generated. By default a table of contents is always generated if the page
199 contains any headers with an `id` attribute.
200
201 The following tag inserts an include file into the page (can be in a different
202 format):
203
204 <? include foo ?>
205
206 Include files should be placed into the `includes` directory of the repository.
207 In the case above the contents of `includes/foo.md` or `includes/foo.tmpl` will
208 be inserted (whichever is present).
209
210 #### Markdown format (md) ####
211
212 This format should normally be used, it allows the pages to be defined using the
213 [Markdown](http://daringfireball.net/projects/markdown/syntax) syntax. Raw HTML
214 tags are allowed and can be used where Markdown syntax isn't sufficient. The
215 [Python-Markdown Extra](https://pythonhosted.org/Markdown/extensions/extra.html)
216 extension is active and allows specifying custom attributes for the generated
217 HTML tags, HTML block elements that contain Markdown and more.
218
219 Any content between `<head>` and `</head>` tags will be inserted into the head
220 of the generated web page, this is meant for styles, scripts and the like.
221 Other pages should be linked by using their name as link target (relative links) ,
222 these links will be resolved to point to the most appropriate page language.
223 Embedding localizable images works the same, use the image name as image source.
224
225 Localizable strings can be specified inline with the following syntax:
226
227 {{string_name String contents in default language}}
228
229 Try to give the string a descriptive name as it will help translators.
230 Optionally you can add a description for strings as well to provide even more
231 context:
232
233 {{string_name[The string description] String contents}}
234
235 _Note: String names and descriptions have no effect on the generated page,
236 assuming string name is unique to the page. The name and description are just
237 used to provide translators with additional context about the string._
238
239 Finally if you find yourself using the same string multiple times in a page
240 you can reduce duplication by simply omitting the description and contents
241 after the first use. For example:
242
243 {{title[Title of the page] Adblock Plus - Home}}
244 {{title}}
245
246 #### Raw HTML format (html) ####
247
248 This format is similar to the Markdown format but uses regular HTML syntax.
249 No processing is performed beyond inserting localized strings and resolving
250 links to pages and images. This format is mainly meant for legacy content.
251 The syntax for localizable strings documented above can be used as with
252 Markdown.
253
254 #### Jinja2 format (tmpl) ####
255
256 Complicated pages can be defined using the
257 [Jinja2 template format](http://jinja.pocoo.org/docs/templates/). Automatic
258 escaping is active so by default values inserted into the page cannot contain
259 any HTML code. Any content between `<head>` and `</head>` tags will be inserted
260 into the head of the generated web page, everything else defined the content of
261 the page.
262
263 The following variables can be used:
264
265 * `page`: The page name
266 * `config`: Contents of the `settings.ini` file in this repository (a
267 [configparser object](http://docs.python.org/2/library/configparser.html))
268 * `locale`: Locale code of the page language
269 * `available_locales`: Locale codes of all languages available for this page
270
271 Following custom filters can be used:
272
273 * `translate(default, name, comment=None)`: translates the given default string
274 and string name for the current page and locale. The string name should be
275 unique for the page but otherwise is only seen by the translators. Optionally
276 a comment (description) can be specified to help provide the translators with
277 additional context.
278 * `linkify(url, locale=None, **attrs)`: generates an `<a href="...">` tag for
279 the URL. If the URL is a page name it will be converted into a link to the
280 most appropriate page language. The language used can also be specified
281 manually with the locale parameter. Any further keyword arguments passed
282 are turned into additional HTML attributes for the tag.
283 * `toclist(html)`: extracts a list of headings from HTML code, this can be used
284 to generate a table of contents.
285
286 The following global functions can be used:
287
288 * `get_string(name, page=None)`: retrieves a string from a locale file.
289 Unless a page is specified the locale file matching the name of the current
290 page is used.
291 * `get_page_content(page, locale=None)`: returns a dictionary of the content
292 and params for the given page and locale. Locale defaults to the current one
293 if not specified. Provided keys include `head`, `body`, `available_locales`
294 and `translation_ratio`.
295
296 ### Static files ###
297
298 Any files located in the `static` directory will be available on the server
299 unchanged. The file `static/css/foo.css` will be available under the URL
300 `/css/foo.css`.
301
302 ### Templates ###
303
304 The templates specified in the `templates` directory specify the overall
305 structure that is common for all pages. These templates should have the file
306 extension `tmpl` and use the [Jinja2 template format](http://jinja.pocoo.org/doc s/templates/).
307 The differences to pages using the same format are:
308
309 * No special treatment of the `<head>` tag.
310 * Additional variables `head` and `body` are defined with the HTML code that
311 should be added to the head and content of the page respectively.
312
313 By default, `default.tmpl` will be used for all pages. If other templates are
314 defined, the pages need to choose them explicitly using the `template` setting.
315
316 ### Custom filters ###
317
318 The `filters` directory can define custom Jinja2 filters which will be available
319 in all Jinja2 templates. The file name defines the filter name, e.g.
320 `filters/myfilter.py` will define a filter named `myfilter`. This file should
321 also contain a function called `myfilter`, this one will be called when the
322 filter is invoked. For more information on Jinja2 filters see
323 [official documentation](http://jinja.pocoo.org/docs/dev/api/#writing-filters).
324
325 ### Custom functions and variables ###
326
327 The `globals` directory can define custom Jinja2 globals which will be available
328 in all Jinja2 templates. Typically, this is used for custom functions. The file
329 name should match the name of the function or variable to be defined, and export
330 a variable with that name. E.g. `globals/myfunction.py` can define a function
331 called `myfunction` that will become available to all Jinja2 templates.
OLDNEW
« no previous file with comments | « no previous file | docs/api/filters.md » ('j') | docs/content/includes.md » ('J')

Powered by Google App Engine
This is Rietveld