Left: | ||
Right: |
OLD | NEW |
---|---|
1 # adblockplus.org web content # | 1 # CMS # |
2 | 2 |
3 The web content of the adblockplus.org domain is generated automatically from | 3 We use this CMS for [adblockplus.org](https://github.com/adblockplus/web.adblock plus.org/) |
4 the files in this repository. | 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 | |
6 make no stability guarantees whatsoever and might change functionality any time. | |
Sebastian Noack
2015/03/12 09:27:51
Really worth pointing this out here? Isn't it the
Wladimir Palant
2015/03/12 16:40:01
No. Most our projects are explicitly developed for
| |
5 | 7 |
6 ## Testing your changes ## | 8 ## How to use ## |
7 | 9 |
8 You can easily test your changes to these files locally. What you need: | 10 ### Running the test server ### |
11 | |
12 The test server will convert your content directory on the fly, your changes | |
13 will become visible immediately. To run it you need: | |
9 | 14 |
10 * Python 2.7 | 15 * Python 2.7 |
11 * [Flask](http://flask.pocoo.org/), [Jinja2](http://jinja.pocoo.org/) and | 16 * [Flask](http://flask.pocoo.org/), [Jinja2](http://jinja.pocoo.org/) and |
12 [Markdown](https://pypi.python.org/pypi/Markdown) modules (can be installed by | 17 [Markdown](https://pypi.python.org/pypi/Markdown) modules (can be installed by |
13 running `easy_install Flask Jinja2 Markdown` from the command line) | 18 running `easy_install Flask Jinja2 Markdown` from the command line) |
14 * A current copy of the | 19 * A current copy of the |
15 [sitescripts repository](https://hg.adblockplus.org/sitescripts/) (can be | 20 [cms repository](https://github.com/adblockplus/cms/) (can be |
Sebastian Noack
2015/03/12 09:27:51
This README goes into the CMS repo, right? So any
Wladimir Palant
2015/03/12 16:40:01
Because repositories like web.adblockplus.org will
| |
16 downloaded from the web or cloned via | 21 [downloaded as ZIP file](https://github.com/adblockplus/cms/archive/master.zip ) |
17 `hg clone https://hg.adblockplus.org/sitescripts/`) | 22 or cloned via `git clone https://github.com/adblockplus/cms.git`) |
18 | 23 |
19 Run the following command from the directory of the sitescripts repository: | 24 Run the following command from the directory of the `cms` repository: |
Sebastian Noack
2015/03/12 09:27:51
How about making runserver.py run from everywhere,
Wladimir Palant
2015/03/12 16:40:01
Done.
| |
20 | 25 |
21 python -m sitescripts.cms.bin.test_server www_directory | 26 python runserver.py www_directory |
22 | 27 |
23 Here `www_directory` should be replaced by the directory of this repository. | 28 Here `www_directory` should be replaced by the path to your content directory. |
24 This will start a local web server on port 5000, e.g. you can open the about | 29 This will start a local web server on port 5000, e.g. the page the page |
25 page as [http://localhost:5000/en/about](http://localhost:5000/en/about). | 30 `pages/example.md` will be accessible under `http://localhost:5000/en/example`. |
26 | 31 |
27 ## Configuration ## | 32 Note that the test server is inefficient and shouldn't be run in production. |
33 There you should generate static files as explained below. | |
28 | 34 |
29 Repository configuration is stored in the `settings.ini` file. The following | 35 ### Generating the standalone test server ### |
30 sections can be defined: | 36 |
37 The standalone test server is a single binary, without any further dependencies. | |
38 It can be copied to another system and will no longer require Python or any of | |
39 its modules. In order to generate the standalone test server you need all the | |
40 prerequisites required to run the test server and | |
41 [PyInstaller](https://github.com/pyinstaller/pyinstaller/wiki). PyInstaller can | |
42 be installed by running `easy_install pyinstaller`. | |
43 | |
44 Run the following command from the directory of the `cms` repository: | |
45 | |
46 pyinstaller runserver.spec | |
47 | |
48 If successful, this will put the standalone test server into the `dist` | |
49 directory. | |
50 | |
51 ### Generating static files ### | |
52 | |
53 On your production server you should convert the content directory into static | |
54 files. To do that you need: | |
55 | |
56 * Python 2.7 | |
57 * [Jinja2](http://jinja.pocoo.org/) and | |
58 [Markdown](https://pypi.python.org/pypi/Markdown) modules (can be installed by | |
59 running `easy_install Jinja2 Markdown` from the command line) | |
60 * A current copy of the | |
61 [cms repository](https://github.com/adblockplus/cms/) (can be | |
62 [downloaded as ZIP file](https://github.com/adblockplus/cms/archive/master.zip ) | |
63 or cloned via `git clone https://github.com/adblockplus/cms.git`) | |
64 | |
65 Run the following command from the directory of the `cms` repository: | |
66 | |
67 python -m cms.bin.generate_static_pages www_directory target_directory | |
68 | |
69 Here `www_directory` should be replaced by the path to your content directory. | |
70 `target_directory` is the path where static files will be placed.. | |
71 | |
72 ## Content structure ## | |
73 | |
74 Currently, the following directories of your content directory will be | |
75 considered: | |
76 | |
77 * `filters`: Custom Jinja2 filters | |
78 * `includes`: Various include files | |
79 * `locales`: Localization files | |
80 * `pages`: User-visible pages | |
81 * `static`: Static content | |
82 * `templates`: Page layout templates | |
83 | |
84 There should also be a `settings.ini` file with configuration. | |
85 | |
86 All of these are explained in more detail below. | |
87 | |
88 ### Configuration (settings.ini) ### | |
89 | |
90 The following sections can be defined in `settings.ini`: | |
31 | 91 |
32 * `[general]`: following settings should be listed here: | 92 * `[general]`: following settings should be listed here: |
33 * `defaultlocale`: The fallback locale, to be used whenever no localized | 93 * `defaultlocale`: The fallback locale, to be used whenever no localized |
34 page/strings can be found for a locale. | 94 page/strings can be found for a locale. |
35 * `defaultpage`: the default page which is displayed by the server if the URL | 95 * `defaultpage`: the default page which is displayed by the server if the URL |
36 doesn't contain a page name. Note that while the test server will consider | 96 doesn't contain a page name. Note that while the test server will consider |
37 that setting automatically, the real server might need to be configured | 97 that setting automatically, the real server might need to be configured |
38 accordingly. | 98 accordingly. |
39 * `[langnames]`: defines the language names correspoding to particular language | 99 * `[langnames]`: defines the language names correspoding to particular language |
40 codes. | 100 codes. |
41 * `[rtl]`: any language codes listed here are treated as right-to-left languages . | 101 * `[rtl]`: any language codes listed here are treated as right-to-left languages . |
42 The values of the settings are ignored. | 102 The values of the settings are ignored. |
43 * `[locale_overrides]`: every entry defines that a page should use a different | 103 * `[locale_overrides]`: every entry defines that a page should use a different |
44 locale file, not the one matching its name (to be used when multiple pages | 104 locale file, not the one matching its name (to be used when multiple pages |
45 share localization data). | 105 share localization data). |
46 | 106 |
47 ## Locales ## | 107 ### Localization files ### |
48 | 108 |
49 The language-specific data is stored in the `locales` directory. Each language | 109 The language-specific data is stored in the `locales` directory. Each language |
50 (identified by its locale code) is given a subdirectory here. The `json` files | 110 (identified by its locale code) is given a subdirectory here. The `.json` files |
51 contain localizable strings using the following format: | 111 contain localizable strings using the following format: |
52 | 112 |
53 { | 113 { |
54 "stringid": { | 114 "stringid": { |
55 "message": "Translated string", | 115 "message": "Translated string", |
56 "description": "Optional string description" | 116 "description": "Optional string description" |
57 }, | 117 }, |
58 ... | 118 ... |
59 } | 119 } |
60 | 120 |
61 Any other files are considered localizable files and will be available on the | 121 Any other files are considered localizable files and will be available on the |
62 server unchanged. This is useful for images for example: a language-dependent | 122 server unchanged. This is useful for images for example: a language-dependent |
63 image can be placed into the `locales/en` directory and a German version | 123 image can be placed into the `locales/en` directory and a German version |
64 of the same image into the `locales/de` directory. E.g. the file | 124 of the same image into the `locales/de` directory. E.g. the file |
65 `locales/en/foo.png` will be available on the server under the URL `/en/foo.png` . | 125 `locales/en/foo.png` will be available on the server under the URL `/en/foo.png` . |
66 | 126 |
67 ## Pages ## | 127 ### Pages ### |
68 | 128 |
69 The pages are defined in the `pages` directory. The file extension defines the | 129 The pages are defined in the `pages` directory. The file extension defines the |
70 format in which a page is specified and won't be visible on the web server. | 130 format in which a page is specified and won't be visible on the web server. |
71 The page name is prepended by the locale code in the URL, e.g. `pages/foo.md` | 131 The page name is prepended by the locale code in the URL, e.g. `pages/foo.md` |
72 can be available under the URLs `/en/foo` and `/de/foo` (the English and German | 132 can be available under the URLs `/en/foo` and `/de/foo` (the English and German |
73 versions respectively). Regardless of the format, a page can define a number of | 133 versions respectively). Regardless of the format, a page can define a number of |
74 settings using the following format: | 134 settings using the following format: |
75 | 135 |
76 setting = value | 136 setting = value |
77 | 137 |
(...skipping 12 matching lines...) Expand all Loading... | |
90 | 150 |
91 The following tag inserts an include file into the page (can be in a different | 151 The following tag inserts an include file into the page (can be in a different |
92 format): | 152 format): |
93 | 153 |
94 <? include foo ?> | 154 <? include foo ?> |
95 | 155 |
96 Include files should be placed into the `includes` directory of the repository. | 156 Include files should be placed into the `includes` directory of the repository. |
97 In the case above the contents of `includes/foo.md` or `includes/foo.tmpl` will | 157 In the case above the contents of `includes/foo.md` or `includes/foo.tmpl` will |
98 be inserted (whichever is present). | 158 be inserted (whichever is present). |
99 | 159 |
100 ### Markdown format (md) ### | 160 #### Markdown format (md) #### |
101 | 161 |
102 This format should normally be used, it allows the pages to be defined using the | 162 This format should normally be used, it allows the pages to be defined using the |
103 [Markdown](http://daringfireball.net/projects/markdown/syntax) syntax. Raw HTML | 163 [Markdown](http://daringfireball.net/projects/markdown/syntax) syntax. Raw HTML |
104 tags are allowed and can be used where Markdown syntax isn't sufficient. The | 164 tags are allowed and can be used where Markdown syntax isn't sufficient. The |
105 [Attribute Lists](http://pythonhosted.org/Markdown/extensions/attr_list.html) | 165 [Attribute Lists](http://pythonhosted.org/Markdown/extensions/attr_list.html) |
106 extension is active and allows specifying custom attributes for the generated | 166 extension is active and allows specifying custom attributes for the generated |
107 HTML tags. | 167 HTML tags. |
108 | 168 |
109 Localizable strings are retrieved from the locale file with the name matching | 169 Localizable strings are retrieved from the locale file with the name matching |
110 the page name. The following syntax can be used: `$foo$` inserts a string named | 170 the page name. The following syntax can be used: `$foo$` inserts a string named |
111 `foo` from the locale (no HTML code or Markdown syntax allowed in the string). | 171 `foo` from the locale (no HTML code or Markdown syntax allowed in the string). |
112 The syntax `$foo(foopage, http://example.com/)$` will work similarly but will | 172 The syntax `$foo(foopage, http://example.com/)$` will work similarly but will |
113 look for `<a>...</a>` blocks in the string: the first will be turned into a link | 173 look for `<a>...</a>` blocks in the string: the first will be turned into a link |
114 to the page `foopage`, the second will become a link to `http://example.com/`. | 174 to the page `foopage`, the second will become a link to `http://example.com/`. |
115 | 175 |
116 Any content between `<head>` and `</head>` tags will be inserted into the head | 176 Any content between `<head>` and `</head>` tags will be inserted into the head |
117 of the generated web page, this is meant for styles, scripts and the like. | 177 of the generated web page, this is meant for styles, scripts and the like. |
118 Other pages should be linked by using their name as link target (relative links) , | 178 Other pages should be linked by using their name as link target (relative links) , |
119 these links will be resolved to point to the most appropriate page language. | 179 these links will be resolved to point to the most appropriate page language. |
120 Embedding localizable images works the same, use the image name as image source. | 180 Embedding localizable images works the same, use the image name as image source. |
121 | 181 |
122 ### Raw HTML format (raw) ### | 182 #### Raw HTML format (raw) #### |
123 | 183 |
124 This format is similar to the Markdown format but uses regular HTML syntax. | 184 This format is similar to the Markdown format but uses regular HTML syntax. |
125 No processing is performed beyond inserting localized strings and resolving | 185 No processing is performed beyond inserting localized strings and resolving |
126 links to pages and images. This format is mainly meant for legacy content. | 186 links to pages and images. This format is mainly meant for legacy content. |
127 | 187 |
128 ### Jinja2 format (tmpl) ### | 188 #### Jinja2 format (tmpl) #### |
129 | 189 |
130 Complicated pages can be defined using the | 190 Complicated pages can be defined using the |
131 [Jinja2 template format](http://jinja.pocoo.org/docs/templates/). Automatic | 191 [Jinja2 template format](http://jinja.pocoo.org/docs/templates/). Automatic |
132 escaping is active so by default values inserted into the page cannot contain | 192 escaping is active so by default values inserted into the page cannot contain |
133 any HTML code. Any content between `<head>` and `</head>` tags will be inserted | 193 any HTML code. Any content between `<head>` and `</head>` tags will be inserted |
134 into the head of the generated web page, everything else defined the content of | 194 into the head of the generated web page, everything else defined the content of |
135 the page. | 195 the page. |
136 | 196 |
137 The following variables can be used: | 197 The following variables can be used: |
138 | 198 |
139 * `page`: The page name | 199 * `page`: The page name |
140 * `config`: Contents of the `settings.ini` file in this repository (a | 200 * `config`: Contents of the `settings.ini` file in this repository (a |
141 [configparser object](http://docs.python.org/2/library/configparser.html)) | 201 [configparser object](http://docs.python.org/2/library/configparser.html)) |
142 * `locale`: Locale code of the page language | 202 * `locale`: Locale code of the page language |
143 * `available_locales`: Locale codes of all languages available for this page | 203 * `available_locales`: Locale codes of all languages available for this page |
144 | 204 |
145 Following custom filters can be used: | 205 Following custom filters can be used: |
146 | 206 |
147 * `translate(string, locale=None)`: retrieves a string from a locale file. | 207 * `translate(string, locale=None)`: retrieves a string from a locale file. |
148 Unless a locale is specified the locale file matching the page name is used. | 208 Unless a locale is specified the locale file matching the page name is used. |
149 * `linkify(url)`: generates an `<a href="...">` tag for the URL. If the URL is | 209 * `linkify(url)`: generates an `<a href="...">` tag for the URL. If the URL is |
150 a page name it will be converted into a link to the most appropriate page | 210 a page name it will be converted into a link to the most appropriate page |
151 language. | 211 language. |
152 * `toclist(html)`: extracts a list of headings from HTML code, this can be used | 212 * `toclist(html)`: extracts a list of headings from HTML code, this can be used |
153 to generate a table of contents. | 213 to generate a table of contents. |
154 | 214 |
155 ## Static files ## | 215 ### Static files ### |
156 | 216 |
157 Any files located in the `static` directory will be available on the server | 217 Any files located in the `static` directory will be available on the server |
158 unchanged. The file `static/css/foo.css` will be available under the URL | 218 unchanged. The file `static/css/foo.css` will be available under the URL |
159 `/css/foo.css`. | 219 `/css/foo.css`. |
160 | 220 |
161 ## Templates ## | 221 ### Templates ### |
162 | 222 |
163 The templates specified in the `templates` directory specify the overall | 223 The templates specified in the `templates` directory specify the overall |
164 structure that is common for all pages. These templates should have the file | 224 structure that is common for all pages. These templates should have the file |
165 extension `tmpl` and use the [Jinja2 template format](http://jinja.pocoo.org/doc s/templates/). | 225 extension `tmpl` and use the [Jinja2 template format](http://jinja.pocoo.org/doc s/templates/). |
166 The differences to pages using the same format are: | 226 The differences to pages using the same format are: |
167 | 227 |
168 * No special treatment of the `<head>` tag. | 228 * No special treatment of the `<head>` tag. |
169 * Additional variables `head` and `body` are defined with the HTML code that | 229 * Additional variables `head` and `body` are defined with the HTML code that |
170 should be added to the head and content of the page respectively. | 230 should be added to the head and content of the page respectively. |
171 | 231 |
172 By default, `default.tmpl` will be used for all pages. If other templates are | 232 By default, `default.tmpl` will be used for all pages. If other templates are |
173 defined, the pages need to choose them explicitly using the `template` setting. | 233 defined, the pages need to choose them explicitly using the `template` setting. |
234 | |
235 ### Custom filters ### | |
236 | |
237 The `filters` directory can define custom Jinja2 filters which will be available | |
238 in all Jinja2 templates. The file name defines the filter name, e.g. | |
239 `myfilter.py` will define a file named `myfilter`. This file should also contain | |
Sebastian Noack
2015/03/12 09:27:51
I suppose you mean "will define a filter name `myf
Wladimir Palant
2015/03/12 16:40:01
Done.
| |
240 a function called `myfilter`, this one will be called when the filter is | |
241 invoked. For more information on Jinja2 filters see | |
242 [official documentation](http://jinja.pocoo.org/docs/dev/api/#writing-filters). | |
OLD | NEW |