2019-10-17 00:42:54 +02:00
|
|
|
# HTML and CSS
|
|
|
|
|
|
|
|
## Zulip CSS organization
|
|
|
|
|
|
|
|
The Zulip application's CSS can be found in the `static/styles/`
|
|
|
|
directory. Zulip uses [Bootstrap](http://getbootstrap.com/) as its
|
|
|
|
main third-party CSS library.
|
|
|
|
|
|
|
|
Zulip uses SCSS for its CSS files. There are two high-level sections
|
|
|
|
of CSS: the "portico" (logged-out pages like /help/, /login/, etc.),
|
|
|
|
and the app. The portico CSS lives under the `static/styles/portico`
|
|
|
|
subdirectory.
|
|
|
|
|
|
|
|
## Editing Zulip CSS
|
|
|
|
|
|
|
|
If you aren't experienced with doing web development and want to make
|
|
|
|
CSS changes, we recommend reading the excellent [Chrome web inspector
|
|
|
|
guide on editing HTML/CSS](https://developer.chrome.com/devtools/docs/dom-and-styles),
|
|
|
|
especially the [section on
|
|
|
|
CSS](https://developer.chrome.com/devtools/docs/dom-and-styles#styles)
|
|
|
|
to learn about all the great tools that you can use to modify and test
|
|
|
|
changes to CSS interactively in-browser (without even having the
|
|
|
|
reload the page!).
|
|
|
|
|
|
|
|
Zulip's development environment has hot code reloading configured, so
|
|
|
|
changes made in source files will immediately take effect in open
|
|
|
|
browser windows, either by live-updating the CSS or reloading the
|
|
|
|
browser window (following backend changes).
|
|
|
|
|
|
|
|
## CSS Style guidelines
|
|
|
|
|
|
|
|
### Avoid duplicated code
|
|
|
|
|
|
|
|
Without care, it's easy for a web application to end up with thousands
|
|
|
|
of lines of duplicated CSS code, which can make it very difficult to
|
|
|
|
understand the current styling or modify it. We would very much like
|
|
|
|
to avoid such a fate. So please make an effort to reuse existing
|
|
|
|
styling, clean up now-unused CSS, etc., to keep things maintainable.
|
|
|
|
|
|
|
|
### Be consistent with existing similar UI
|
|
|
|
|
|
|
|
Ideally, do this by reusing existing CSS declarations, so that any
|
|
|
|
improvements we make to the styling can improve all similar UI
|
|
|
|
elements.
|
|
|
|
|
|
|
|
### Use clear, unique names for classes and object IDs
|
|
|
|
|
|
|
|
This makes it much easier to read the code and use `git grep` to find
|
|
|
|
where a particular class is used.
|
|
|
|
|
|
|
|
## Validating CSS
|
|
|
|
|
|
|
|
When changing any part of the Zulip CSS, it's important to check that
|
|
|
|
the new CSS looks good at a wide range of screen widths, from very
|
|
|
|
wide screen (e.g. 1920px) all the way down to narrow phone screens
|
|
|
|
(e.g. 480px).
|
|
|
|
|
|
|
|
For complex changes, it's definitely worth testing in a few different
|
|
|
|
browsers to make sure things look the same.
|
|
|
|
|
|
|
|
## HTML templates
|
2017-08-22 14:54:08 +02:00
|
|
|
|
|
|
|
### Behavior
|
|
|
|
|
|
|
|
* Templates are automatically recompiled in development when the file
|
|
|
|
is saved; a refresh of the page should be enough to display the latest
|
|
|
|
version. You might need to do a hard refresh, as some browsers cache
|
|
|
|
webpages.
|
|
|
|
|
|
|
|
* Variables can be used in templates. The variables available to the
|
|
|
|
template are called the **context**. Passing the context to the HTML
|
|
|
|
template sets the values of those variables to the value they were
|
|
|
|
given in the context. The sections below contain specifics on how the
|
|
|
|
context is defined and where it can be found.
|
|
|
|
|
2019-10-17 00:42:54 +02:00
|
|
|
### Backend templates
|
2017-08-22 14:54:08 +02:00
|
|
|
|
|
|
|
For text generated in the backend, including logged-out ("portico")
|
|
|
|
pages and the webapp's base content, we use the [Jinja2][] template
|
|
|
|
engine (files in `templates/zerver`).
|
|
|
|
|
|
|
|
The syntax for using conditionals and other common structures can be
|
|
|
|
found [here][jconditionals].
|
|
|
|
|
|
|
|
The context for Jinja2 templates is assembled from a few places:
|
|
|
|
|
|
|
|
* `zulip_default_context` in `zerver/context_processors.py`. This is
|
|
|
|
the default context available to all Jinja2 templates.
|
|
|
|
|
|
|
|
* As an argument in the `render` call in the relevant function that
|
|
|
|
renders the template. For example, if you want to find the context
|
|
|
|
passed to `index.html`, you can do:
|
|
|
|
|
|
|
|
```
|
2018-04-22 07:02:19 +02:00
|
|
|
$ git grep zerver/app/index.html '*.py'
|
|
|
|
zerver/views/home.py: response = render(request, 'zerver/app/index.html',
|
2017-08-22 14:54:08 +02:00
|
|
|
```
|
|
|
|
|
|
|
|
The next line in the code being the context definition.
|
|
|
|
|
|
|
|
* `zproject/urls.py` for some fairly static pages that are rendered
|
|
|
|
using `TemplateView`, for example:
|
|
|
|
|
|
|
|
```
|
|
|
|
url(r'^config-error/google$', TemplateView.as_view(
|
|
|
|
template_name='zerver/config_error.html',),
|
|
|
|
{'google_error': True},),
|
|
|
|
```
|
|
|
|
|
2019-10-17 00:42:54 +02:00
|
|
|
### Frontend templates
|
2017-08-22 14:54:08 +02:00
|
|
|
|
|
|
|
For text generated in the frontend, live-rendering HTML from
|
|
|
|
JavaScript for things like the main message feed, we use the
|
|
|
|
[Handlebars][] template engine (files in `static/templates/`) and
|
|
|
|
sometimes work directly from JavaScript code (though as a policy
|
|
|
|
matter, we try to avoid generating HTML directly in JavaScript
|
|
|
|
wherever possible).
|
|
|
|
|
|
|
|
The syntax for using conditionals and other common structures can be
|
|
|
|
found [here][hconditionals].
|
|
|
|
|
|
|
|
There's no equivalent of `zulip_default_context` for the Handlebars
|
|
|
|
templates.
|
|
|
|
|
2018-04-28 19:44:19 +02:00
|
|
|
### Toolchain
|
|
|
|
|
2019-06-25 11:39:03 +02:00
|
|
|
Handlebars is in our `package.json` and thus ends up in `node_modules`; We use
|
|
|
|
handlebars-loader to load and compile templates during the webpack bundling
|
|
|
|
stage. In the development environment, webpack will trigger a browser reload
|
|
|
|
whenever a template is changed.
|
2018-04-28 19:44:19 +02:00
|
|
|
|
2017-08-22 14:54:08 +02:00
|
|
|
### Translation
|
|
|
|
|
|
|
|
All user-facing strings (excluding pages only visible to sysadmins or
|
|
|
|
developers) should be tagged for [translation][].
|
|
|
|
|
|
|
|
[Jinja2]: http://jinja.pocoo.org/
|
|
|
|
[Handlebars]: http://handlebarsjs.com/
|
|
|
|
[trans]: http://jinja.pocoo.org/docs/dev/templates/#i18n
|
2017-11-08 17:55:36 +01:00
|
|
|
[i18next]: https://www.i18next.com
|
|
|
|
[official]: https://www.i18next.com/plurals.html
|
2017-08-22 14:54:08 +02:00
|
|
|
[helpers]: http://handlebarsjs.com/block_helpers.html
|
|
|
|
[jconditionals]: http://jinja.pocoo.org/docs/2.9/templates/#list-of-control-structures
|
|
|
|
[hconditionals]: http://handlebarsjs.com/block_helpers.html
|
2019-09-30 19:37:56 +02:00
|
|
|
[translation]: ../translating/translating.md
|