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