mirror of https://github.com/zulip/zulip.git
docs: Add comma to all uses of "e.g." in contributor docs.
This commit is contained in:
parent
2bb037f2a0
commit
62d452f983
|
@ -213,13 +213,13 @@ down the line!
|
||||||
- Open up the parts of the UI that were changed, and make sure they look as
|
- Open up the parts of the UI that were changed, and make sure they look as
|
||||||
you were expecting.
|
you were expecting.
|
||||||
- Is the new UI consistent with similar UI elements? Think about fonts, colors,
|
- Is the new UI consistent with similar UI elements? Think about fonts, colors,
|
||||||
sizes, etc. If a new or modified element has multiple states (e.g. "on" and
|
sizes, etc. If a new or modified element has multiple states (e.g., "on" and
|
||||||
"off"), consider all of them.
|
"off"), consider all of them.
|
||||||
- Is the new UI aligned correctly with the elements around it, both vertically and
|
- Is the new UI aligned correctly with the elements around it, both vertically and
|
||||||
horizontally?
|
horizontally?
|
||||||
- If the PR adds or modifies a clickable element, does it have a hover behavior
|
- If the PR adds or modifies a clickable element, does it have a hover behavior
|
||||||
that's consistent with similar UI elements?
|
that's consistent with similar UI elements?
|
||||||
- If the PR adds or modifies an element (e.g. a button or checkbox) that is
|
- If the PR adds or modifies an element (e.g., a button or checkbox) that is
|
||||||
sometimes disabled, is the disabled version of the UI consistent with similar
|
sometimes disabled, is the disabled version of the UI consistent with similar
|
||||||
UI elements?
|
UI elements?
|
||||||
- Did the PR accidentally affect any other parts of the UI? E.g., if the PR
|
- Did the PR accidentally affect any other parts of the UI? E.g., if the PR
|
||||||
|
|
|
@ -171,7 +171,7 @@ This is a **complete sentence** that briefly summarizes your changes. There are
|
||||||
a few rules to keep in mind:
|
a few rules to keep in mind:
|
||||||
|
|
||||||
- Start the sentence with an
|
- Start the sentence with an
|
||||||
[imperative](https://en.wikipedia.org/wiki/Imperative_mood) verb, e.g.
|
[imperative](https://en.wikipedia.org/wiki/Imperative_mood) verb, e.g.,
|
||||||
"fix", "add", "change", "rename", etc.
|
"fix", "add", "change", "rename", etc.
|
||||||
- Use proper capitalization and punctuation.
|
- Use proper capitalization and punctuation.
|
||||||
- Avoid abbreviations and acronyms.
|
- Avoid abbreviations and acronyms.
|
||||||
|
|
|
@ -60,7 +60,7 @@ better decisions as a group, and learn and have fun along the way.
|
||||||
where they are coming from.
|
where they are coming from.
|
||||||
|
|
||||||
- If you think someone is factually mistaken, consider how they might have reached
|
- If you think someone is factually mistaken, consider how they might have reached
|
||||||
their conclusion, and aim to get to a shared understanding. E.g.:
|
their conclusion, and aim to get to a shared understanding. E.g.,:
|
||||||
|
|
||||||
- “I wasn't able to replicate this -- is it possible you are on an old Zulip
|
- “I wasn't able to replicate this -- is it possible you are on an old Zulip
|
||||||
server?”, rather than “This bug report is wrong.”
|
server?”, rather than “This bug report is wrong.”
|
||||||
|
@ -86,7 +86,7 @@ question in the development community, or suggesting a new feature. It's
|
||||||
especially important to thank and encourage folks who are stretching themselves
|
especially important to thank and encourage folks who are stretching themselves
|
||||||
to try something new.
|
to try something new.
|
||||||
|
|
||||||
- Remember to say “thanks” when responding to a question or suggestion. E.g.:
|
- Remember to say “thanks” when responding to a question or suggestion. E.g.,:
|
||||||
|
|
||||||
- “Thanks for the report! ... ” when someone reports a bug.
|
- “Thanks for the report! ... ” when someone reports a bug.
|
||||||
- “Thanks for reviewing my PR! ... ”
|
- “Thanks for reviewing my PR! ... ”
|
||||||
|
@ -101,7 +101,7 @@ to try something new.
|
||||||
|
|
||||||
- You can use a variety of channels to express your appreciation. A comment
|
- You can use a variety of channels to express your appreciation. A comment
|
||||||
directly in a Zulip thread or on a pull request is often best, but in some
|
directly in a Zulip thread or on a pull request is often best, but in some
|
||||||
cases you may also want to send a friendly direct message. E.g.:
|
cases you may also want to send a friendly direct message. E.g.,:
|
||||||
|
|
||||||
- “I've noticed that you've been answering lots of questions in #**development
|
- “I've noticed that you've been answering lots of questions in #**development
|
||||||
help** lately. Thanks so much for doing that!”
|
help** lately. Thanks so much for doing that!”
|
||||||
|
|
|
@ -171,7 +171,7 @@ actual flows for LDAP configuration.
|
||||||
- To disable fakeldap, set `FAKE_LDAP_MODE` back to `None`.
|
- To disable fakeldap, set `FAKE_LDAP_MODE` back to `None`.
|
||||||
|
|
||||||
- In all fakeldap configurations, users' fake LDAP passwords are equal
|
- In all fakeldap configurations, users' fake LDAP passwords are equal
|
||||||
to their usernames (e.g. for `ldapuser1@zulip.com`, the password is
|
to their usernames (e.g., for `ldapuser1@zulip.com`, the password is
|
||||||
`ldapuser1`).
|
`ldapuser1`).
|
||||||
|
|
||||||
- `FAKE_LDAP_NUM_USERS` in `zproject/dev_settings.py` can be used to
|
- `FAKE_LDAP_NUM_USERS` in `zproject/dev_settings.py` can be used to
|
||||||
|
|
|
@ -151,7 +151,7 @@ guide][rtd-git-guide]. In brief, the steps are as follows.
|
||||||
On your **local computer**:
|
On your **local computer**:
|
||||||
|
|
||||||
1. Open _Terminal_ (macOS/Linux) or _Git for BASH_.
|
1. Open _Terminal_ (macOS/Linux) or _Git for BASH_.
|
||||||
2. Change directory to where you cloned Zulip (e.g. `cd zulip`).
|
2. Change directory to where you cloned Zulip (e.g., `cd zulip`).
|
||||||
3. Use `git add` and `git commit` to stage and commit your changes (if you
|
3. Use `git add` and `git commit` to stage and commit your changes (if you
|
||||||
haven't already).
|
haven't already).
|
||||||
4. Push your commits to GitHub with `git push origin branchname`.
|
4. Push your commits to GitHub with `git push origin branchname`.
|
||||||
|
@ -282,7 +282,7 @@ Next, read the following to learn more about developing for Zulip:
|
||||||
|
|
||||||
## Using an nginx reverse proxy
|
## Using an nginx reverse proxy
|
||||||
|
|
||||||
For some applications (e.g. developing an OAuth2 integration for
|
For some applications (e.g., developing an OAuth2 integration for
|
||||||
Facebook), you may need your Zulip development to have a valid SSL
|
Facebook), you may need your Zulip development to have a valid SSL
|
||||||
certificate. While `run-dev` doesn't support that, you can do this
|
certificate. While `run-dev` doesn't support that, you can do this
|
||||||
with an `nginx` reverse proxy sitting in front of `run-dev`.
|
with an `nginx` reverse proxy sitting in front of `run-dev`.
|
||||||
|
|
|
@ -132,7 +132,7 @@ installation method described here. We require version 0.67.6+ of WSL 2.
|
||||||
$ sudo apt install rabbitmq-server memcached redis-server postgresql
|
$ sudo apt install rabbitmq-server memcached redis-server postgresql
|
||||||
```
|
```
|
||||||
|
|
||||||
1. Open `/etc/rabbitmq/rabbitmq-env.conf` using e.g.:
|
1. Open `/etc/rabbitmq/rabbitmq-env.conf` using e.g.,:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ sudo nano /etc/rabbitmq/rabbitmq-env.conf
|
$ sudo nano /etc/rabbitmq/rabbitmq-env.conf
|
||||||
|
@ -955,7 +955,7 @@ The `vagrant up` command basically does the following:
|
||||||
|
|
||||||
To debug such errors, you can log in to the Vagrant guest machine by
|
To debug such errors, you can log in to the Vagrant guest machine by
|
||||||
running `vagrant ssh`, which should present you with a standard shell
|
running `vagrant ssh`, which should present you with a standard shell
|
||||||
prompt. You can debug interactively by using e.g.
|
prompt. You can debug interactively by using e.g.,
|
||||||
`cd zulip && ./tools/provision`, and then running the individual
|
`cd zulip && ./tools/provision`, and then running the individual
|
||||||
subcommands that failed. Once you've resolved the problem, you can
|
subcommands that failed. Once you've resolved the problem, you can
|
||||||
rerun `tools/provision` to proceed; the provisioning system is
|
rerun `tools/provision` to proceed; the provisioning system is
|
||||||
|
@ -1094,7 +1094,7 @@ NO_PROXY localhost,127.0.0.1,.example.com,.zulipdev.com
|
||||||
```
|
```
|
||||||
|
|
||||||
For proxies that require authentication, the config will be a bit more
|
For proxies that require authentication, the config will be a bit more
|
||||||
complex, e.g.:
|
complex, e.g.,:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
HTTP_PROXY http://userName:userPassword@192.168.1.1:8080
|
HTTP_PROXY http://userName:userPassword@192.168.1.1:8080
|
||||||
|
@ -1119,7 +1119,7 @@ then do a `vagrant reload`.
|
||||||
### Using a different port for Vagrant
|
### Using a different port for Vagrant
|
||||||
|
|
||||||
You can also change the port on the host machine that Vagrant uses by
|
You can also change the port on the host machine that Vagrant uses by
|
||||||
adding to your `~/.zulip-vagrant-config` file. E.g. if you set:
|
adding to your `~/.zulip-vagrant-config` file. E.g., if you set:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
HOST_PORT 9971
|
HOST_PORT 9971
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
If you ever want to recreate your development environment again from
|
If you ever want to recreate your development environment again from
|
||||||
scratch (e.g. to test a change you've made to the provisioning
|
scratch (e.g., to test a change you've made to the provisioning
|
||||||
process, or because you think something is broken), you can do so
|
process, or because you think something is broken), you can do so
|
||||||
using `vagrant destroy` and then `vagrant up`. This will usually be
|
using `vagrant destroy` and then `vagrant up`. This will usually be
|
||||||
much faster than the original `vagrant up` since the base image is
|
much faster than the original `vagrant up` since the base image is
|
||||||
already cached on your machine (it takes about 5 minutes to run with a
|
already cached on your machine (it takes about 5 minutes to run with a
|
||||||
fast Internet connection).
|
fast Internet connection).
|
||||||
|
|
||||||
Any additional programs (e.g. Zsh, emacs, etc.) or configuration that
|
Any additional programs (e.g., Zsh, emacs, etc.) or configuration that
|
||||||
you may have installed in the development environment will be lost
|
you may have installed in the development environment will be lost
|
||||||
when you recreate it. To address this, you can create a script called
|
when you recreate it. To address this, you can create a script called
|
||||||
`tools/custom_provision` in your Zulip Git checkout; and place any
|
`tools/custom_provision` in your Zulip Git checkout; and place any
|
||||||
|
|
|
@ -62,7 +62,7 @@ branch, or a significant time has passed since you last used it.
|
||||||
### Test an install
|
### Test an install
|
||||||
|
|
||||||
The `test-install` tooling takes a distribution release name
|
The `test-install` tooling takes a distribution release name
|
||||||
(e.g. "jammy"), the path to an unpacked release directory
|
(e.g., "jammy"), the path to an unpacked release directory
|
||||||
or tarball, and then any of the normal options you want to pass down
|
or tarball, and then any of the normal options you want to pass down
|
||||||
into the installer.
|
into the installer.
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ the development environment][authentication-dev-server].
|
||||||
## Common
|
## Common
|
||||||
|
|
||||||
- Zulip's `main` branch moves quickly, and you should rebase
|
- Zulip's `main` branch moves quickly, and you should rebase
|
||||||
constantly with e.g.
|
constantly with e.g.,
|
||||||
`git fetch upstream; git rebase upstream/main` to avoid developing
|
`git fetch upstream; git rebase upstream/main` to avoid developing
|
||||||
on an old version of the Zulip codebase (leading to unnecessary
|
on an old version of the Zulip codebase (leading to unnecessary
|
||||||
merge conflicts).
|
merge conflicts).
|
||||||
|
|
|
@ -354,7 +354,7 @@ it? There's several major benefits to this system:
|
||||||
pre-substituted for the user.
|
pre-substituted for the user.
|
||||||
- We're able to share implementation language and visual styling with
|
- We're able to share implementation language and visual styling with
|
||||||
our Help Center, which is especially useful for the extensive
|
our Help Center, which is especially useful for the extensive
|
||||||
non-REST API documentation pages (e.g. our bot framework).
|
non-REST API documentation pages (e.g., our bot framework).
|
||||||
|
|
||||||
Using the standard OpenAPI format gives us flexibility, though; if we
|
Using the standard OpenAPI format gives us flexibility, though; if we
|
||||||
later choose to migrate to third-party tools, we don't need to redo
|
later choose to migrate to third-party tools, we don't need to redo
|
||||||
|
@ -393,7 +393,7 @@ documentation for the REST API endpoint for uploading a file,
|
||||||
There are no parameters for this endpoint, and only one return value
|
There are no parameters for this endpoint, and only one return value
|
||||||
specific to this endpoint, `uri`, which is the URL of the uploaded file.
|
specific to this endpoint, `uri`, which is the URL of the uploaded file.
|
||||||
If we comment out that return value and example from the existing API
|
If we comment out that return value and example from the existing API
|
||||||
documentation in `zerver/openapi/zulip.yaml`, e.g.:
|
documentation in `zerver/openapi/zulip.yaml`, e.g.,:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
/user_uploads:
|
/user_uploads:
|
||||||
|
|
|
@ -19,7 +19,7 @@ and a handful of longer guides. The feature articles serve a few different purpo
|
||||||
organization settings.
|
organization settings.
|
||||||
|
|
||||||
Zulip help center documentation is available under `/help/` on any Zulip server;
|
Zulip help center documentation is available under `/help/` on any Zulip server;
|
||||||
(e.g. <https://zulip.com/help/> or `http://localhost:9991/help/` in
|
(e.g., <https://zulip.com/help/> or `http://localhost:9991/help/` in
|
||||||
the Zulip development environment). The help center documentation is not hosted
|
the Zulip development environment). The help center documentation is not hosted
|
||||||
on ReadTheDocs, since Zulip supports running a server completely disconnected
|
on ReadTheDocs, since Zulip supports running a server completely disconnected
|
||||||
from the Internet, and we'd like the documentation to be available in that
|
from the Internet, and we'd like the documentation to be available in that
|
||||||
|
@ -55,7 +55,7 @@ There are over 100 feature articles and longer guides in the
|
||||||
the current documentation as a resource and guide as you begin.
|
the current documentation as a resource and guide as you begin.
|
||||||
|
|
||||||
- Use the list on [Zulip help center home](https://zulip.com/help/)
|
- Use the list on [Zulip help center home](https://zulip.com/help/)
|
||||||
to find the section of the docs (e.g. Preferences, Sending
|
to find the section of the docs (e.g., Preferences, Sending
|
||||||
messages, Reading messages, etc.) that relates to the new feature
|
messages, Reading messages, etc.) that relates to the new feature
|
||||||
you're documenting.
|
you're documenting.
|
||||||
|
|
||||||
|
@ -144,7 +144,7 @@ updating existing documentation:
|
||||||
An anti-pattern is trying to make up for bad UX by adding help center
|
An anti-pattern is trying to make up for bad UX by adding help center
|
||||||
documentation. It's worth remembering that for most articles, almost 100% of
|
documentation. It's worth remembering that for most articles, almost 100% of
|
||||||
the users of the feature will never read the article. Instructions for
|
the users of the feature will never read the article. Instructions for
|
||||||
filling out forms, interacting with UI widgets (e.g. typeaheads), interacting
|
filling out forms, interacting with UI widgets (e.g., typeaheads), interacting
|
||||||
with modals, etc. should never go in the help center documentation.
|
with modals, etc. should never go in the help center documentation.
|
||||||
In such cases, you may be able to fix the problem by adding text in-app,
|
In such cases, you may be able to fix the problem by adding text in-app,
|
||||||
where the user will see it as they are interacting with the feature.
|
where the user will see it as they are interacting with the feature.
|
||||||
|
@ -208,7 +208,7 @@ as guidance when documenting Zulip's features.
|
||||||
### User interface
|
### User interface
|
||||||
|
|
||||||
When you refer to the features in the Zulip UI, you should **bold** the
|
When you refer to the features in the Zulip UI, you should **bold** the
|
||||||
feature's name followed by the feature itself (e.g. **Settings** page,
|
feature's name followed by the feature itself (e.g., **Settings** page,
|
||||||
**Change password** button, **Email** field). No quotation marks should be
|
**Change password** button, **Email** field). No quotation marks should be
|
||||||
used. Use **bold** for channel names, and quotation marks for topic names.
|
used. Use **bold** for channel names, and quotation marks for topic names.
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ an arrow key (↑, ↓, ←, →) will also need the `"arrow-key"` CSS class inc
|
||||||
in the `<kbd>` start tag (e.g., ` <kbd class="arrow-key">↑</kbd>`).
|
in the `<kbd>` start tag (e.g., ` <kbd class="arrow-key">↑</kbd>`).
|
||||||
|
|
||||||
Use the labels one sees on the actual keyboard rather than the letter they
|
Use the labels one sees on the actual keyboard rather than the letter they
|
||||||
produce when pressed (e.g. `R` and `Shift` + `R` rather than `r` and `R`).
|
produce when pressed (e.g., `R` and `Shift` + `R` rather than `r` and `R`).
|
||||||
For symbols, such as `?` or `@`, that are produced through key combinations that
|
For symbols, such as `?` or `@`, that are produced through key combinations that
|
||||||
change depending on the user's keyboard layout, you should use the symbol as it
|
change depending on the user's keyboard layout, you should use the symbol as it
|
||||||
appears on a keyboard instead of any specific combination of keys.
|
appears on a keyboard instead of any specific combination of keys.
|
||||||
|
@ -290,7 +290,7 @@ your documentation to help improve its readability:
|
||||||
### Images
|
### Images
|
||||||
|
|
||||||
Images and screenshots should be included in help center documentation
|
Images and screenshots should be included in help center documentation
|
||||||
only if they will help guide the user in how to do something (e.g. if
|
only if they will help guide the user in how to do something (e.g., if
|
||||||
the image will make it much clearer which element on the page the user
|
the image will make it much clearer which element on the page the user
|
||||||
should interact with). For instance, an image of an element should
|
should interact with). For instance, an image of an element should
|
||||||
not be included if the element the user needs to interact with is the
|
not be included if the element the user needs to interact with is the
|
||||||
|
@ -435,7 +435,7 @@ languages in API docs, etc. To create a tab switcher, write:
|
||||||
{end_tabs}
|
{end_tabs}
|
||||||
```
|
```
|
||||||
|
|
||||||
The tab identifiers (e.g. `desktop-web` above) and their mappings to
|
The tab identifiers (e.g., `desktop-web` above) and their mappings to
|
||||||
the tabs' labels are declared in
|
the tabs' labels are declared in
|
||||||
[zerver/lib/markdown/tabbed_sections.py][tabbed-sections-code].
|
[zerver/lib/markdown/tabbed_sections.py][tabbed-sections-code].
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ for every pull request, accessible from a "Details" link in the
|
||||||
to submit a screenshot with any pull request modifying documentation
|
to submit a screenshot with any pull request modifying documentation
|
||||||
to help make reviews efficient.
|
to help make reviews efficient.
|
||||||
|
|
||||||
If you want to build the developer documentation locally (e.g. to test
|
If you want to build the developer documentation locally (e.g., to test
|
||||||
your changes), the dependencies are automatically installed as part of
|
your changes), the dependencies are automatically installed as part of
|
||||||
Zulip development environment provisioning, and you can build the
|
Zulip development environment provisioning, and you can build the
|
||||||
documentation using:
|
documentation using:
|
||||||
|
@ -58,7 +58,7 @@ documentation using:
|
||||||
and then opening `http://127.0.0.1:9991/docs/index.html` in your
|
and then opening `http://127.0.0.1:9991/docs/index.html` in your
|
||||||
browser. The raw files are available at
|
browser. The raw files are available at
|
||||||
`file:///path/to/zulip/docs/_build/html/index.html` in your browser
|
`file:///path/to/zulip/docs/_build/html/index.html` in your browser
|
||||||
(so you can also use e.g. `firefox docs/_build/html/index.html` from
|
(so you can also use e.g., `firefox docs/_build/html/index.html` from
|
||||||
the root of your Zulip checkout).
|
the root of your Zulip checkout).
|
||||||
|
|
||||||
If you are adding a new page to the table of contents, you will want
|
If you are adding a new page to the table of contents, you will want
|
||||||
|
|
|
@ -19,7 +19,7 @@ In the Zulip project, we encourage submitting [draft pull
|
||||||
requests][github-help-draft-pr] early and often. This allows you to
|
requests][github-help-draft-pr] early and often. This allows you to
|
||||||
share your code to make it easier to get feedback and help with your
|
share your code to make it easier to get feedback and help with your
|
||||||
changes, even if you don't think your pull request is ready to be
|
changes, even if you don't think your pull request is ready to be
|
||||||
merged (e.g. it might not work or pass tests). This sets expectations
|
merged (e.g., it might not work or pass tests). This sets expectations
|
||||||
correctly for any feedback from other developers, and prevents your
|
correctly for any feedback from other developers, and prevents your
|
||||||
work from being merged before you're confident in it.
|
work from being merged before you're confident in it.
|
||||||
|
|
||||||
|
|
|
@ -410,7 +410,7 @@ To git@github.com:christi3k/zulip.git
|
||||||
! [rejected] 1754-docs-add-git-workflow -> 1754-docs-add-git-workflow (non-fast-forward)
|
! [rejected] 1754-docs-add-git-workflow -> 1754-docs-add-git-workflow (non-fast-forward)
|
||||||
error: failed to push some refs to 'git@github.com:christi3k/zulip.git'
|
error: failed to push some refs to 'git@github.com:christi3k/zulip.git'
|
||||||
hint: Updates were rejected because the tip of your current branch is behind
|
hint: Updates were rejected because the tip of your current branch is behind
|
||||||
hint: its remote counterpart. Integrate the remote changes (e.g.
|
hint: its remote counterpart. Integrate the remote changes (e.g.,
|
||||||
hint: 'git pull ...') before pushing again.
|
hint: 'git pull ...') before pushing again.
|
||||||
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
|
hint: See the 'Note about fast-forwards' in 'git push --help' for details.
|
||||||
```
|
```
|
||||||
|
|
|
@ -120,7 +120,7 @@ HEAD is now at 5a1e982 tools: Update clean-branches to clean review branches.
|
||||||
`tools/push-to-pull-request` is primarily useful for maintainers who
|
`tools/push-to-pull-request` is primarily useful for maintainers who
|
||||||
are merging other users' commits into a Zulip repository. After doing
|
are merging other users' commits into a Zulip repository. After doing
|
||||||
`reset-to-pull-request` or `fetch-pull-request` and making some
|
`reset-to-pull-request` or `fetch-pull-request` and making some
|
||||||
changes, you can push a branch back to a pull request with e.g.
|
changes, you can push a branch back to a pull request with e.g.,
|
||||||
`tools/push-to-pull-request 1234`. This is useful for a few things:
|
`tools/push-to-pull-request 1234`. This is useful for a few things:
|
||||||
|
|
||||||
- Getting CI to run and enabling you to use the GitHub "Merge" buttons
|
- Getting CI to run and enabling you to use the GitHub "Merge" buttons
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
# How to have an amazing experience
|
# How to have an amazing experience
|
||||||
|
|
||||||
If you are joining Zulip as part of an outreach program (e.g.
|
If you are joining Zulip as part of an outreach program (e.g.,
|
||||||
[GSoC](https://summerofcode.withgoogle.com/) or
|
[GSoC](https://summerofcode.withgoogle.com/) or
|
||||||
[Outreachy](https://www.outreachy.org/)), welcome! Please make sure you read
|
[Outreachy](https://www.outreachy.org/)), welcome! Please make sure you read
|
||||||
this page carefully early on, and we encourage you to come back to it over the
|
this page carefully early on, and we encourage you to come back to it over the
|
||||||
|
@ -125,7 +125,7 @@ You can find many examples in the
|
||||||
working on, not just issue/PR numbers.
|
working on, not just issue/PR numbers.
|
||||||
|
|
||||||
- For projects where you are waiting on feedback, what **type of feedback** is
|
- For projects where you are waiting on feedback, what **type of feedback** is
|
||||||
needed (e.g. product review, next round of code review after initial
|
needed (e.g., product review, next round of code review after initial
|
||||||
feedback has been addressed, answer to some question, etc.). Use [silent
|
feedback has been addressed, answer to some question, etc.). Use [silent
|
||||||
mentions](https://zulip.com/help/mention-a-user-or-group#silently-mention-a-user)
|
mentions](https://zulip.com/help/mention-a-user-or-group#silently-mention-a-user)
|
||||||
to indicate whose feedback is required, if you think you know who it should
|
to indicate whose feedback is required, if you think you know who it should
|
||||||
|
@ -183,7 +183,7 @@ time, start by quickly sharing your initial thoughts or feedback on the general
|
||||||
direction, and let the PR author know when you expect to provide a more detailed
|
direction, and let the PR author know when you expect to provide a more detailed
|
||||||
review.
|
review.
|
||||||
|
|
||||||
Make sure the GitHub comments on the PR are always clear on the status -- e.g.
|
Make sure the GitHub comments on the PR are always clear on the status -- e.g.,
|
||||||
buddy code review has been requested, feedback is being discussed, code buddy
|
buddy code review has been requested, feedback is being discussed, code buddy
|
||||||
has approved the PR, etc. This will help project maintainers know when it's time
|
has approved the PR, etc. This will help project maintainers know when it's time
|
||||||
to move on to the next step of the review process.
|
to move on to the next step of the review process.
|
||||||
|
|
|
@ -90,7 +90,7 @@ requests to those services, but the Django-based database libraries we
|
||||||
use in most of our codebase don't support that, and in any case,
|
use in most of our codebase don't support that, and in any case,
|
||||||
our architecture doesn't require Tornado to do that).
|
our architecture doesn't require Tornado to do that).
|
||||||
|
|
||||||
The parts that are activated relatively rarely (e.g. when people type or
|
The parts that are activated relatively rarely (e.g., when people type or
|
||||||
click on something) are processed by the Django application server.
|
click on something) are processed by the Django application server.
|
||||||
|
|
||||||
There is detailed documentation on the
|
There is detailed documentation on the
|
||||||
|
@ -209,7 +209,7 @@ RabbitMQ is a queueing system. Its config files live in
|
||||||
`zulip/puppet/zulip/files/rabbitmq`. Initial configuration happens in
|
`zulip/puppet/zulip/files/rabbitmq`. Initial configuration happens in
|
||||||
`zulip/scripts/setup/configure-rabbitmq`.
|
`zulip/scripts/setup/configure-rabbitmq`.
|
||||||
|
|
||||||
We use RabbitMQ for queuing expensive work (e.g. sending emails
|
We use RabbitMQ for queuing expensive work (e.g., sending emails
|
||||||
triggered by a message, push notifications, some analytics, etc.) that
|
triggered by a message, push notifications, some analytics, etc.) that
|
||||||
require reliable delivery but which we don't want to do on the main
|
require reliable delivery but which we don't want to do on the main
|
||||||
thread. It's also used for communication between the application server
|
thread. It's also used for communication between the application server
|
||||||
|
@ -256,7 +256,7 @@ administrator, e.g., in case of outages.
|
||||||
This component is intended to install Nagios plugins intended to be run
|
This component is intended to install Nagios plugins intended to be run
|
||||||
on a Nagios server; most of the Zulip Nagios plugins are intended to be
|
on a Nagios server; most of the Zulip Nagios plugins are intended to be
|
||||||
run on the Zulip servers themselves, and are included with the relevant
|
run on the Zulip servers themselves, and are included with the relevant
|
||||||
component of the Zulip server (e.g.
|
component of the Zulip server (e.g.,
|
||||||
`puppet/zulip/manifests/postgresql_backups.pp` installs a few under
|
`puppet/zulip/manifests/postgresql_backups.pp` installs a few under
|
||||||
`/usr/lib/nagios/plugins/zulip_backups`).
|
`/usr/lib/nagios/plugins/zulip_backups`).
|
||||||
|
|
||||||
|
|
|
@ -198,7 +198,7 @@ _Released 2024-03-19_
|
||||||
- Fixed the “Topics are required for this organization” pop-up incorrectly
|
- Fixed the “Topics are required for this organization” pop-up incorrectly
|
||||||
closing on some keypresses.
|
closing on some keypresses.
|
||||||
- Fixed the analytics cron job leaking its lock if unexpectedly interrupted
|
- Fixed the analytics cron job leaking its lock if unexpectedly interrupted
|
||||||
(e.g. by a reboot).
|
(e.g., by a reboot).
|
||||||
- Fixed sorting by expiration date in the “Invites” settings panel.
|
- Fixed sorting by expiration date in the “Invites” settings panel.
|
||||||
- Fixed the gear menu staying open after clicking on “plan management”.
|
- Fixed the gear menu staying open after clicking on “plan management”.
|
||||||
- Fixed a small visual issue with bot icons in the left sidebar DM section.
|
- Fixed a small visual issue with bot icons in the left sidebar DM section.
|
||||||
|
@ -1697,7 +1697,7 @@ _Released 2021-07-22_
|
||||||
- Fixed a performance/scalability issue for installations using the S3
|
- Fixed a performance/scalability issue for installations using the S3
|
||||||
file uploads backend.
|
file uploads backend.
|
||||||
- Fixed a bug where users could turn other users’ messages they could
|
- Fixed a bug where users could turn other users’ messages they could
|
||||||
read into widgets (e.g. polls).
|
read into widgets (e.g., polls).
|
||||||
- Fixed a bug where emoji and avatar image requests were sent through
|
- Fixed a bug where emoji and avatar image requests were sent through
|
||||||
Camo; doing so does not add any security benefit, and broke custom
|
Camo; doing so does not add any security benefit, and broke custom
|
||||||
emoji that had been imported from Slack in Zulip 1.8.1 or earlier.
|
emoji that had been imported from Slack in Zulip 1.8.1 or earlier.
|
||||||
|
@ -1813,7 +1813,7 @@ _Released 2021-05-13_
|
||||||
`zulip::foo` to `zulip::profile::foo`. Configuration referencing
|
`zulip::foo` to `zulip::profile::foo`. Configuration referencing
|
||||||
these `/etc/zulip/zulip.conf` will be automatically updated during
|
these `/etc/zulip/zulip.conf` will be automatically updated during
|
||||||
the upgrade process, but if you have a complex deployment or you
|
the upgrade process, but if you have a complex deployment or you
|
||||||
maintain `zulip.conf` is another system (E.g. with the [manual
|
maintain `zulip.conf` is another system (e.g., with the [manual
|
||||||
configuration][docker-zulip-manual] option for
|
configuration][docker-zulip-manual] option for
|
||||||
[docker-zulip][docker-zulip]), you'll want to manually update the
|
[docker-zulip][docker-zulip]), you'll want to manually update the
|
||||||
`puppet_classes` variable.
|
`puppet_classes` variable.
|
||||||
|
@ -1895,7 +1895,7 @@ _Released 2021-05-13_
|
||||||
unsubscribe links.
|
unsubscribe links.
|
||||||
- Password forms now have a "Show password" widget.
|
- Password forms now have a "Show password" widget.
|
||||||
- Fixed performance issues when creating hundreds of new users in
|
- Fixed performance issues when creating hundreds of new users in
|
||||||
quick succession (E.g. at the start of a conference or event).
|
quick succession (e.g., at the start of a conference or event).
|
||||||
- Fixed performance issues in organizations with thousands of online users.
|
- Fixed performance issues in organizations with thousands of online users.
|
||||||
- Fixed numerous rare exceptions when running Zulip at scale.
|
- Fixed numerous rare exceptions when running Zulip at scale.
|
||||||
- Fixed several subtle installer bugs.
|
- Fixed several subtle installer bugs.
|
||||||
|
@ -3439,7 +3439,7 @@ _Released 2017-10-25_
|
||||||
- Switched from npm to yarn for downloading JS packages.
|
- Switched from npm to yarn for downloading JS packages.
|
||||||
- Switched the function of the 'q' and 'w' search hotkeys.
|
- Switched the function of the 'q' and 'w' search hotkeys.
|
||||||
- Simplified the settings for configuring senders for our emails.
|
- Simplified the settings for configuring senders for our emails.
|
||||||
- Emoji can now be typed with spaces, e.g. entering "robot face" in
|
- Emoji can now be typed with spaces, e.g., entering "robot face" in
|
||||||
the typeahead as well as "robot_face".
|
the typeahead as well as "robot_face".
|
||||||
- Improved title and alt text for Unicode emoji.
|
- Improved title and alt text for Unicode emoji.
|
||||||
- Added development tools to make iterating on emails and error pages easy.
|
- Added development tools to make iterating on emails and error pages easy.
|
||||||
|
@ -3657,7 +3657,7 @@ _Released 2017-02-06_
|
||||||
notifications.
|
notifications.
|
||||||
- Added buttons to download .zuliprc files.
|
- Added buttons to download .zuliprc files.
|
||||||
- Added italics and strikethrough support in Markdown implementation.
|
- Added italics and strikethrough support in Markdown implementation.
|
||||||
- Added errors for common installations mistakes (e.g. too little RAM).
|
- Added errors for common installations mistakes (e.g., too little RAM).
|
||||||
- Added a new /authors page showing the contributors to the current
|
- Added a new /authors page showing the contributors to the current
|
||||||
Zulip version.
|
Zulip version.
|
||||||
- Added illustrations to the 404 and 500 pages.
|
- Added illustrations to the 404 and 500 pages.
|
||||||
|
@ -3678,7 +3678,7 @@ _Released 2017-02-06_
|
||||||
- Fixed Zulip Tornado service not working with http_proxy set in environment.
|
- Fixed Zulip Tornado service not working with http_proxy set in environment.
|
||||||
- Fixed text overflow in stream subscriptions.
|
- Fixed text overflow in stream subscriptions.
|
||||||
- Fixed CSS issues with message topic editing.
|
- Fixed CSS issues with message topic editing.
|
||||||
- Fixed several transactionality bugs (e.g. in Huddle creation).
|
- Fixed several transactionality bugs (e.g., in Huddle creation).
|
||||||
- Fixed missed-message email configuration error handling.
|
- Fixed missed-message email configuration error handling.
|
||||||
- Fixed annoying @-mentions in Jira integration.
|
- Fixed annoying @-mentions in Jira integration.
|
||||||
- Fixed various mismatches between frontend and backend Markdown
|
- Fixed various mismatches between frontend and backend Markdown
|
||||||
|
@ -3892,7 +3892,7 @@ _Released 2016-05-02_
|
||||||
- Added options for configuring PostgreSQL, RabbitMQ, Redis, and memcached
|
- Added options for configuring PostgreSQL, RabbitMQ, Redis, and memcached
|
||||||
in settings.py.
|
in settings.py.
|
||||||
- Added documentation on using Hubot to integrate with useful services
|
- Added documentation on using Hubot to integrate with useful services
|
||||||
not yet integrated with Zulip directly (e.g. Google Hangouts).
|
not yet integrated with Zulip directly (e.g., Google Hangouts).
|
||||||
- Added new management command to test sending email from Zulip.
|
- Added new management command to test sending email from Zulip.
|
||||||
- Added Codeship, Pingdom, Taiga, TeamCity, and Yo integrations.
|
- Added Codeship, Pingdom, Taiga, TeamCity, and Yo integrations.
|
||||||
- Added Nagios plugins to the main distribution.
|
- Added Nagios plugins to the main distribution.
|
||||||
|
|
|
@ -92,7 +92,7 @@ Django context (i.e. with database access).
|
||||||
|
|
||||||
- `zerver/management/commands/`
|
- `zerver/management/commands/`
|
||||||
[Management commands](../subsystems/management-commands.md) one might run at a
|
[Management commands](../subsystems/management-commands.md) one might run at a
|
||||||
production deployment site (e.g. scripts to change a value or
|
production deployment site (e.g., scripts to change a value or
|
||||||
deactivate a user properly).
|
deactivate a user properly).
|
||||||
|
|
||||||
- `zilencer/management/commands/` includes some dev-specific
|
- `zilencer/management/commands/` includes some dev-specific
|
||||||
|
@ -115,7 +115,7 @@ Django context (i.e. with database access).
|
||||||
- `tools/` Scripts used only in a Zulip development environment.
|
- `tools/` Scripts used only in a Zulip development environment.
|
||||||
These are not included in production release tarballs for Zulip, so
|
These are not included in production release tarballs for Zulip, so
|
||||||
that we can include scripts here one wouldn't want someone to run in
|
that we can include scripts here one wouldn't want someone to run in
|
||||||
production accidentally (e.g. things that delete the Zulip database
|
production accidentally (e.g., things that delete the Zulip database
|
||||||
without prompting).
|
without prompting).
|
||||||
|
|
||||||
- `tools/setup/` Subdirectory of `tools/` for things only used during
|
- `tools/setup/` Subdirectory of `tools/` for things only used during
|
||||||
|
|
|
@ -32,7 +32,7 @@ server repository][zulip-server].
|
||||||
Organizations self-hosting Zulip primarily use stable releases.
|
Organizations self-hosting Zulip primarily use stable releases.
|
||||||
- The numbering scheme is simple: the first digit indicates the major
|
- The numbering scheme is simple: the first digit indicates the major
|
||||||
release series (which we'll refer to as "7.x"). (Before Zulip 3.0,
|
release series (which we'll refer to as "7.x"). (Before Zulip 3.0,
|
||||||
Zulip versions had another digit, e.g. 1.9.2 was a bug fix release
|
Zulip versions had another digit, e.g., 1.9.2 was a bug fix release
|
||||||
in the Zulip 1.9.x major release series).
|
in the Zulip 1.9.x major release series).
|
||||||
- [New major releases][blog-major-releases], like Zulip 7.0, are
|
- [New major releases][blog-major-releases], like Zulip 7.0, are
|
||||||
published every 3-6 months, and contain hundreds of features, bug
|
published every 3-6 months, and contain hundreds of features, bug
|
||||||
|
@ -121,7 +121,7 @@ bug fix release, transparently documenting the issue(s) using the
|
||||||
industry-standard [CVE advisory process](https://cve.mitre.org/).
|
industry-standard [CVE advisory process](https://cve.mitre.org/).
|
||||||
|
|
||||||
When new security releases are published, we simultaneously publish
|
When new security releases are published, we simultaneously publish
|
||||||
the fixes to the `main` and stable release branches (E.g. `4.x`), so
|
the fixes to the `main` and stable release branches (e.g., `4.x`), so
|
||||||
that anyone using those branches can immediately upgrade as well.
|
that anyone using those branches can immediately upgrade as well.
|
||||||
|
|
||||||
See also our [security model][security-model] documentation.
|
See also our [security model][security-model] documentation.
|
||||||
|
@ -143,7 +143,7 @@ The nag will appear only to organization administrators starting a
|
||||||
month before the deadline; after that, it will appear for all users on
|
month before the deadline; after that, it will appear for all users on
|
||||||
the server.
|
the server.
|
||||||
|
|
||||||
You can adjust the deadline for your installation by setting e.g.
|
You can adjust the deadline for your installation by setting e.g.,
|
||||||
`SERVER_UPGRADE_NAG_DEADLINE_DAYS = 30 * 21` in
|
`SERVER_UPGRADE_NAG_DEADLINE_DAYS = 30 * 21` in
|
||||||
`/etc/zulip/settings.py` and then [restarting the server](../production/settings.md).
|
`/etc/zulip/settings.py` and then [restarting the server](../production/settings.md).
|
||||||
|
|
||||||
|
|
|
@ -367,7 +367,7 @@ Other fields you may want to sync from LDAP include:
|
||||||
group last, if you'd like a user who is in both groups to be a realm
|
group last, if you'd like a user who is in both groups to be a realm
|
||||||
owner rather than a guest).
|
owner rather than a guest).
|
||||||
|
|
||||||
- String fields like `default_language` (e.g. `en`) or `timezone`, if
|
- String fields like `default_language` (e.g., `en`) or `timezone`, if
|
||||||
you have that data in the right format in your LDAP database.
|
you have that data in the right format in your LDAP database.
|
||||||
|
|
||||||
You can look at the [full list of fields][models-py] in the Zulip user
|
You can look at the [full list of fields][models-py] in the Zulip user
|
||||||
|
@ -544,7 +544,7 @@ it as follows:
|
||||||
metadata and enter them on the right-hand side of this
|
metadata and enter them on the right-hand side of this
|
||||||
Python dictionary:
|
Python dictionary:
|
||||||
1. Set the outer `idp_name` key to be an identifier for your IdP,
|
1. Set the outer `idp_name` key to be an identifier for your IdP,
|
||||||
e.g. `testshib` or `okta`. This field appears in URLs for
|
e.g., `testshib` or `okta`. This field appears in URLs for
|
||||||
parts of your Zulip server's SAML authentication flow.
|
parts of your Zulip server's SAML authentication flow.
|
||||||
2. The IdP should provide the `url` and `entity_id` values.
|
2. The IdP should provide the `url` and `entity_id` values.
|
||||||
3. Save the `x509cert` value to a file; you'll use it in the
|
3. Save the `x509cert` value to a file; you'll use it in the
|
||||||
|
@ -1165,7 +1165,7 @@ If you need to use this feature in combination with those backends,
|
||||||
you should make your logic be applied when processing the
|
you should make your logic be applied when processing the
|
||||||
`ZulipDummyBackend` - which is the final layer of the authentication
|
`ZulipDummyBackend` - which is the final layer of the authentication
|
||||||
checks for whether authentication should succeed. If you want to
|
checks for whether authentication should succeed. If you want to
|
||||||
reject authentication requests e.g. based on IP address of the
|
reject authentication requests e.g., based on IP address of the
|
||||||
request, this is where it should happen.
|
request, this is where it should happen.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
|
|
@ -206,7 +206,7 @@ the following after unpacking a Zulip production release tarball:
|
||||||
```
|
```
|
||||||
|
|
||||||
To run the database on a separate server, including a cloud provider's managed
|
To run the database on a separate server, including a cloud provider's managed
|
||||||
PostgreSQL instance (e.g. AWS RDS), or with a warm-standby replica for
|
PostgreSQL instance (e.g., AWS RDS), or with a warm-standby replica for
|
||||||
reliability, see our [dedicated PostgreSQL documentation][postgresql].
|
reliability, see our [dedicated PostgreSQL documentation][postgresql].
|
||||||
|
|
||||||
[standalone.pp]: https://github.com/zulip/zulip/blob/main/puppet/zulip/manifests/profile/standalone.pp
|
[standalone.pp]: https://github.com/zulip/zulip/blob/main/puppet/zulip/manifests/profile/standalone.pp
|
||||||
|
|
|
@ -80,7 +80,7 @@ with [`EMAIL_USE_SSL = True`](https://docs.djangoproject.com/en/5.0/ref/settings
|
||||||
### Using system email
|
### Using system email
|
||||||
|
|
||||||
If you'd like to send outgoing email using the local operating
|
If you'd like to send outgoing email using the local operating
|
||||||
system's email delivery configuration (e.g. you have `postfix`
|
system's email delivery configuration (e.g., you have `postfix`
|
||||||
configuration on the system that forwards email sent locally into your
|
configuration on the system that forwards email sent locally into your
|
||||||
corporate email system), you will likely need to use something like
|
corporate email system), you will likely need to use something like
|
||||||
these setting values:
|
these setting values:
|
||||||
|
@ -118,7 +118,7 @@ how to make it work:
|
||||||
["less secure"](https://support.google.com/accounts/answer/6010255);
|
["less secure"](https://support.google.com/accounts/answer/6010255);
|
||||||
Gmail doesn't allow servers to send outgoing email by default.
|
Gmail doesn't allow servers to send outgoing email by default.
|
||||||
- Note also that the rate limits for Gmail are also quite low
|
- Note also that the rate limits for Gmail are also quite low
|
||||||
(e.g. 100 / day), so it's easy to get rate-limited if your server
|
(e.g., 100 / day), so it's easy to get rate-limited if your server
|
||||||
has significant traffic. For more active servers, we recommend
|
has significant traffic. For more active servers, we recommend
|
||||||
moving to a free account on a transactional email service.
|
moving to a free account on a transactional email service.
|
||||||
|
|
||||||
|
|
|
@ -123,7 +123,7 @@ When that finishes, your Zulip server should be fully operational again.
|
||||||
|
|
||||||
It's common, when testing backup restoration, to restore backups with a
|
It's common, when testing backup restoration, to restore backups with a
|
||||||
different user-facing hostname than the original server to avoid
|
different user-facing hostname than the original server to avoid
|
||||||
disrupting service (e.g. `zuliptest.example.com` rather than
|
disrupting service (e.g., `zuliptest.example.com` rather than
|
||||||
`zulip.example.com`).
|
`zulip.example.com`).
|
||||||
|
|
||||||
If you do so, just like any other time you change the hostname, you'll
|
If you do so, just like any other time you change the hostname, you'll
|
||||||
|
@ -136,7 +136,7 @@ errors when trying to access it via `zuliptest.example.com`.
|
||||||
|
|
||||||
#### Changing database settings
|
#### Changing database settings
|
||||||
|
|
||||||
If you wish to restore onto a very differently configured host (e.g. with
|
If you wish to restore onto a very differently configured host (e.g., with
|
||||||
`REMOTE_POSTGRES_HOST` set to a different value), you can edit
|
`REMOTE_POSTGRES_HOST` set to a different value), you can edit
|
||||||
`/etc/zulip/settings.py` to configure the host to suit the new host's needs,
|
`/etc/zulip/settings.py` to configure the host to suit the new host's needs,
|
||||||
then restore with `--keep-settings`:
|
then restore with `--keep-settings`:
|
||||||
|
@ -197,7 +197,7 @@ emails to send). You can check whether these queues are empty using
|
||||||
#### Backup details
|
#### Backup details
|
||||||
|
|
||||||
This section is primarily for users managing backups themselves
|
This section is primarily for users managing backups themselves
|
||||||
(E.g. if they're using a remote PostgreSQL database with an existing
|
(e.g., if they're using a remote PostgreSQL database with an existing
|
||||||
backup strategy), and also serves as documentation for what is
|
backup strategy), and also serves as documentation for what is
|
||||||
included in the backups generated by Zulip's standard tools. The
|
included in the backups generated by Zulip's standard tools. The
|
||||||
data includes:
|
data includes:
|
||||||
|
@ -213,7 +213,7 @@ data includes:
|
||||||
will be stored in that directory and you'll want to back it up.
|
will be stored in that directory and you'll want to back it up.
|
||||||
|
|
||||||
- Your Zulip configuration including secrets from `/etc/zulip/`.
|
- Your Zulip configuration including secrets from `/etc/zulip/`.
|
||||||
E.g. if you lose the value of `secret_key`, all users will need to
|
E.g., if you lose the value of `secret_key`, all users will need to
|
||||||
log in again when you set up a replacement server since you won't be
|
log in again when you set up a replacement server since you won't be
|
||||||
able to verify their cookies. If you lose `avatar_salt`, any
|
able to verify their cookies. If you lose `avatar_salt`, any
|
||||||
user-uploaded avatars will need to be re-uploaded (since avatar
|
user-uploaded avatars will need to be re-uploaded (since avatar
|
||||||
|
@ -408,7 +408,7 @@ importing.
|
||||||
|
|
||||||
The commands above create an imported organization on the root domain
|
The commands above create an imported organization on the root domain
|
||||||
(`EXTERNAL_HOST`) of the Zulip installation. You can also import into a
|
(`EXTERNAL_HOST`) of the Zulip installation. You can also import into a
|
||||||
custom subdomain, e.g. if you already have an existing organization on the
|
custom subdomain, e.g., if you already have an existing organization on the
|
||||||
root domain. Replace the last two lines above with the following, after replacing
|
root domain. Replace the last two lines above with the following, after replacing
|
||||||
`<subdomain>` with the desired subdomain.
|
`<subdomain>` with the desired subdomain.
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ recommend starting with sending one to yourself for testing:
|
||||||
./manage.py send_password_reset_email -u username@example.com
|
./manage.py send_password_reset_email -u username@example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
and then once you're ready, you can email them to everyone using e.g.
|
and then once you're ready, you can email them to everyone using e.g.,
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./manage.py send_password_reset_email -r '' --all-users
|
./manage.py send_password_reset_email -r '' --all-users
|
||||||
|
@ -467,7 +467,7 @@ If you're hosting multiple organizations and would like to remove
|
||||||
uploads from a single organization, you'll need to access `realm.id`
|
uploads from a single organization, you'll need to access `realm.id`
|
||||||
in the management shell before deleting the organization from the
|
in the management shell before deleting the organization from the
|
||||||
database (this will be `2` for the first organization created on a
|
database (this will be `2` for the first organization created on a
|
||||||
Zulip server, shown in the example below), e.g.:
|
Zulip server, shown in the example below), e.g.,:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rm -rf /home/zulip/uploads/*/2/
|
rm -rf /home/zulip/uploads/*/2/
|
||||||
|
|
|
@ -54,14 +54,14 @@ unlikely to ever need to interact with that realm.)
|
||||||
Unless you are
|
Unless you are
|
||||||
[hosting multiple organizations on your Zulip server](multiple-organizations.md),
|
[hosting multiple organizations on your Zulip server](multiple-organizations.md),
|
||||||
your single Zulip organization on the root domain will have the empty
|
your single Zulip organization on the root domain will have the empty
|
||||||
string (`''`) as its `string_id`. So you can run e.g.:
|
string (`''`) as its `string_id`. So you can run e.g.,:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
zulip@zulip:~$ /home/zulip/deployments/current/manage.py show_admins -r ''
|
zulip@zulip:~$ /home/zulip/deployments/current/manage.py show_admins -r ''
|
||||||
```
|
```
|
||||||
|
|
||||||
Otherwise, the `string_id` will correspond to the organization's
|
Otherwise, the `string_id` will correspond to the organization's
|
||||||
subdomain. E.g. on `it.zulip.example.com`, use
|
subdomain. E.g., on `it.zulip.example.com`, use
|
||||||
`/home/zulip/deployments/current/manage.py show_admins -r it`.
|
`/home/zulip/deployments/current/manage.py show_admins -r it`.
|
||||||
|
|
||||||
## manage.py shell
|
## manage.py shell
|
||||||
|
|
|
@ -8,7 +8,7 @@ If you do modify Zulip and then report an issue you see in your
|
||||||
modified version of Zulip, please be responsible about communicating
|
modified version of Zulip, please be responsible about communicating
|
||||||
that fact:
|
that fact:
|
||||||
|
|
||||||
- Ideally, you'd reproduce the issue in an unmodified version (e.g. in
|
- Ideally, you'd reproduce the issue in an unmodified version (e.g., in
|
||||||
[the Zulip development community](https://zulip.com/development-community/) or on
|
[the Zulip development community](https://zulip.com/development-community/) or on
|
||||||
[zulip.com](https://zulip.com)).
|
[zulip.com](https://zulip.com)).
|
||||||
- Where that is difficult or you think it's very unlikely your changes
|
- Where that is difficult or you think it's very unlikely your changes
|
||||||
|
@ -159,7 +159,7 @@ responsive in debugging any problems caused by a patch we asked
|
||||||
you to apply.
|
you to apply.
|
||||||
|
|
||||||
Also, consider asking whether a small fix that is important to you can
|
Also, consider asking whether a small fix that is important to you can
|
||||||
be added to the current stable release branch (E.g. `2.1.x`). In
|
be added to the current stable release branch (e.g., `2.1.x`). In
|
||||||
addition to scheduling that change for Zulip's next bug fix release,
|
addition to scheduling that change for Zulip's next bug fix release,
|
||||||
we support changes in stable release branches as though they were
|
we support changes in stable release branches as though they were
|
||||||
released.
|
released.
|
||||||
|
@ -190,8 +190,8 @@ upgrade to Zulip `main` using [upgrade-zulip-from-git][]. Before
|
||||||
upgrading to `main`, make sure you understand:
|
upgrading to `main`, make sure you understand:
|
||||||
|
|
||||||
- In Zulip's version numbering scheme, `main` will always be "newer"
|
- In Zulip's version numbering scheme, `main` will always be "newer"
|
||||||
than the latest maintenance release (E.g. `3.1` or `2.1.6`) and
|
than the latest maintenance release (e.g., `3.1` or `2.1.6`) and
|
||||||
"older" than the next major release (E.g. `3.0` or `4.0`).
|
"older" than the next major release (e.g., `3.0` or `4.0`).
|
||||||
- The `main` branch is under very active development; dozens of new
|
- The `main` branch is under very active development; dozens of new
|
||||||
changes are integrated into it on most days. The `main` branch
|
changes are integrated into it on most days. The `main` branch
|
||||||
can have thousands of changes not present in the latest release (all
|
can have thousands of changes not present in the latest release (all
|
||||||
|
|
|
@ -14,7 +14,7 @@ reading.
|
||||||
|
|
||||||
Zulip's approach for supporting multiple organizations on a single
|
Zulip's approach for supporting multiple organizations on a single
|
||||||
Zulip server is for each organization to be hosted on its own
|
Zulip server is for each organization to be hosted on its own
|
||||||
subdomain. E.g. you'd have `org1.zulip.example.com` and
|
subdomain. E.g., you'd have `org1.zulip.example.com` and
|
||||||
`org2.zulip.example.com`.
|
`org2.zulip.example.com`.
|
||||||
|
|
||||||
Web security standards mean that one subdomain per organization is
|
Web security standards mean that one subdomain per organization is
|
||||||
|
@ -81,12 +81,12 @@ into the database.
|
||||||
### The root domain
|
### The root domain
|
||||||
|
|
||||||
Most Zulip servers host a single Zulip organization on the root domain
|
Most Zulip servers host a single Zulip organization on the root domain
|
||||||
(e.g. `zulip.example.com`). The way this is implemented internally
|
(e.g., `zulip.example.com`). The way this is implemented internally
|
||||||
involves the organization having the empty string (`''`) as its
|
involves the organization having the empty string (`''`) as its
|
||||||
"subdomain".
|
"subdomain".
|
||||||
|
|
||||||
You can mix having an organization on the root domain and some others
|
You can mix having an organization on the root domain and some others
|
||||||
on subdomains (e.g. `subdivision.zulip.example.com`), but this only
|
on subdomains (e.g., `subdivision.zulip.example.com`), but this only
|
||||||
works well if there are no users in common between the two
|
works well if there are no users in common between the two
|
||||||
organizations, because the auth cookies for the root domain are
|
organizations, because the auth cookies for the root domain are
|
||||||
visible to the subdomain (so it's not possible for a single
|
visible to the subdomain (so it's not possible for a single
|
||||||
|
@ -111,7 +111,7 @@ provider with a whitelist of callback URLs to your Zulip server (or
|
||||||
even a single URL). For those vendors that support a whitelist, you
|
even a single URL). For those vendors that support a whitelist, you
|
||||||
can provide the callback URLs for each of your Zulip organizations.
|
can provide the callback URLs for each of your Zulip organizations.
|
||||||
|
|
||||||
The cleaner solution is to register a special subdomain, e.g.
|
The cleaner solution is to register a special subdomain, e.g.,
|
||||||
`auth.zulip.example.com` with the third-party provider, and then set
|
`auth.zulip.example.com` with the third-party provider, and then set
|
||||||
`SOCIAL_AUTH_SUBDOMAIN = 'auth'` in `/etc/zulip/settings.py`, so that
|
`SOCIAL_AUTH_SUBDOMAIN = 'auth'` in `/etc/zulip/settings.py`, so that
|
||||||
Zulip knows to use that subdomain for these authentication callbacks.
|
Zulip knows to use that subdomain for these authentication callbacks.
|
||||||
|
|
|
@ -19,13 +19,13 @@ primary application server. There are two possible flavors of this -- using a
|
||||||
managed PostgreSQL instance from a cloud provider, or separating the PostgreSQL
|
managed PostgreSQL instance from a cloud provider, or separating the PostgreSQL
|
||||||
server onto a separate (but still Zulip-managed) server for scaling purposes.
|
server onto a separate (but still Zulip-managed) server for scaling purposes.
|
||||||
|
|
||||||
### Cloud-provider-managed PostgreSQL (e.g. Amazon RDS)
|
### Cloud-provider-managed PostgreSQL (e.g., Amazon RDS)
|
||||||
|
|
||||||
You can use a database-as-a-service like Amazon RDS for the Zulip database. The
|
You can use a database-as-a-service like Amazon RDS for the Zulip database. The
|
||||||
experience is slightly degraded, in that most providers don't include useful
|
experience is slightly degraded, in that most providers don't include useful
|
||||||
dictionary files in their installations, and don't provide a way to provide them
|
dictionary files in their installations, and don't provide a way to provide them
|
||||||
yourself, resulting in a degraded [full-text search][fts] experience around
|
yourself, resulting in a degraded [full-text search][fts] experience around
|
||||||
issues dictionary files are relevant (e.g. stemming).
|
issues dictionary files are relevant (e.g., stemming).
|
||||||
|
|
||||||
[fts]: ../subsystems/full-text-search.md
|
[fts]: ../subsystems/full-text-search.md
|
||||||
|
|
||||||
|
|
|
@ -99,7 +99,7 @@ on hardware requirements for larger organizations.
|
||||||
features](https://zulip.com/help/allow-image-link-previews).
|
features](https://zulip.com/help/allow-image-link-previews).
|
||||||
- Outgoing SMTP access (usually port 587) to your [SMTP
|
- Outgoing SMTP access (usually port 587) to your [SMTP
|
||||||
server](email.md) so that Zulip can send emails.
|
server](email.md) so that Zulip can send emails.
|
||||||
- A domain name (e.g. `zulip.example.com`) that your users will use to
|
- A domain name (e.g., `zulip.example.com`) that your users will use to
|
||||||
access the Zulip server. In order to generate valid SSL
|
access the Zulip server. In order to generate valid SSL
|
||||||
certificates [with Certbot][doc-certbot], and to enable other
|
certificates [with Certbot][doc-certbot], and to enable other
|
||||||
services such as Google authentication, public DNS name is simpler,
|
services such as Google authentication, public DNS name is simpler,
|
||||||
|
@ -143,7 +143,7 @@ certificate documentation](ssl-certificates.md).
|
||||||
#### Outgoing email
|
#### Outgoing email
|
||||||
|
|
||||||
- Outgoing email (SMTP) credentials that Zulip can use to send
|
- Outgoing email (SMTP) credentials that Zulip can use to send
|
||||||
outgoing emails to users (e.g. email address confirmation emails
|
outgoing emails to users (e.g., email address confirmation emails
|
||||||
during the signup process, message notification emails, password
|
during the signup process, message notification emails, password
|
||||||
reset, etc.). If you don't have an existing outgoing SMTP solution,
|
reset, etc.). If you don't have an existing outgoing SMTP solution,
|
||||||
read about
|
read about
|
||||||
|
@ -158,7 +158,7 @@ This section details some basic guidelines for running a Zulip server
|
||||||
for larger organizations (especially >1000 users or 500+ daily active
|
for larger organizations (especially >1000 users or 500+ daily active
|
||||||
users). Zulip's resource needs depend mainly on 3 parameters:
|
users). Zulip's resource needs depend mainly on 3 parameters:
|
||||||
|
|
||||||
- daily active users (e.g. number of employees if everyone's an
|
- daily active users (e.g., number of employees if everyone's an
|
||||||
employee)
|
employee)
|
||||||
- total user accounts (can be much larger)
|
- total user accounts (can be much larger)
|
||||||
- message volume.
|
- message volume.
|
||||||
|
|
|
@ -87,7 +87,7 @@ that your Zulip server sits at `https://10.10.10.10:443`; see
|
||||||
|
|
||||||
1. Configure the root `nginx.conf` file. We recommend using
|
1. Configure the root `nginx.conf` file. We recommend using
|
||||||
`/etc/nginx/nginx.conf` from your Zulip server for our recommended
|
`/etc/nginx/nginx.conf` from your Zulip server for our recommended
|
||||||
settings. E.g. if you don't set `client_max_body_size`, it won't be
|
settings. E.g., if you don't set `client_max_body_size`, it won't be
|
||||||
possible to upload large files to your Zulip server.
|
possible to upload large files to your Zulip server.
|
||||||
|
|
||||||
1. Configure the `nginx` site-specific configuration (in
|
1. Configure the `nginx` site-specific configuration (in
|
||||||
|
@ -149,7 +149,7 @@ Apache requires you use the hostname, not the IP address; see
|
||||||
|
|
||||||
1. Create an Apache2 virtual host configuration file, similar to the
|
1. Create an Apache2 virtual host configuration file, similar to the
|
||||||
following. Place it the appropriate path for your Apache2
|
following. Place it the appropriate path for your Apache2
|
||||||
installation and enable it (E.g. if you use Debian or Ubuntu, then
|
installation and enable it (e.g., if you use Debian or Ubuntu, then
|
||||||
place it in `/etc/apache2/sites-available/zulip.example.com.conf`
|
place it in `/etc/apache2/sites-available/zulip.example.com.conf`
|
||||||
and then run
|
and then run
|
||||||
`a2ensite zulip.example.com && systemctl reload apache2`):
|
`a2ensite zulip.example.com && systemctl reload apache2`):
|
||||||
|
@ -268,7 +268,7 @@ things you need to be careful about when configuring it:
|
||||||
addresses for a given hostname. This can result in mysterious errors
|
addresses for a given hostname. This can result in mysterious errors
|
||||||
that can be quite difficult to debug. Be sure to declare your
|
that can be quite difficult to debug. Be sure to declare your
|
||||||
`upstreams` equivalent in a way that won't do load-balancing
|
`upstreams` equivalent in a way that won't do load-balancing
|
||||||
unexpectedly (e.g. pointing to a DNS name that you haven't configured
|
unexpectedly (e.g., pointing to a DNS name that you haven't configured
|
||||||
with multiple IPs for your Zulip machine; sometimes this happens with
|
with multiple IPs for your Zulip machine; sometimes this happens with
|
||||||
IPv6 configuration).
|
IPv6 configuration).
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,7 @@ strength allowed is controlled by two settings in
|
||||||
already been sent. As a general philosophy, our policies provide
|
already been sent. As a general philosophy, our policies provide
|
||||||
hard limits on the ways in which message content can be changed or
|
hard limits on the ways in which message content can be changed or
|
||||||
undone. In contrast, our policies around message topics favor
|
undone. In contrast, our policies around message topics favor
|
||||||
usefulness (e.g. for conversational organization) over faithfulness
|
usefulness (e.g., for conversational organization) over faithfulness
|
||||||
to the original. In all configurations:
|
to the original. In all configurations:
|
||||||
|
|
||||||
- Message content can only ever be modified by the original author.
|
- Message content can only ever be modified by the original author.
|
||||||
|
@ -158,7 +158,7 @@ strength allowed is controlled by two settings in
|
||||||
- Administrators can change the ownership of a bot. If a bot is subscribed
|
- Administrators can change the ownership of a bot. If a bot is subscribed
|
||||||
to a private channel, then an administrator can indirectly get access to
|
to a private channel, then an administrator can indirectly get access to
|
||||||
channel messages by taking control of the bot, though the access will be
|
channel messages by taking control of the bot, though the access will be
|
||||||
limited to what the bot can do. (E.g. incoming webhook bots cannot read
|
limited to what the bot can do. (e.g., incoming webhook bots cannot read
|
||||||
messages.)
|
messages.)
|
||||||
|
|
||||||
- Every Zulip user has an API key, available on the settings page.
|
- Every Zulip user has an API key, available on the settings page.
|
||||||
|
@ -187,7 +187,7 @@ strength allowed is controlled by two settings in
|
||||||
|
|
||||||
- Incoming webhook bots can only send messages into Zulip.
|
- Incoming webhook bots can only send messages into Zulip.
|
||||||
- Outgoing webhook bots and Generic bots can essentially do anything a
|
- Outgoing webhook bots and Generic bots can essentially do anything a
|
||||||
non-administrator user can, with a few exceptions (e.g. a bot cannot
|
non-administrator user can, with a few exceptions (e.g., a bot cannot
|
||||||
log in to the web application, register for mobile push
|
log in to the web application, register for mobile push
|
||||||
notifications, or create other bots).
|
notifications, or create other bots).
|
||||||
- Bots with the `can_forge_sender` permission can send messages that appear to have been sent by
|
- Bots with the `can_forge_sender` permission can send messages that appear to have been sent by
|
||||||
|
@ -203,7 +203,7 @@ strength allowed is controlled by two settings in
|
||||||
|
|
||||||
- Zulip supports user-uploaded files. Ideally they should be hosted
|
- Zulip supports user-uploaded files. Ideally they should be hosted
|
||||||
from a separate domain from the main Zulip server to protect against
|
from a separate domain from the main Zulip server to protect against
|
||||||
various same-domain attacks (e.g. zulip-user-content.example.com).
|
various same-domain attacks (e.g., zulip-user-content.example.com).
|
||||||
|
|
||||||
We support two ways of hosting them: the basic `LOCAL_UPLOADS_DIR`
|
We support two ways of hosting them: the basic `LOCAL_UPLOADS_DIR`
|
||||||
file storage backend, where they are stored in a directory on the
|
file storage backend, where they are stored in a directory on the
|
||||||
|
@ -221,7 +221,7 @@ strength allowed is controlled by two settings in
|
||||||
instead of the URL, so this is arguably pretty good protection.)
|
instead of the URL, so this is arguably pretty good protection.)
|
||||||
|
|
||||||
However, to help protect against accidental sharing of URLs to
|
However, to help protect against accidental sharing of URLs to
|
||||||
restricted files (e.g. by forwarding a missed-message email or leaks
|
restricted files (e.g., by forwarding a missed-message email or leaks
|
||||||
involving the Referer header), every access to an uploaded file has
|
involving the Referer header), every access to an uploaded file has
|
||||||
access control verified (confirming that the browser is logged into
|
access control verified (confirming that the browser is logged into
|
||||||
a Zulip account that has received the uploaded file in question).
|
a Zulip account that has received the uploaded file in question).
|
||||||
|
|
|
@ -142,7 +142,7 @@ processes to use][supervisor-minfds]; defaults to 40000. If your Zulip deploymen
|
||||||
is very large (hundreds of thousands of concurrent users), your Django processes
|
is very large (hundreds of thousands of concurrent users), your Django processes
|
||||||
hit this limit and refuse connections to clients. Raising it above this default
|
hit this limit and refuse connections to clients. Raising it above this default
|
||||||
may require changing system-level limits, particularly if you are using a
|
may require changing system-level limits, particularly if you are using a
|
||||||
virtualized environment (e.g. Docker, or Proxmox LXC).
|
virtualized environment (e.g., Docker, or Proxmox LXC).
|
||||||
|
|
||||||
[supervisor-minfds]: http://supervisord.org/configuration.html?highlight=minfds#supervisord-section-values
|
[supervisor-minfds]: http://supervisord.org/configuration.html?highlight=minfds#supervisord-section-values
|
||||||
|
|
||||||
|
|
|
@ -87,11 +87,11 @@ that version of Zulip.
|
||||||
|
|
||||||
Branches with names like `2.1.x` are stable release branches,
|
Branches with names like `2.1.x` are stable release branches,
|
||||||
containing the changes planned for the next minor release
|
containing the changes planned for the next minor release
|
||||||
(E.g. 2.1.5); we support these stable release branches as though they
|
(e.g., 2.1.5); we support these stable release branches as though they
|
||||||
were a published release.
|
were a published release.
|
||||||
|
|
||||||
The `main` branch contains changes planned for the next major
|
The `main` branch contains changes planned for the next major
|
||||||
release (E.g. 3.0); see our documentation on [running
|
release (e.g., 3.0); see our documentation on [running
|
||||||
`main`](modify.md#upgrading-to-main) before upgrading to it.
|
`main`](modify.md#upgrading-to-main) before upgrading to it.
|
||||||
|
|
||||||
By default, this uses the main upstream Zulip server repository, but
|
By default, this uses the main upstream Zulip server repository, but
|
||||||
|
@ -168,7 +168,7 @@ guide](troubleshooting.md).
|
||||||
The upgrade scripts are idempotent, so there's no harm in trying again
|
The upgrade scripts are idempotent, so there's no harm in trying again
|
||||||
after resolving an issue. The most common causes of errors are:
|
after resolving an issue. The most common causes of errors are:
|
||||||
|
|
||||||
- Networking issues (e.g. your Zulip server doesn't have reliable
|
- Networking issues (e.g., your Zulip server doesn't have reliable
|
||||||
Internet access or needs a proxy set up). Fix the networking issue
|
Internet access or needs a proxy set up). Fix the networking issue
|
||||||
and try again.
|
and try again.
|
||||||
- Especially when using `upgrade-zulip-from-git`, systems with the
|
- Especially when using `upgrade-zulip-from-git`, systems with the
|
||||||
|
@ -197,7 +197,7 @@ in any reports.
|
||||||
|
|
||||||
### Rolling back to a prior version
|
### Rolling back to a prior version
|
||||||
|
|
||||||
This rollback process is intended for minor releases (e.g. `2.0.3` to
|
This rollback process is intended for minor releases (e.g., `2.0.3` to
|
||||||
`2.0.6`); a more complicated process is required to roll back database
|
`2.0.6`); a more complicated process is required to roll back database
|
||||||
migrations before downgrading to an older major release.
|
migrations before downgrading to an older major release.
|
||||||
|
|
||||||
|
@ -229,8 +229,8 @@ code, the upgrade will abort.
|
||||||
The hook is run with the following environment variables set:
|
The hook is run with the following environment variables set:
|
||||||
|
|
||||||
- `ZULIP_OLD_VERSION`: The version being upgraded from, which may either be a
|
- `ZULIP_OLD_VERSION`: The version being upgraded from, which may either be a
|
||||||
release name (e.g. `7.0` or `7.0-beta3`) or the output from `git describe`
|
release name (e.g., `7.0` or `7.0-beta3`) or the output from `git describe`
|
||||||
(e.g. `7.0-beta3-2-gdc158b18f2`).
|
(e.g., `7.0-beta3-2-gdc158b18f2`).
|
||||||
- `ZULIP_NEW_VERSION`: The version being upgraded to, in the same format as
|
- `ZULIP_NEW_VERSION`: The version being upgraded to, in the same format as
|
||||||
`ZULIP_OLD_VERSION`.
|
`ZULIP_OLD_VERSION`.
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ hooks included with Zulip.
|
||||||
|
|
||||||
:::{warning}
|
:::{warning}
|
||||||
If you have modified service configuration files installed by
|
If you have modified service configuration files installed by
|
||||||
Zulip (e.g. the nginx configuration), the Zulip upgrade process will
|
Zulip (e.g., the nginx configuration), the Zulip upgrade process will
|
||||||
overwrite your configuration when it does the `puppet apply`.
|
overwrite your configuration when it does the `puppet apply`.
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
@ -292,7 +292,7 @@ and the latter for `server` contexts.
|
||||||
## Upgrading the operating system
|
## Upgrading the operating system
|
||||||
|
|
||||||
When you upgrade the operating system on which Zulip is installed
|
When you upgrade the operating system on which Zulip is installed
|
||||||
(E.g. Ubuntu 20.04 Focal to Ubuntu 22.04 Jammy), you need to take
|
(e.g., Ubuntu 20.04 Focal to Ubuntu 22.04 Jammy), you need to take
|
||||||
some additional steps to update your Zulip installation, documented
|
some additional steps to update your Zulip installation, documented
|
||||||
below.
|
below.
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ instructions for other supported platforms.
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Switch to the root user and upgrade the operating system using the
|
3. Switch to the root user and upgrade the operating system using the
|
||||||
OS's standard tooling. E.g. for Ubuntu, this means running
|
OS's standard tooling. E.g., for Ubuntu, this means running
|
||||||
`do-release-upgrade` and following the prompts until it completes
|
`do-release-upgrade` and following the prompts until it completes
|
||||||
successfully:
|
successfully:
|
||||||
|
|
||||||
|
@ -367,7 +367,7 @@ instructions for other supported platforms.
|
||||||
```
|
```
|
||||||
|
|
||||||
3. Switch to the root user and upgrade the operating system using the
|
3. Switch to the root user and upgrade the operating system using the
|
||||||
OS's standard tooling. E.g. for Ubuntu, this means running
|
OS's standard tooling. E.g., for Ubuntu, this means running
|
||||||
`do-release-upgrade` and following the prompts until it completes
|
`do-release-upgrade` and following the prompts until it completes
|
||||||
successfully:
|
successfully:
|
||||||
|
|
||||||
|
|
|
@ -33,17 +33,17 @@ backend. To enable this backend, you need to do the following:
|
||||||
|
|
||||||
1. Set the `S3_AUTH_UPLOADS_BUCKET` and `S3_AVATAR_BUCKET` settings in
|
1. Set the `S3_AUTH_UPLOADS_BUCKET` and `S3_AVATAR_BUCKET` settings in
|
||||||
`/etc/zulip/settings.py` to be the names of the S3 buckets you
|
`/etc/zulip/settings.py` to be the names of the S3 buckets you
|
||||||
created (e.g. `"exampleinc-zulip-uploads"`).
|
created (e.g., `"exampleinc-zulip-uploads"`).
|
||||||
|
|
||||||
1. Comment out the `LOCAL_UPLOADS_DIR` setting in
|
1. Comment out the `LOCAL_UPLOADS_DIR` setting in
|
||||||
`/etc/zulip/settings.py` (add a `#` at the start of the line).
|
`/etc/zulip/settings.py` (add a `#` at the start of the line).
|
||||||
|
|
||||||
1. If you are using a non-AWS block storage provider,
|
1. If you are using a non-AWS block storage provider,
|
||||||
you need to set the `S3_ENDPOINT_URL` setting to your
|
you need to set the `S3_ENDPOINT_URL` setting to your
|
||||||
endpoint url (e.g. `"https://s3.eu-central-1.amazonaws.com"`).
|
endpoint url (e.g., `"https://s3.eu-central-1.amazonaws.com"`).
|
||||||
|
|
||||||
For certain AWS regions, you may need to set the `S3_REGION`
|
For certain AWS regions, you may need to set the `S3_REGION`
|
||||||
setting to your default AWS region's code (e.g. `"eu-central-1"`).
|
setting to your default AWS region's code (e.g., `"eu-central-1"`).
|
||||||
|
|
||||||
1. Finally, restart the Zulip server so that your settings changes
|
1. Finally, restart the Zulip server so that your settings changes
|
||||||
take effect
|
take effect
|
||||||
|
|
|
@ -7,7 +7,7 @@ designed around the following goals:
|
||||||
|
|
||||||
- Minimal impact on scalability and service complexity.
|
- Minimal impact on scalability and service complexity.
|
||||||
- Well-tested so that we can count on the results being correct.
|
- Well-tested so that we can count on the results being correct.
|
||||||
- Efficient to query so that we can display data in-app (e.g. on the channels
|
- Efficient to query so that we can display data in-app (e.g., on the channels
|
||||||
page) with minimum impact on the overall performance of those pages.
|
page) with minimum impact on the overall performance of those pages.
|
||||||
- Storage size smaller than the size of the main Message/UserMessage
|
- Storage size smaller than the size of the main Message/UserMessage
|
||||||
database tables, so that we can store the data in the main PostgreSQL
|
database tables, so that we can store the data in the main PostgreSQL
|
||||||
|
@ -45,7 +45,7 @@ set of database tables. Each of these tables has the following fields:
|
||||||
an hour (or UTC day) boundary for stats collected at hourly (or daily)
|
an hour (or UTC day) boundary for stats collected at hourly (or daily)
|
||||||
frequency. The time interval is determined by the `CountStat`.
|
frequency. The time interval is determined by the `CountStat`.
|
||||||
- various "id" fields: Foreign keys into `Realm`, `UserProfile`, `Stream`, or
|
- various "id" fields: Foreign keys into `Realm`, `UserProfile`, `Stream`, or
|
||||||
nothing. E.g. the `RealmCount` table has a foreign key into `Realm`.
|
nothing. E.g., the `RealmCount` table has a foreign key into `Realm`.
|
||||||
- value: The integer counts. For `"active_users_audit:is_bot:hour"` in the
|
- value: The integer counts. For `"active_users_audit:is_bot:hour"` in the
|
||||||
`RealmCount` table, this is the number of active humans or bots (depending
|
`RealmCount` table, this is the number of active humans or bots (depending
|
||||||
on subgroup) in a particular realm at a particular `end_time`. For
|
on subgroup) in a particular realm at a particular `end_time`. For
|
||||||
|
@ -114,7 +114,7 @@ efficient:
|
||||||
for this, which is why we use raw database queries (which we usually avoid
|
for this, which is why we use raw database queries (which we usually avoid
|
||||||
in Zulip) rather than the ORM.
|
in Zulip) rather than the ORM.
|
||||||
- Aggregating where possible to avoid unnecessary queries against the
|
- Aggregating where possible to avoid unnecessary queries against the
|
||||||
`Message` and `UserMessage` tables. E.g. rather than querying the `Message`
|
`Message` and `UserMessage` tables. E.g., rather than querying the `Message`
|
||||||
table both to generate sent message counts for each realm and again for
|
table both to generate sent message counts for each realm and again for
|
||||||
each user, we just query for each user, and then add up the numbers for
|
each user, we just query for each user, and then add up the numbers for
|
||||||
the users to get the totals for the realm.
|
the users to get the totals for the realm.
|
||||||
|
@ -147,10 +147,10 @@ analytics tests, to make sure it stays that way as we refactor.
|
||||||
|
|
||||||
The system discussed above is designed primarily around the technical
|
The system discussed above is designed primarily around the technical
|
||||||
problem of showing useful analytics about things where the raw data is
|
problem of showing useful analytics about things where the raw data is
|
||||||
already stored in the database (e.g. `Message`, `UserMessage`). This is great
|
already stored in the database (e.g., `Message`, `UserMessage`). This is great
|
||||||
because we can always backfill that data to the beginning of time, but of
|
because we can always backfill that data to the beginning of time, but of
|
||||||
course sometimes one wants to do analytics on things that aren't worth
|
course sometimes one wants to do analytics on things that aren't worth
|
||||||
storing every data point for (e.g. activity data, request performance
|
storing every data point for (e.g., activity data, request performance
|
||||||
statistics, etc.). There is currently a reference implementation of a
|
statistics, etc.). There is currently a reference implementation of a
|
||||||
`LoggingCountStat` that shows how to handle such a situation.
|
`LoggingCountStat` that shows how to handle such a situation.
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ Tips and tricks:
|
||||||
better in Chrome than in Firefox, though this hasn't been extensively
|
better in Chrome than in Firefox, though this hasn't been extensively
|
||||||
verified.
|
verified.
|
||||||
- Unless a graph has a ton of data, it is typically better to just redraw it
|
- Unless a graph has a ton of data, it is typically better to just redraw it
|
||||||
when something changes (e.g. in the various aggregation click handlers)
|
when something changes (e.g., in the various aggregation click handlers)
|
||||||
rather than to use retrace or relayout or do other complicated
|
rather than to use retrace or relayout or do other complicated
|
||||||
things. Performance on the `/stats` page is nice but not critical, and we've
|
things. Performance on the `/stats` page is nice but not critical, and we've
|
||||||
run into a lot of small bugs when trying to use Plotly's retrace/relayout.
|
run into a lot of small bugs when trying to use Plotly's retrace/relayout.
|
||||||
|
@ -211,7 +211,7 @@ Tips and tricks:
|
||||||
isn't documented well.
|
isn't documented well.
|
||||||
- `'paper'` as a Plotly option refers to the bounding box of the graph (or
|
- `'paper'` as a Plotly option refers to the bounding box of the graph (or
|
||||||
something related to that).
|
something related to that).
|
||||||
- You can't right click and inspect the elements of a Plotly graph (e.g. the
|
- You can't right click and inspect the elements of a Plotly graph (e.g., the
|
||||||
bars in a bar graph) in your browser, since there is an interaction layer
|
bars in a bar graph) in your browser, since there is an interaction layer
|
||||||
on top of it. But if you hunt around the document tree you should be able
|
on top of it. But if you hunt around the document tree you should be able
|
||||||
to find it.
|
to find it.
|
||||||
|
|
|
@ -47,7 +47,7 @@ work.
|
||||||
As a side note, the policy of using these accessor functions wherever
|
As a side note, the policy of using these accessor functions wherever
|
||||||
possible is a good idea, regardless of caching, because the functions
|
possible is a good idea, regardless of caching, because the functions
|
||||||
also generally take care of details you might not think about
|
also generally take care of details you might not think about
|
||||||
(e.g. case-insensitive matching of channel names or email addresses).
|
(e.g., case-insensitive matching of channel names or email addresses).
|
||||||
It's amazing how slightly tricky logic that's duplicated in several
|
It's amazing how slightly tricky logic that's duplicated in several
|
||||||
places invariably ends up buggy in some of those places, and in
|
places invariably ends up buggy in some of those places, and in
|
||||||
aggregate we call these accessor functions hundreds of times in
|
aggregate we call these accessor functions hundreds of times in
|
||||||
|
@ -158,7 +158,7 @@ those keys from the cache (if present).
|
||||||
Maintaining these flush functions requires some care (every time we
|
Maintaining these flush functions requires some care (every time we
|
||||||
add a new cache, we need to look through them), but overall it's a
|
add a new cache, we need to look through them), but overall it's a
|
||||||
pretty simple algorithm: If the changed data appears in any form in a
|
pretty simple algorithm: If the changed data appears in any form in a
|
||||||
given cache key, that cache key needs to be cleared. E.g. the
|
given cache key, that cache key needs to be cleared. E.g., the
|
||||||
`active_user_ids_cache_key` cache for a realm needs to be flushed
|
`active_user_ids_cache_key` cache for a realm needs to be flushed
|
||||||
whenever a new user is created in that realm, or user is
|
whenever a new user is created in that realm, or user is
|
||||||
deactivated/reactivated, even though it's just a list of IDs and thus
|
deactivated/reactivated, even though it's just a list of IDs and thus
|
||||||
|
@ -231,7 +231,7 @@ them in loops (the same applies for database queries!). Instead, one
|
||||||
should use a bulk query. We have a fancy function,
|
should use a bulk query. We have a fancy function,
|
||||||
`generate_bulk_cached_fetch`, which is super magical and handles this
|
`generate_bulk_cached_fetch`, which is super magical and handles this
|
||||||
for us, with support for a bunch of fancy features like marshalling
|
for us, with support for a bunch of fancy features like marshalling
|
||||||
data before/after going into the cache (e.g. to compress `message`
|
data before/after going into the cache (e.g., to compress `message`
|
||||||
objects to minimize data transfer between Django and memcached).
|
objects to minimize data transfer between Django and memcached).
|
||||||
|
|
||||||
## In-process caching in Django
|
## In-process caching in Django
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
`zerver.models.Client` is Zulip's analogue of the HTTP User-Agent
|
`zerver.models.Client` is Zulip's analogue of the HTTP User-Agent
|
||||||
header (and is populated from User-Agent). It exists for use in
|
header (and is populated from User-Agent). It exists for use in
|
||||||
analytics and other places to provide human-readable summary data
|
analytics and other places to provide human-readable summary data
|
||||||
about "which Zulip client" was used for an operation (e.g. was it the
|
about "which Zulip client" was used for an operation (e.g., was it the
|
||||||
Android app, the desktop app, or a bot?).
|
Android app, the desktop app, or a bot?).
|
||||||
|
|
||||||
In general, it shouldn't be used for anything controlling the behavior
|
In general, it shouldn't be used for anything controlling the behavior
|
||||||
|
|
|
@ -136,7 +136,7 @@ highlighting. The system is largely managed by the code in
|
||||||
versions in a `requirements.txt` file to declare what we're using.
|
versions in a `requirements.txt` file to declare what we're using.
|
||||||
Since we have a few different installation targets, we maintain
|
Since we have a few different installation targets, we maintain
|
||||||
several `requirements.txt` format files in the `requirements/`
|
several `requirements.txt` format files in the `requirements/`
|
||||||
directory (e.g. `dev.in` for development, `prod.in` for
|
directory (e.g., `dev.in` for development, `prod.in` for
|
||||||
production, `docs.in` for ReadTheDocs, `common.in` for the vast
|
production, `docs.in` for ReadTheDocs, `common.in` for the vast
|
||||||
majority of packages common to prod and development, etc.). We use
|
majority of packages common to prod and development, etc.). We use
|
||||||
`pip install --no-deps` to ensure we only install the packages we
|
`pip install --no-deps` to ensure we only install the packages we
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
This page has developer documentation on the Zulip email system. If you're
|
This page has developer documentation on the Zulip email system. If you're
|
||||||
trying to configure your server to send email, you might be looking for our
|
trying to configure your server to send email, you might be looking for our
|
||||||
guide to [sending outgoing email](../production/email.md). If you're trying to
|
guide to [sending outgoing email](../production/email.md). If you're trying to
|
||||||
configure an email integration to receive incoming email (e.g. so that users
|
configure an email integration to receive incoming email (e.g., so that users
|
||||||
can reply to message notification emails via email), you might be interested in
|
can reply to message notification emails via email), you might be interested in
|
||||||
our instructions for
|
our instructions for
|
||||||
[setting up an email integration](https://zulip.com/integrations/doc/email).
|
[setting up an email integration](https://zulip.com/integrations/doc/email).
|
||||||
|
@ -33,7 +33,7 @@ with only a few things you need to know to get started.
|
||||||
One slightly complicated decision you may have to make when adding an email
|
One slightly complicated decision you may have to make when adding an email
|
||||||
is figuring out how to schedule it. There are 3 ways to schedule email.
|
is figuring out how to schedule it. There are 3 ways to schedule email.
|
||||||
|
|
||||||
- Send it immediately, in the current Django process, e.g. by calling
|
- Send it immediately, in the current Django process, e.g., by calling
|
||||||
`send_email` directly. An example of this is the `confirm_registration`
|
`send_email` directly. An example of this is the `confirm_registration`
|
||||||
email.
|
email.
|
||||||
- Add it to a queue. An example is the `invitation` email.
|
- Add it to a queue. An example is the `invitation` email.
|
||||||
|
@ -56,7 +56,7 @@ custom backend, `EmailLogBackEnd`. It does the following:
|
||||||
|
|
||||||
- Logs any sent emails to `var/log/email_content.log`. This log is
|
- Logs any sent emails to `var/log/email_content.log`. This log is
|
||||||
displayed by the `/emails` endpoint
|
displayed by the `/emails` endpoint
|
||||||
(e.g. http://zulip.zulipdev.com:9991/emails).
|
(e.g., http://zulip.zulipdev.com:9991/emails).
|
||||||
- Print a friendly message on console advertising `/emails` to make
|
- Print a friendly message on console advertising `/emails` to make
|
||||||
this nice and discoverable.
|
this nice and discoverable.
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ are multiple copies or they contain CSS colors, you did it wrong.
|
||||||
A final note for translating emails is that strings that are sent to
|
A final note for translating emails is that strings that are sent to
|
||||||
user accounts (where we know the user's language) are higher-priority
|
user accounts (where we know the user's language) are higher-priority
|
||||||
to translate than things sent to an email address (where we don't).
|
to translate than things sent to an email address (where we don't).
|
||||||
E.g. for password reset emails, it makes sense for the code path for
|
E.g., for password reset emails, it makes sense for the code path for
|
||||||
people with an actual account can be tagged for translation, while the
|
people with an actual account can be tagged for translation, while the
|
||||||
code path for the "you don't have an account email" might not be,
|
code path for the "you don't have an account email" might not be,
|
||||||
since we might not know what language to use in the second case.
|
since we might not know what language to use in the second case.
|
||||||
|
|
|
@ -64,15 +64,15 @@ to be consumed by the delivery system.
|
||||||
|
|
||||||
Usually, this list of users is one of 3 things:
|
Usually, this list of users is one of 3 things:
|
||||||
|
|
||||||
- A single user (e.g. for user-level settings changes).
|
- A single user (e.g., for user-level settings changes).
|
||||||
- Everyone in the realm (e.g. for organization-level settings changes,
|
- Everyone in the realm (e.g., for organization-level settings changes,
|
||||||
like new realm emoji).
|
like new realm emoji).
|
||||||
- Everyone who would receive a given message (for messages, emoji
|
- Everyone who would receive a given message (for messages, emoji
|
||||||
reactions, message editing, etc.); i.e. the subscribers to a channel
|
reactions, message editing, etc.); i.e. the subscribers to a channel
|
||||||
or the people on a direct message thread.
|
or the people on a direct message thread.
|
||||||
|
|
||||||
It is the responsibility of the caller of `send_event` to choose the
|
It is the responsibility of the caller of `send_event` to choose the
|
||||||
list of user IDs correctly. There can be security problems if e.g. an
|
list of user IDs correctly. There can be security problems if e.g., an
|
||||||
event containing direct message content is sent to the entire
|
event containing direct message content is sent to the entire
|
||||||
organization. However, if an event isn't sent to enough clients,
|
organization. However, if an event isn't sent to enough clients,
|
||||||
there will likely be user-visible real-time sync bugs.
|
there will likely be user-visible real-time sync bugs.
|
||||||
|
@ -175,7 +175,7 @@ anyway).
|
||||||
When a client starts up, it usually wants to get 2 things from the
|
When a client starts up, it usually wants to get 2 things from the
|
||||||
server:
|
server:
|
||||||
|
|
||||||
- The "current state" of various pieces of data, e.g. the current
|
- The "current state" of various pieces of data, e.g., the current
|
||||||
settings, set of users in the organization (for typeahead), channel,
|
settings, set of users in the organization (for typeahead), channel,
|
||||||
messages, etc. (aka the "initial state").
|
messages, etc. (aka the "initial state").
|
||||||
- A subscription to receive updates to those data when they are
|
- A subscription to receive updates to those data when they are
|
||||||
|
@ -212,7 +212,7 @@ request; the logic is in `zerver/views/events_register.py` and
|
||||||
that had been added to the Tornado event queue since it
|
that had been added to the Tornado event queue since it
|
||||||
was created.
|
was created.
|
||||||
- Finally, Django "applies" the events (see the `apply_events`
|
- Finally, Django "applies" the events (see the `apply_events`
|
||||||
function) to the initial state that it fetched. E.g. for a name
|
function) to the initial state that it fetched. E.g., for a name
|
||||||
change event, it finds the user data in the `realm_user` data
|
change event, it finds the user data in the `realm_user` data
|
||||||
structure, and updates it to have the new name.
|
structure, and updates it to have the new name.
|
||||||
|
|
||||||
|
@ -266,7 +266,7 @@ action and then fetching a fresh copy of the state.
|
||||||
In particular, `verify_action` does the following:
|
In particular, `verify_action` does the following:
|
||||||
|
|
||||||
- Call `fetch_initial_state_data` to get the current state.
|
- Call `fetch_initial_state_data` to get the current state.
|
||||||
- Call the action function (e.g. `do_add_default_stream`).
|
- Call the action function (e.g., `do_add_default_stream`).
|
||||||
- Capture the events generated by the action function.
|
- Capture the events generated by the action function.
|
||||||
- Check the events generated are documented in the [OpenAPI
|
- Check the events generated are documented in the [OpenAPI
|
||||||
schema](../documentation/api.md) defined in
|
schema](../documentation/api.md) defined in
|
||||||
|
@ -421,7 +421,7 @@ to make sure we handle backwards-compatibility properly.
|
||||||
`GET /events` API documentation. It's also a good idea to and open
|
`GET /events` API documentation. It's also a good idea to and open
|
||||||
issues with the mobile and terminal projects to notify them.
|
issues with the mobile and terminal projects to notify them.
|
||||||
- If we're making changes that could confuse existing client app logic
|
- If we're making changes that could confuse existing client app logic
|
||||||
that parses events (E.g. changing the type/meaning of an existing
|
that parses events (e.g., changing the type/meaning of an existing
|
||||||
field, or removing a field), we need to be very careful, since Zulip
|
field, or removing a field), we need to be very careful, since Zulip
|
||||||
supports old clients connecting to a modern server. See our
|
supports old clients connecting to a modern server. See our
|
||||||
[release lifecycle](../overview/release-lifecycle.md) documentation
|
[release lifecycle](../overview/release-lifecycle.md) documentation
|
||||||
|
@ -441,14 +441,14 @@ to make sure we handle backwards-compatibility properly.
|
||||||
format, or Tornado may crash when upgrading past the relevant
|
format, or Tornado may crash when upgrading past the relevant
|
||||||
commit. We attempt to contain that sort of logic in the `from_dict`
|
commit. We attempt to contain that sort of logic in the `from_dict`
|
||||||
function (which is used for changing event queue formats) and
|
function (which is used for changing event queue formats) and
|
||||||
`client_capabilities` conditionals (E.g. in
|
`client_capabilities` conditionals (e.g., in
|
||||||
`process_deletion_event`). Compatibility code not related to a
|
`process_deletion_event`). Compatibility code not related to a
|
||||||
`client_capabilities` entry should be marked with a
|
`client_capabilities` entry should be marked with a
|
||||||
`# TODO/compatibility: ...` comment noting when it can be safely deleted;
|
`# TODO/compatibility: ...` comment noting when it can be safely deleted;
|
||||||
we grep for these comments entries during major releases.
|
we grep for these comments entries during major releases.
|
||||||
- Schema changes are a sensitive operation, and like with database
|
- Schema changes are a sensitive operation, and like with database
|
||||||
schema changes, it's critical to do thoughtful manual testing.
|
schema changes, it's critical to do thoughtful manual testing.
|
||||||
E.g. run the mobile app against your test server and verify it
|
E.g., run the mobile app against your test server and verify it
|
||||||
handles the new event properly, or arrange for your new Tornado code
|
handles the new event properly, or arrange for your new Tornado code
|
||||||
to actually process a pre-upgrade event and verify via the browser
|
to actually process a pre-upgrade event and verify via the browser
|
||||||
console what came out.
|
console what came out.
|
||||||
|
|
|
@ -30,9 +30,9 @@ different flows:
|
||||||
- The user uses the "back" button in their browser (basically
|
- The user uses the "back" button in their browser (basically
|
||||||
equivalent to the previous one, as a _link_ out of the browser history
|
equivalent to the previous one, as a _link_ out of the browser history
|
||||||
will be visited).
|
will be visited).
|
||||||
- The user clicking some in-app click handler (e.g. "Channel settings"
|
- The user clicking some in-app click handler (e.g., "Channel settings"
|
||||||
for an individual channel), that potentially does
|
for an individual channel), that potentially does
|
||||||
several UI-manipulating things including e.g. loading the channels
|
several UI-manipulating things including e.g., loading the channels
|
||||||
overlay, and needs to update the hash without re-triggering the open
|
overlay, and needs to update the hash without re-triggering the open
|
||||||
animation (etc.).
|
animation (etc.).
|
||||||
- Within an overlay like the channels overlay, the user clicks to
|
- Within an overlay like the channels overlay, the user clicks to
|
||||||
|
@ -45,7 +45,7 @@ different flows:
|
||||||
- A server-initiated browser reload (done after a new version is
|
- A server-initiated browser reload (done after a new version is
|
||||||
deployed, or when a user comes back after being idle for a while,
|
deployed, or when a user comes back after being idle for a while,
|
||||||
see [notes below][self-server-reloads]), where we try to preserve
|
see [notes below][self-server-reloads]), where we try to preserve
|
||||||
extra state (e.g. content of compose box, scroll position within a
|
extra state (e.g., content of compose box, scroll position within a
|
||||||
narrow) using the `/#reload` hash prefix.
|
narrow) using the `/#reload` hash prefix.
|
||||||
|
|
||||||
When making changes to the hashchange system, it is **essential** to
|
When making changes to the hashchange system, it is **essential** to
|
||||||
|
@ -65,7 +65,7 @@ The main external API lives in `web/src/browser_history.js`:
|
||||||
Internally you have these functions:
|
Internally you have these functions:
|
||||||
|
|
||||||
- `hashchange.hashchanged` is the function used to handle the hash,
|
- `hashchange.hashchanged` is the function used to handle the hash,
|
||||||
whether it's changed by the browser (e.g. by clicking on a link to
|
whether it's changed by the browser (e.g., by clicking on a link to
|
||||||
a hash or using the back button) or triggered internally.
|
a hash or using the back button) or triggered internally.
|
||||||
- `hashchange.do_hashchange_normal` handles most cases, like loading the main
|
- `hashchange.do_hashchange_normal` handles most cases, like loading the main
|
||||||
page (but maybe with a specific URL if you are narrowed to a
|
page (but maybe with a specific URL if you are narrowed to a
|
||||||
|
|
|
@ -83,8 +83,8 @@ with its corresponding CSS selector as `.my-multiword-class`.
|
||||||
|
|
||||||
When changing any part of the Zulip CSS, it's important to check that
|
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
|
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
|
wide screen (e.g., 1920px) all the way down to narrow phone screens
|
||||||
(e.g. 480px).
|
(e.g., 480px).
|
||||||
|
|
||||||
For complex changes, it's definitely worth testing in a few different
|
For complex changes, it's definitely worth testing in a few different
|
||||||
browsers to make sure things look the same.
|
browsers to make sure things look the same.
|
||||||
|
@ -228,9 +228,9 @@ needs to be accessible from one of the entry points defined either in
|
||||||
`web/src/bundles/common.ts` which itself is imported to the
|
`web/src/bundles/common.ts` which itself is imported to the
|
||||||
`app` and `common` bundles.
|
`app` and `common` bundles.
|
||||||
- If it's just used on a single standalone page which is only used in
|
- If it's just used on a single standalone page which is only used in
|
||||||
a development environment (e.g. `/devlogin`) create a new entry
|
a development environment (e.g., `/devlogin`) create a new entry
|
||||||
point in `web/webpack.dev-assets.json` or it's used in both
|
point in `web/webpack.dev-assets.json` or it's used in both
|
||||||
production and development (e.g. `/stats`) create a new entry point
|
production and development (e.g., `/stats`) create a new entry point
|
||||||
in `web/webpack.assets.json`. Use the `bundle` macro (defined in
|
in `web/webpack.assets.json`. Use the `bundle` macro (defined in
|
||||||
`templates/zerver/base.html`) in the relevant Jinja2 template to
|
`templates/zerver/base.html`) in the relevant Jinja2 template to
|
||||||
inject the compiled JS and CSS.
|
inject the compiled JS and CSS.
|
||||||
|
@ -246,10 +246,10 @@ A few useful notes are:
|
||||||
`/home/zulip/prod-static`. When a new version is deployed, before the
|
`/home/zulip/prod-static`. When a new version is deployed, before the
|
||||||
server is restarted, files are copied into that directory.
|
server is restarted, files are copied into that directory.
|
||||||
- We use the VFL (versioned file layout) strategy, where each file in
|
- We use the VFL (versioned file layout) strategy, where each file in
|
||||||
the codebase (e.g. `favicon.ico`) gets a new name
|
the codebase (e.g., `favicon.ico`) gets a new name
|
||||||
(e.g. `favicon.c55d45ae8c58.ico`) that contains a hash in it. Each
|
(e.g., `favicon.c55d45ae8c58.ico`) that contains a hash in it. Each
|
||||||
deployment, has a manifest file
|
deployment, has a manifest file
|
||||||
(e.g. `/home/zulip/deployments/current/staticfiles.json`) that maps
|
(e.g., `/home/zulip/deployments/current/staticfiles.json`) that maps
|
||||||
codebase filenames to serving filenames for that deployment. The
|
codebase filenames to serving filenames for that deployment. The
|
||||||
benefit of this VFL approach is that all the static files for past
|
benefit of this VFL approach is that all the static files for past
|
||||||
deployments can coexist, which in turn eliminates most classes of
|
deployments can coexist, which in turn eliminates most classes of
|
||||||
|
@ -257,7 +257,7 @@ A few useful notes are:
|
||||||
deployment can't find their static assets. It also is necessary for
|
deployment can't find their static assets. It also is necessary for
|
||||||
any incremental rollout strategy where different clients get
|
any incremental rollout strategy where different clients get
|
||||||
different versions of the site.
|
different versions of the site.
|
||||||
- Some paths for files (e.g. emoji) are stored in the
|
- Some paths for files (e.g., emoji) are stored in the
|
||||||
`rendered_content` of past messages, and thus cannot be removed
|
`rendered_content` of past messages, and thus cannot be removed
|
||||||
without breaking the rendering of old messages (or doing a
|
without breaking the rendering of old messages (or doing a
|
||||||
mass-rerender of old messages).
|
mass-rerender of old messages).
|
||||||
|
|
|
@ -111,7 +111,7 @@ The format of this output is:
|
||||||
- HTTP method
|
- HTTP method
|
||||||
- HTTP status code
|
- HTTP status code
|
||||||
- Time to process
|
- Time to process
|
||||||
- (Optional perf data details, e.g. database time/queries, memcached
|
- (Optional perf data details, e.g., database time/queries, memcached
|
||||||
time/queries, Django process startup time, Markdown processing time,
|
time/queries, Django process startup time, Markdown processing time,
|
||||||
etc.)
|
etc.)
|
||||||
- Endpoint/URL from zproject/urls.py
|
- Endpoint/URL from zproject/urls.py
|
||||||
|
@ -200,7 +200,7 @@ Blueslip supports several error levels:
|
||||||
than returning execution to the caller.
|
than returning execution to the caller.
|
||||||
- `blueslip.error`: For logging of events that are definitely caused by a bug
|
- `blueslip.error`: For logging of events that are definitely caused by a bug
|
||||||
and thus sufficiently important to be reported, but where we can handle the
|
and thus sufficiently important to be reported, but where we can handle the
|
||||||
error without creating major user-facing problems (e.g. an exception when
|
error without creating major user-facing problems (e.g., an exception when
|
||||||
handling a presence update).
|
handling a presence update).
|
||||||
- `blueslip.warn`: For logging of events that are a problem but not important
|
- `blueslip.warn`: For logging of events that are a problem but not important
|
||||||
enough to log an error to Sentry in production. They are, however, highlighted
|
enough to log an error to Sentry in production. They are, however, highlighted
|
||||||
|
@ -208,7 +208,7 @@ Blueslip supports several error levels:
|
||||||
production.
|
production.
|
||||||
- `blueslip.log` (and `blueslip.info`): Logged to the JS console in development
|
- `blueslip.log` (and `blueslip.info`): Logged to the JS console in development
|
||||||
and also in the Sentry breadcrumb log in production. Useful for data that
|
and also in the Sentry breadcrumb log in production. Useful for data that
|
||||||
might help discern what state the browser was in during an error (e.g. whether
|
might help discern what state the browser was in during an error (e.g., whether
|
||||||
the user was in a narrow).
|
the user was in a narrow).
|
||||||
- `blueslip.debug`: Similar to `blueslip.log`, but are not printed to
|
- `blueslip.debug`: Similar to `blueslip.log`, but are not printed to
|
||||||
the JS console in development.
|
the JS console in development.
|
||||||
|
|
|
@ -13,22 +13,22 @@ While Zulip takes advantage of built-in Django management commands for
|
||||||
things like managing Django migrations, we also have dozens that we've
|
things like managing Django migrations, we also have dozens that we've
|
||||||
written for a range of purposes:
|
written for a range of purposes:
|
||||||
|
|
||||||
- Cron jobs to do regular updates, e.g. `update_analytics_counts.py`,
|
- Cron jobs to do regular updates, e.g., `update_analytics_counts.py`,
|
||||||
`sync_ldap_user_data`, etc.
|
`sync_ldap_user_data`, etc.
|
||||||
- Useful parts of provisioning or upgrading a Zulip development
|
- Useful parts of provisioning or upgrading a Zulip development
|
||||||
environment or server, e.g. `makemessages`, `compilemessages`,
|
environment or server, e.g., `makemessages`, `compilemessages`,
|
||||||
`populate_db`, `fill_memcached_caches`, etc.
|
`populate_db`, `fill_memcached_caches`, etc.
|
||||||
- The actual scripts run by supervisord to run the persistent
|
- The actual scripts run by supervisord to run the persistent
|
||||||
processes in a Zulip server, e.g. `runtornado` and `process_queue`.
|
processes in a Zulip server, e.g., `runtornado` and `process_queue`.
|
||||||
- For a sysadmin to verify a Zulip server's configuration during
|
- For a sysadmin to verify a Zulip server's configuration during
|
||||||
installation, e.g. `checkconfig`, `send_test_email`.
|
installation, e.g., `checkconfig`, `send_test_email`.
|
||||||
- As the interface for doing those rare operations that don't have a
|
- As the interface for doing those rare operations that don't have a
|
||||||
UI yet, e.g. `deactivate_realm`, `reactivate_realm`,
|
UI yet, e.g., `deactivate_realm`, `reactivate_realm`,
|
||||||
`change_user_email` (for the case where the user doesn't control the
|
`change_user_email` (for the case where the user doesn't control the
|
||||||
old email address).
|
old email address).
|
||||||
- For a sysadmin to easily interact with and script common possible
|
- For a sysadmin to easily interact with and script common possible
|
||||||
changes they might want to make to the database on a Zulip server.
|
changes they might want to make to the database on a Zulip server.
|
||||||
E.g. `send_password_reset_email`, `export`, `purge_queue`.
|
E.g., `send_password_reset_email`, `export`, `purge_queue`.
|
||||||
|
|
||||||
## Writing management commands
|
## Writing management commands
|
||||||
|
|
||||||
|
|
|
@ -147,10 +147,10 @@ object and other arguments passed into `do_convert` (`sent_by_bot`,
|
||||||
`translate_emoticons`, `mention_data`, etc.). Because
|
`translate_emoticons`, `mention_data`, etc.). Because
|
||||||
Python-Markdown doesn't support directly passing arguments into the
|
Python-Markdown doesn't support directly passing arguments into the
|
||||||
Markdown processor, our logic attaches these data to the Markdown
|
Markdown processor, our logic attaches these data to the Markdown
|
||||||
processor object via e.g. `_md_engine.zulip_db_data`, and then
|
processor object via e.g., `_md_engine.zulip_db_data`, and then
|
||||||
individual Markdown rules can access the data from there.
|
individual Markdown rules can access the data from there.
|
||||||
|
|
||||||
For non-message contexts (e.g. an organization's profile (aka the
|
For non-message contexts (e.g., an organization's profile (aka the
|
||||||
thing on the right-hand side of the login page), channel descriptions,
|
thing on the right-hand side of the login page), channel descriptions,
|
||||||
or rendering custom profile fields), one needs to just pass in a
|
or rendering custom profile fields), one needs to just pass in a
|
||||||
`message_realm` (see, for example, `zulip_default_context` for the
|
`message_realm` (see, for example, `zulip_default_context` for the
|
||||||
|
@ -166,7 +166,7 @@ Markdown, not newer Markdown variants like CommonMark.
|
||||||
Markdown is great for group chat for the same reason it's been
|
Markdown is great for group chat for the same reason it's been
|
||||||
successful in products ranging from blogs to wikis to bug trackers:
|
successful in products ranging from blogs to wikis to bug trackers:
|
||||||
it's close enough to how people try to express themselves when writing
|
it's close enough to how people try to express themselves when writing
|
||||||
plain text (e.g. emails) that it helps more than getting in the way.
|
plain text (e.g., emails) that it helps more than getting in the way.
|
||||||
|
|
||||||
The main issue for using Markdown in instant messaging is that the
|
The main issue for using Markdown in instant messaging is that the
|
||||||
Markdown standard syntax used in a lot of wikis/blogs has nontrivial
|
Markdown standard syntax used in a lot of wikis/blogs has nontrivial
|
||||||
|
@ -212,7 +212,7 @@ accurate.
|
||||||
|
|
||||||
- Allow only `*` syntax for italics, not `_`. This resolves an issue where
|
- Allow only `*` syntax for italics, not `_`. This resolves an issue where
|
||||||
people were using `_` and hitting it by mistake too often. Asterisks
|
people were using `_` and hitting it by mistake too often. Asterisks
|
||||||
surrounded by spaces won't trigger italics, either (e.g. with stock Markdown
|
surrounded by spaces won't trigger italics, either (e.g., with stock Markdown
|
||||||
`You should use char * instead of void * there` would produce undesired
|
`You should use char * instead of void * there` would produce undesired
|
||||||
results).
|
results).
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ as follows:
|
||||||
|
|
||||||
- `do_send_messages` is the synchronous message-sending code path,
|
- `do_send_messages` is the synchronous message-sending code path,
|
||||||
and passing the following data in its `send_event` call:
|
and passing the following data in its `send_event` call:
|
||||||
- Data about the message's content (E.g. mentions, wildcard
|
- Data about the message's content (e.g., mentions, wildcard
|
||||||
mentions, and alert words) and encodes it into the `UserMessage`
|
mentions, and alert words) and encodes it into the `UserMessage`
|
||||||
table's `flags` structure, which is in turn passed into
|
table's `flags` structure, which is in turn passed into
|
||||||
`send_event` for each user receiving the message.
|
`send_event` for each user receiving the message.
|
||||||
|
@ -72,7 +72,7 @@ as follows:
|
||||||
`receiver_is_off_zulip` returns `True`, which checks whether the user has any
|
`receiver_is_off_zulip` returns `True`, which checks whether the user has any
|
||||||
current events system clients registered to receive `message`
|
current events system clients registered to receive `message`
|
||||||
events. This check is done immediately (handling soft disconnects,
|
events. This check is done immediately (handling soft disconnects,
|
||||||
where E.g. the user closes their last Zulip tab and we get the
|
where e.g., the user closes their last Zulip tab and we get the
|
||||||
`DELETE /events/{queue_id}` request).
|
`DELETE /events/{queue_id}` request).
|
||||||
- The `receiver_is_off_zulip` check is effectively repeated when
|
- The `receiver_is_off_zulip` check is effectively repeated when
|
||||||
event queues are garbage-collected (in `missedmessage_hook`) by
|
event queues are garbage-collected (in `missedmessage_hook`) by
|
||||||
|
@ -89,7 +89,7 @@ as follows:
|
||||||
notifications in cases like a mention added during message
|
notifications in cases like a mention added during message
|
||||||
editing.
|
editing.
|
||||||
- The notification sending logic for message edits
|
- The notification sending logic for message edits
|
||||||
inside Tornado has extensive automated test suites; e.g.
|
inside Tornado has extensive automated test suites; e.g.,
|
||||||
`test_message_edit_notifications.py` covers all the cases around
|
`test_message_edit_notifications.py` covers all the cases around
|
||||||
editing a message to add/remove a mention.
|
editing a message to add/remove a mention.
|
||||||
- We may in the future want to add some sort of system for letting
|
- We may in the future want to add some sort of system for letting
|
||||||
|
|
|
@ -4,7 +4,7 @@ When you're using Zulip and you reload, or narrow to a channel, how
|
||||||
does Zulip decide where to place you?
|
does Zulip decide where to place you?
|
||||||
|
|
||||||
Conceptually, Zulip takes you to the place where you left off
|
Conceptually, Zulip takes you to the place where you left off
|
||||||
(e.g. the first unread message), not the most recent messages, to
|
(e.g., the first unread message), not the most recent messages, to
|
||||||
facilitate reviewing all the discussions that happened while you were
|
facilitate reviewing all the discussions that happened while you were
|
||||||
away from your computer. The scroll position is then set to keep that
|
away from your computer. The scroll position is then set to keep that
|
||||||
message in view and away from both the top and bottom of the visible
|
message in view and away from both the top and bottom of the visible
|
||||||
|
@ -53,7 +53,7 @@ channels.)
|
||||||
|
|
||||||
### Unnarrow: previous sequence
|
### Unnarrow: previous sequence
|
||||||
|
|
||||||
When you unnarrow using e.g. the `a` key, you will automatically be
|
When you unnarrow using e.g., the `a` key, you will automatically be
|
||||||
taken to the same message that was selected in the Combined feed view before
|
taken to the same message that was selected in the Combined feed view before
|
||||||
you narrowed, unless in the narrow you read new messages, in which
|
you narrowed, unless in the narrow you read new messages, in which
|
||||||
case you will be jumped forward to the first unread and non-muted
|
case you will be jumped forward to the first unread and non-muted
|
||||||
|
|
|
@ -13,7 +13,7 @@ scalability problems for a team chat tool like Zulip.
|
||||||
There's a lot of performance-related details in the backend and
|
There's a lot of performance-related details in the backend and
|
||||||
network protocol design that we won't get into here. The focus of
|
network protocol design that we won't get into here. The focus of
|
||||||
this is what one needs to know to correctly implement a Zulip client's
|
this is what one needs to know to correctly implement a Zulip client's
|
||||||
presence implementation (e.g. web app, mobile app, terminal client, or
|
presence implementation (e.g., web app, mobile app, terminal client, or
|
||||||
other tool that's intended to represent whether a user is online and
|
other tool that's intended to represent whether a user is online and
|
||||||
using Zulip).
|
using Zulip).
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ about that data structure:
|
||||||
- It's really important that the timestamp is the last time we heard
|
- It's really important that the timestamp is the last time we heard
|
||||||
from the client. A client can only interpret the status to display
|
from the client. A client can only interpret the status to display
|
||||||
about another user by doing a simple computation using the (status,
|
about another user by doing a simple computation using the (status,
|
||||||
timestamp) pair. E.g. a user who last used Zulip 1 week ago will
|
timestamp) pair. E.g., a user who last used Zulip 1 week ago will
|
||||||
have a timestamp of 1 week ago and a status of "active". Why?
|
have a timestamp of 1 week ago and a status of "active". Why?
|
||||||
Because this correctly handles the race conditions. For example, if
|
Because this correctly handles the race conditions. For example, if
|
||||||
the threshold for displaying a user as "offline" was 5 minutes
|
the threshold for displaying a user as "offline" was 5 minutes
|
||||||
|
@ -50,7 +50,7 @@ about that data structure:
|
||||||
- The `status_from_timestamp` function in `web/src/presence.js` is
|
- The `status_from_timestamp` function in `web/src/presence.js` is
|
||||||
useful sample code; the `OFFLINE_THRESHOLD_SECS` check is critical
|
useful sample code; the `OFFLINE_THRESHOLD_SECS` check is critical
|
||||||
to correct output.
|
to correct output.
|
||||||
- We provide the data for e.g. whether the user was online on their
|
- We provide the data for e.g., whether the user was online on their
|
||||||
desktop or the mobile app, but for a basic client, you will likely
|
desktop or the mobile app, but for a basic client, you will likely
|
||||||
only want to parse the "aggregated" key, which shows the summary
|
only want to parse the "aggregated" key, which shows the summary
|
||||||
answer for "is this user online".
|
answer for "is this user online".
|
||||||
|
|
|
@ -5,11 +5,11 @@ used for a variety of purposes:
|
||||||
|
|
||||||
- Asynchronously doing expensive operations like sending email
|
- Asynchronously doing expensive operations like sending email
|
||||||
notifications which can take seconds per email and thus would
|
notifications which can take seconds per email and thus would
|
||||||
otherwise time out when 100s are triggered at once (E.g. inviting a
|
otherwise time out when 100s are triggered at once (e.g., inviting a
|
||||||
lot of new users to a realm).
|
lot of new users to a realm).
|
||||||
|
|
||||||
- Asynchronously doing non-time-critical somewhat expensive operations
|
- Asynchronously doing non-time-critical somewhat expensive operations
|
||||||
like updating analytics tables (e.g. UserActivityInternal) which
|
like updating analytics tables (e.g., UserActivityInternal) which
|
||||||
don't have any immediate runtime effect.
|
don't have any immediate runtime effect.
|
||||||
|
|
||||||
- Communicating events to push to clients (browsers, etc.) from the
|
- Communicating events to push to clients (browsers, etc.) from the
|
||||||
|
@ -40,7 +40,7 @@ To add a new queue processor:
|
||||||
processor. This suffices to test your queue worker in the Zulip development
|
processor. This suffices to test your queue worker in the Zulip development
|
||||||
environment (`tools/run-dev` will automatically restart the queue processors
|
environment (`tools/run-dev` will automatically restart the queue processors
|
||||||
and start running your new queue processor code). You can also run a single
|
and start running your new queue processor code). You can also run a single
|
||||||
queue processor manually using e.g. `./manage.py process_queue --queue=user_activity`.
|
queue processor manually using e.g., `./manage.py process_queue --queue=user_activity`.
|
||||||
|
|
||||||
- So that supervisord will know to run the queue processor in
|
- So that supervisord will know to run the queue processor in
|
||||||
production, you will need to add to the `queues` variable in
|
production, you will need to add to the `queues` variable in
|
||||||
|
|
|
@ -92,5 +92,5 @@ lookup should still work even if you disable proxy for
|
||||||
127.0.0.1 testsubdomain.zulipdev.com
|
127.0.0.1 testsubdomain.zulipdev.com
|
||||||
```
|
```
|
||||||
|
|
||||||
These records are also useful if you want to e.g. run the Puppeteer tests
|
These records are also useful if you want to e.g., run the Puppeteer tests
|
||||||
when you are not connected to the Internet.
|
when you are not connected to the Internet.
|
||||||
|
|
|
@ -5,12 +5,12 @@ preparing a new release.
|
||||||
|
|
||||||
### A week before the release
|
### A week before the release
|
||||||
|
|
||||||
- _Major releases only (e.g. 4.0):_
|
- _Major releases only (e.g., 4.0):_
|
||||||
- Upgrade all Python dependencies in
|
- Upgrade all Python dependencies in
|
||||||
`requirements` to latest upstream versions so they can burn in (use
|
`requirements` to latest upstream versions so they can burn in (use
|
||||||
`pip list --outdated`).
|
`pip list --outdated`).
|
||||||
- Upgrade all puppet dependencies in `puppet/deps.yaml`
|
- Upgrade all puppet dependencies in `puppet/deps.yaml`
|
||||||
- Upgrade all puppet-installed dependencies (e.g. Smokescreen, go,
|
- Upgrade all puppet-installed dependencies (e.g., Smokescreen, go,
|
||||||
etc) in `puppet/zulip/manifests/common.pp`
|
etc) in `puppet/zulip/manifests/common.pp`
|
||||||
- [Upload strings to
|
- [Upload strings to
|
||||||
Transifex](../translating/internationalization.md#translation-process)
|
Transifex](../translating/internationalization.md#translation-process)
|
||||||
|
@ -49,7 +49,7 @@ preparing a new release.
|
||||||
- If the draft post should remain secret until release, avoid using
|
- If the draft post should remain secret until release, avoid using
|
||||||
a guessable Git branch name for the pull request (the deployment
|
a guessable Git branch name for the pull request (the deployment
|
||||||
preview URL is based on the branch name).
|
preview URL is based on the branch name).
|
||||||
- _Major releases only (e.g. 4.0):_ Schedule team members to provide
|
- _Major releases only (e.g., 4.0):_ Schedule team members to provide
|
||||||
extra responsive #production help support following the release.
|
extra responsive #production help support following the release.
|
||||||
|
|
||||||
### Executing the release
|
### Executing the release
|
||||||
|
@ -94,12 +94,12 @@ preparing a new release.
|
||||||
once it is built, and how to test it. Verify it, then publish it to
|
once it is built, and how to test it. Verify it, then publish it to
|
||||||
DigitalOcean marketplace.
|
DigitalOcean marketplace.
|
||||||
- _Major releases only:_
|
- _Major releases only:_
|
||||||
- Create a release branch (e.g. `4.x`).
|
- Create a release branch (e.g., `4.x`).
|
||||||
- On the release branch, update `ZULIP_VERSION` in `version.py` to
|
- On the release branch, update `ZULIP_VERSION` in `version.py` to
|
||||||
the present release with a `+git` suffix, e.g. `4.0+git`.
|
the present release with a `+git` suffix, e.g., `4.0+git`.
|
||||||
- On `main`, update `ZULIP_VERSION` to the future major release with
|
- On `main`, update `ZULIP_VERSION` to the future major release with
|
||||||
a `-dev+git` suffix, e.g. `5.0-dev+git`. Make a Git tag for this
|
a `-dev+git` suffix, e.g., `5.0-dev+git`. Make a Git tag for this
|
||||||
update commit with a `-dev` suffix, e.g. `5.0-dev`. Push the tag
|
update commit with a `-dev` suffix, e.g., `5.0-dev`. Push the tag
|
||||||
to both zulip.git and zulip-internal.git to get a correct version
|
to both zulip.git and zulip-internal.git to get a correct version
|
||||||
number for future Cloud deployments.
|
number for future Cloud deployments.
|
||||||
- Add the new release to `.github/ISSUE_TEMPLATE/2_bug_report.md`.
|
- Add the new release to `.github/ISSUE_TEMPLATE/2_bug_report.md`.
|
||||||
|
@ -113,16 +113,16 @@ preparing a new release.
|
||||||
- Add a new line to the `production_upgrade` matrix in
|
- Add a new line to the `production_upgrade` matrix in
|
||||||
`.github/workflows/production-suite.yml`.
|
`.github/workflows/production-suite.yml`.
|
||||||
- Update /history page in `templates/corporate/history.md`.
|
- Update /history page in `templates/corporate/history.md`.
|
||||||
- _Minor releases only (e.g. 3.2):_
|
- _Minor releases only (e.g., 3.2):_
|
||||||
- On the release branch, update `ZULIP_VERSION` to the present
|
- On the release branch, update `ZULIP_VERSION` to the present
|
||||||
release with a `+git` suffix, e.g. `3.2+git`.
|
release with a `+git` suffix, e.g., `3.2+git`.
|
||||||
- On main, update `LATEST_RELEASE_VERSION` with the released
|
- On main, update `LATEST_RELEASE_VERSION` with the released
|
||||||
version, as well as the changelog changes from the release branch.
|
version, as well as the changelog changes from the release branch.
|
||||||
- _Prereleases only (e.g. 7.0-beta3):_
|
- _Prereleases only (e.g., 7.0-beta3):_
|
||||||
- Atop the prerelease commit (e.g. `7.0-beta3`), make a commit
|
- Atop the prerelease commit (e.g., `7.0-beta3`), make a commit
|
||||||
updating `ZULIP_VERSION` to the prerelease version with a `+git`
|
updating `ZULIP_VERSION` to the prerelease version with a `+git`
|
||||||
suffix, e.g. `7.0-beta3+git`. Push this to `main`. (If `main` has
|
suffix, e.g., `7.0-beta3+git`. Push this to `main`. (If `main` has
|
||||||
already diverged from the prerelease, a merge commit will be
|
already diverged from the prerelease, a merge commit will be
|
||||||
needed here.)
|
needed here.)
|
||||||
- Delete the prerelease branch (e.g. `7.0-beta3-branch`); it's now
|
- Delete the prerelease branch (e.g., `7.0-beta3-branch`); it's now
|
||||||
an ancestor of `main` and thus unnecessary.
|
an ancestor of `main` and thus unnecessary.
|
||||||
|
|
|
@ -49,7 +49,7 @@ migrations.
|
||||||
migration that exists on the release branch. This should be
|
migration that exists on the release branch. This should be
|
||||||
followed, on `main`, by a migration which merges the two resulting
|
followed, on `main`, by a migration which merges the two resulting
|
||||||
tips; you can make such a merge with `manage.py makemigrations --merge`.
|
tips; you can make such a merge with `manage.py makemigrations --merge`.
|
||||||
- **Large tables**: For our very largest tables (e.g. Message and
|
- **Large tables**: For our very largest tables (e.g., Message and
|
||||||
UserMessage), we often need to take precautions when adding columns
|
UserMessage), we often need to take precautions when adding columns
|
||||||
to the table, performing data backfills, or building indexes. We
|
to the table, performing data backfills, or building indexes. We
|
||||||
have a `zerver/lib/migrate.py` library to help with adding columns
|
have a `zerver/lib/migrate.py` library to help with adding columns
|
||||||
|
@ -63,7 +63,7 @@ migrations.
|
||||||
- **Atomicity**. By default, each Django migration is run atomically
|
- **Atomicity**. By default, each Django migration is run atomically
|
||||||
inside a transaction. This can be problematic if one wants to do
|
inside a transaction. This can be problematic if one wants to do
|
||||||
something in a migration that touches a lot of data and would best
|
something in a migration that touches a lot of data and would best
|
||||||
be done in batches of e.g. 1000 objects (e.g. a `Message` or
|
be done in batches of e.g., 1000 objects (e.g., a `Message` or
|
||||||
`UserMessage` table change). There is a [useful Django
|
`UserMessage` table change). There is a [useful Django
|
||||||
feature][migrations-non-atomic] that makes it possible to add
|
feature][migrations-non-atomic] that makes it possible to add
|
||||||
`atomic=False` at the top of a `Migration` class and thus not have
|
`atomic=False` at the top of a `Migration` class and thus not have
|
||||||
|
@ -130,7 +130,7 @@ migrations.
|
||||||
to do lots of small batches, potentially with a brief sleep in
|
to do lots of small batches, potentially with a brief sleep in
|
||||||
between, so that we don't block other operations from finishing.
|
between, so that we don't block other operations from finishing.
|
||||||
- **Rerunnability/idempotency**. Good migrations are ones where if
|
- **Rerunnability/idempotency**. Good migrations are ones where if
|
||||||
operational concerns (e.g. it taking down the Zulip server for
|
operational concerns (e.g., it taking down the Zulip server for
|
||||||
users) interfere with it finishing, it's easy to restart the
|
users) interfere with it finishing, it's easy to restart the
|
||||||
migration without doing a bunch of hand investigation. Ideally,
|
migration without doing a bunch of hand investigation. Ideally,
|
||||||
the migration can even continue where it left off, without needing
|
the migration can even continue where it left off, without needing
|
||||||
|
@ -144,7 +144,7 @@ migrations.
|
||||||
2. Second, do a migration to copy values from the old column to
|
2. Second, do a migration to copy values from the old column to
|
||||||
the new column, to ensure that the two data stores agree.
|
the new column, to ensure that the two data stores agree.
|
||||||
3. Third, a commit that stops writing to the old field.
|
3. Third, a commit that stops writing to the old field.
|
||||||
4. Any cleanup work, e.g. if the old field were a column, we'd do
|
4. Any cleanup work, e.g., if the old field were a column, we'd do
|
||||||
a migration to remove it entirely here.
|
a migration to remove it entirely here.
|
||||||
|
|
||||||
This multi-step process is how most migrations on large database
|
This multi-step process is how most migrations on large database
|
||||||
|
|
|
@ -22,7 +22,7 @@ There are 3 related structures:
|
||||||
IDs go in what order.
|
IDs go in what order.
|
||||||
- A `message_list` is built on top of `message_list_data` and
|
- A `message_list` is built on top of `message_list_data` and
|
||||||
additionally contains the data for a visible-to-the-user message list
|
additionally contains the data for a visible-to-the-user message list
|
||||||
(E.g. where trailing bookends should appear, a selected message,
|
(e.g., where trailing bookends should appear, a selected message,
|
||||||
etc.).
|
etc.).
|
||||||
- A `message_list_view` is built on top of `message_list` and
|
- A `message_list_view` is built on top of `message_list` and
|
||||||
additionally contains rendering details like a window of up to 400
|
additionally contains rendering details like a window of up to 400
|
||||||
|
@ -37,7 +37,7 @@ and narrowing).
|
||||||
The compose box does a lot of fancy things that are out of scope for
|
The compose box does a lot of fancy things that are out of scope for
|
||||||
this article. But it also does a decent amount of client-side
|
this article. But it also does a decent amount of client-side
|
||||||
validation before sending a message off to the server, especially
|
validation before sending a message off to the server, especially
|
||||||
around mentions (E.g. checking the channel name is a valid channel,
|
around mentions (e.g., checking the channel name is a valid channel,
|
||||||
displaying a warning about the number of recipients before a user can
|
displaying a warning about the number of recipients before a user can
|
||||||
use `@**all**` or mention a user who is not subscribed to the current
|
use `@**all**` or mention a user who is not subscribed to the current
|
||||||
channel, etc.).
|
channel, etc.).
|
||||||
|
@ -62,12 +62,12 @@ This section details the ways in which it is different:
|
||||||
[queue](queuing.md) to actually send the message.
|
[queue](queuing.md) to actually send the message.
|
||||||
See `maybe_enqueue_notifications` and `zerver/lib/notification_data.py` for
|
See `maybe_enqueue_notifications` and `zerver/lib/notification_data.py` for
|
||||||
this part of the logic.
|
this part of the logic.
|
||||||
- Splicing user-dependent data (E.g. `flags` such as when the user
|
- Splicing user-dependent data (e.g., `flags` such as when the user
|
||||||
was `mentioned`) into the events.
|
was `mentioned`) into the events.
|
||||||
- Handling the [local echo details](#local-echo).
|
- Handling the [local echo details](#local-echo).
|
||||||
- Handling certain client configuration options that affect
|
- Handling certain client configuration options that affect
|
||||||
messages. E.g. determining whether to send the
|
messages. E.g., determining whether to send the
|
||||||
plaintext/Markdown raw content or the rendered HTML (e.g. the
|
plaintext/Markdown raw content or the rendered HTML (e.g., the
|
||||||
`apply_markdown` and `client_gravatar` features in our
|
`apply_markdown` and `client_gravatar` features in our
|
||||||
[events API docs](https://zulip.com/api/register-queue)).
|
[events API docs](https://zulip.com/api/register-queue)).
|
||||||
- Following our standard naming convention, input validation is done
|
- Following our standard naming convention, input validation is done
|
||||||
|
@ -94,7 +94,7 @@ This section details the ways in which it is different:
|
||||||
step adds a lot of complexity, because the events system cannot
|
step adds a lot of complexity, because the events system cannot
|
||||||
make queries to the database directly.
|
make queries to the database directly.
|
||||||
- Trigger any other deferred work caused by the current message,
|
- Trigger any other deferred work caused by the current message,
|
||||||
e.g. [outgoing webhooks](https://zulip.com/api/outgoing-webhooks)
|
e.g., [outgoing webhooks](https://zulip.com/api/outgoing-webhooks)
|
||||||
or embedded bots.
|
or embedded bots.
|
||||||
- Every query is designed to be a bulk query; we carefully
|
- Every query is designed to be a bulk query; we carefully
|
||||||
unit-test this system for how many database and memcached queries
|
unit-test this system for how many database and memcached queries
|
||||||
|
@ -146,7 +146,7 @@ messages.
|
||||||
is passed two special parameters that clients not implementing local
|
is passed two special parameters that clients not implementing local
|
||||||
echo don't use: `queue_id` and `local_id`. The `queue_id` is the ID
|
echo don't use: `queue_id` and `local_id`. The `queue_id` is the ID
|
||||||
of the client's event queue; here, it is used just as a unique
|
of the client's event queue; here, it is used just as a unique
|
||||||
identifier for the specific client (e.g. a browser tab) that sent
|
identifier for the specific client (e.g., a browser tab) that sent
|
||||||
the message. And the `local_id` is, by the construction above, a
|
the message. And the `local_id` is, by the construction above, a
|
||||||
unique value within that namespace identifying the message.
|
unique value within that namespace identifying the message.
|
||||||
- The `do_send_messages` backend code path includes the `queue_id` and
|
- The `do_send_messages` backend code path includes the `queue_id` and
|
||||||
|
|
|
@ -29,7 +29,7 @@ Zulip uses the [Django settings
|
||||||
system](https://docs.djangoproject.com/en/5.0/topics/settings/), which
|
system](https://docs.djangoproject.com/en/5.0/topics/settings/), which
|
||||||
means that the settings files are Python programs that set a lot of
|
means that the settings files are Python programs that set a lot of
|
||||||
variables with all-capital names like `EMAIL_GATEWAY_PATTERN`. You can
|
variables with all-capital names like `EMAIL_GATEWAY_PATTERN`. You can
|
||||||
access these anywhere in the Zulip Django code using e.g.:
|
access these anywhere in the Zulip Django code using e.g.,:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
@ -37,7 +37,7 @@ print(settings.EMAIL_GATEWAY_PATTERN)
|
||||||
```
|
```
|
||||||
|
|
||||||
Additionally, if you need to access a Django setting in a shell
|
Additionally, if you need to access a Django setting in a shell
|
||||||
script (or just on the command line for debugging), you can use e.g.:
|
script (or just on the command line for debugging), you can use e.g.,:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ ./scripts/get-django-setting EMAIL_GATEWAY_PATTERN
|
$ ./scripts/get-django-setting EMAIL_GATEWAY_PATTERN
|
||||||
|
@ -55,7 +55,7 @@ In a production environment, we have:
|
||||||
administrator-facing settings file for Zulip. It contains all the
|
administrator-facing settings file for Zulip. It contains all the
|
||||||
server-specific settings, such as how to send outgoing email, the
|
server-specific settings, such as how to send outgoing email, the
|
||||||
hostname of the PostgreSQL database, etc., but does not contain any
|
hostname of the PostgreSQL database, etc., but does not contain any
|
||||||
secrets (e.g. passwords, secret API keys, cryptographic keys, etc.).
|
secrets (e.g., passwords, secret API keys, cryptographic keys, etc.).
|
||||||
The way we generally do settings that can be controlled with shell
|
The way we generally do settings that can be controlled with shell
|
||||||
access to a Zulip server is to put a default in
|
access to a Zulip server is to put a default in
|
||||||
`zproject/default_settings.py`, and then override it here. As this
|
`zproject/default_settings.py`, and then override it here. As this
|
||||||
|
@ -91,7 +91,7 @@ In a production environment, we have:
|
||||||
|
|
||||||
- `zproject/computed_settings.py` contains all the settings that are
|
- `zproject/computed_settings.py` contains all the settings that are
|
||||||
constant for all Zulip installations or computed as a function of
|
constant for all Zulip installations or computed as a function of
|
||||||
`zproject/configured_settings.py` (e.g. configuration for logging,
|
`zproject/configured_settings.py` (e.g., configuration for logging,
|
||||||
static assets, middleware, etc.).
|
static assets, middleware, etc.).
|
||||||
|
|
||||||
In a development environment, we have `zproject/settings.py`, and
|
In a development environment, we have `zproject/settings.py`, and
|
||||||
|
@ -106,7 +106,7 @@ additionally:
|
||||||
features like [authentication
|
features like [authentication
|
||||||
options](../development/authentication.md) that require secrets to
|
options](../development/authentication.md) that require secrets to
|
||||||
work. It is also used to set certain settings that in production
|
work. It is also used to set certain settings that in production
|
||||||
belong in `/etc/zulip/settings.py`, e.g. `SOCIAL_AUTH_GITHUB_KEY`.
|
belong in `/etc/zulip/settings.py`, e.g., `SOCIAL_AUTH_GITHUB_KEY`.
|
||||||
You can see a full list with `git grep development_only=True`, or
|
You can see a full list with `git grep development_only=True`, or
|
||||||
add additional settings of this form if needed.
|
add additional settings of this form if needed.
|
||||||
|
|
||||||
|
@ -152,11 +152,11 @@ want those settings.
|
||||||
|
|
||||||
### Testing non-default settings
|
### Testing non-default settings
|
||||||
|
|
||||||
You can write tests for settings using e.g.
|
You can write tests for settings using e.g.,
|
||||||
`with self.settings(TERMS_OF_SERVICE=None)`. However, this only works
|
`with self.settings(TERMS_OF_SERVICE=None)`. However, this only works
|
||||||
for settings which are checked at runtime, not settings which are only
|
for settings which are checked at runtime, not settings which are only
|
||||||
accessed in initialization of Django (or Zulip) internals
|
accessed in initialization of Django (or Zulip) internals
|
||||||
(e.g. `DATABASES`). See the [Django docs on overriding settings in
|
(e.g., `DATABASES`). See the [Django docs on overriding settings in
|
||||||
tests][django-test-settings] for more details.
|
tests][django-test-settings] for more details.
|
||||||
|
|
||||||
[django-test-settings]: https://docs.djangoproject.com/en/5.0/topics/testing/tools/#overriding-settings
|
[django-test-settings]: https://docs.djangoproject.com/en/5.0/topics/testing/tools/#overriding-settings
|
||||||
|
|
|
@ -172,7 +172,7 @@ is the extent of our checking.
|
||||||
Finally, we're checking line length in Python code (and hope to extend
|
Finally, we're checking line length in Python code (and hope to extend
|
||||||
this to other parts of the codebase soon). You can use
|
this to other parts of the codebase soon). You can use
|
||||||
`#ignorelinelength` for special cases where a very long line makes
|
`#ignorelinelength` for special cases where a very long line makes
|
||||||
sense (e.g. a link in a comment to an extremely long URL).
|
sense (e.g., a link in a comment to an extremely long URL).
|
||||||
|
|
||||||
#### Python code
|
#### Python code
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ So, to summarize our approach to integration vs. unit testing:
|
||||||
HTTP response and the internal state of the server following the request
|
HTTP response and the internal state of the server following the request
|
||||||
are both correct.
|
are both correct.
|
||||||
- Following the end-to-end principle in system design, where possible
|
- Following the end-to-end principle in system design, where possible
|
||||||
we write tests that execute a complete flow (e.g. registering a new
|
we write tests that execute a complete flow (e.g., registering a new
|
||||||
Zulip account) rather than testing the implementations of individual
|
Zulip account) rather than testing the implementations of individual
|
||||||
functions.
|
functions.
|
||||||
- We invest in the performance of Zulip in part to give users a great
|
- We invest in the performance of Zulip in part to give users a great
|
||||||
|
@ -214,7 +214,7 @@ test conditions.
|
||||||
The benefit of this strategy is that you guarantee that the test setup
|
The benefit of this strategy is that you guarantee that the test setup
|
||||||
only differs as intended: Done well, it helps avoid the otherwise
|
only differs as intended: Done well, it helps avoid the otherwise
|
||||||
extremely common failure mode where a `test_foo_failure` test passes
|
extremely common failure mode where a `test_foo_failure` test passes
|
||||||
for the wrong reason. (E.g. the action fails not because of the
|
for the wrong reason. (e.g., the action fails not because of the
|
||||||
permission check, but because a required HTTP parameter was only added
|
permission check, but because a required HTTP parameter was only added
|
||||||
to an adjacent `test_foo_success`).
|
to an adjacent `test_foo_success`).
|
||||||
|
|
||||||
|
|
|
@ -121,7 +121,7 @@ Here are some example action methods that tests may use for data setup:
|
||||||
|
|
||||||
### Testing code that accesses the filesystem
|
### Testing code that accesses the filesystem
|
||||||
|
|
||||||
Some tests need to access the filesystem (e.g. `test_upload.py` tests
|
Some tests need to access the filesystem (e.g., `test_upload.py` tests
|
||||||
for `LocalUploadBackend` and the data import tests). Doing
|
for `LocalUploadBackend` and the data import tests). Doing
|
||||||
this correctly requires care to avoid problems like:
|
this correctly requires care to avoid problems like:
|
||||||
|
|
||||||
|
@ -142,7 +142,7 @@ To avoid these problems, you can do the following:
|
||||||
avoid conflicts with other tests run later by the same test process.
|
avoid conflicts with other tests run later by the same test process.
|
||||||
|
|
||||||
Our common testing infrastructure handles some of this for you,
|
Our common testing infrastructure handles some of this for you,
|
||||||
e.g. it replaces `settings.LOCAL_UPLOADS_DIR` for each test process
|
e.g., it replaces `settings.LOCAL_UPLOADS_DIR` for each test process
|
||||||
with a unique path under `/var/<uuid>/test-backend`. And
|
with a unique path under `/var/<uuid>/test-backend`. And
|
||||||
`UploadSerializeMixin` manages some of the cleanup work for
|
`UploadSerializeMixin` manages some of the cleanup work for
|
||||||
`test_upload.py`.
|
`test_upload.py`.
|
||||||
|
@ -252,7 +252,7 @@ foo.qux = 42
|
||||||
```
|
```
|
||||||
|
|
||||||
is _not_ going to throw any errors. Our mock silently accepts all these calls and records them.
|
is _not_ going to throw any errors. Our mock silently accepts all these calls and records them.
|
||||||
`Mock` also implements methods for us to access and assert its records, e.g.
|
`Mock` also implements methods for us to access and assert its records, e.g.,
|
||||||
|
|
||||||
```python
|
```python
|
||||||
foo.bar.assert_called_with('quux')
|
foo.bar.assert_called_with('quux')
|
||||||
|
|
|
@ -274,7 +274,7 @@ These instructions assume you're using the Vagrant development environment.
|
||||||
1. In the `Configure Node.js Remote Interpreter`, window select `Vagrant`
|
1. In the `Configure Node.js Remote Interpreter`, window select `Vagrant`
|
||||||
1. Wait for WebStorm to connect to Vagrant. This will be displayed
|
1. Wait for WebStorm to connect to Vagrant. This will be displayed
|
||||||
by the `Vagrant Host URL` section updating to contain the Vagrant
|
by the `Vagrant Host URL` section updating to contain the Vagrant
|
||||||
SSH URL, e.g. `ssh://vagrant@127.0.0.1:2222`.
|
SSH URL, e.g., `ssh://vagrant@127.0.0.1:2222`.
|
||||||
1. **Set the `Node.js interpreter path` to `/usr/local/bin/node`**
|
1. **Set the `Node.js interpreter path` to `/usr/local/bin/node`**
|
||||||
1. Hit `OK` 2 times to get back to the `Run/Debug Configurations` window.
|
1. Hit `OK` 2 times to get back to the `Run/Debug Configurations` window.
|
||||||
1. Under `Working Directory` select the root `zulip` directory.
|
1. Under `Working Directory` select the root `zulip` directory.
|
||||||
|
@ -288,7 +288,7 @@ Congratulations! You've now set up the integration.
|
||||||
To use Webstorm to debug a given node test file, do the following:
|
To use Webstorm to debug a given node test file, do the following:
|
||||||
|
|
||||||
1. Under `Application parameters` choose the node test file that you
|
1. Under `Application parameters` choose the node test file that you
|
||||||
are trying to test (e.g. `web/tests/message_store.test.js`).
|
are trying to test (e.g., `web/tests/message_store.test.js`).
|
||||||
1. Under `Path Mappings`, set `Project Root` to `/srv/zulip`
|
1. Under `Path Mappings`, set `Project Root` to `/srv/zulip`
|
||||||
(i.e. where the `zulip` Git repository is mounted in the Vagrant guest).
|
(i.e. where the `zulip` Git repository is mounted in the Vagrant guest).
|
||||||
1. Use the WebStorm debugger; see [this overview][webstorm-debugging]
|
1. Use the WebStorm debugger; see [this overview][webstorm-debugging]
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
While our [node test suite](testing-with-node.md) is the
|
While our [node test suite](testing-with-node.md) is the
|
||||||
preferred way to test most frontend code because they are easy to
|
preferred way to test most frontend code because they are easy to
|
||||||
write and maintain, some code is best tested in a real browser, either
|
write and maintain, some code is best tested in a real browser, either
|
||||||
because of navigation (E.g. login) or because we want to verify the
|
because of navigation (e.g., login) or because we want to verify the
|
||||||
interaction between Zulip logic and browser behavior (E.g. copy/paste,
|
interaction between Zulip logic and browser behavior (e.g., copy/paste,
|
||||||
keyboard shortcuts, etc.).
|
keyboard shortcuts, etc.).
|
||||||
|
|
||||||
## Running tests
|
## Running tests
|
||||||
|
@ -74,7 +74,7 @@ integration](continuous-integration.md):
|
||||||
affects any of the selectors used in the tests? If so, the test may
|
affects any of the selectors used in the tests? If so, the test may
|
||||||
just need to be updated for your changes.
|
just need to be updated for your changes.
|
||||||
- Does the test fail deterministically when you run it locally using
|
- Does the test fail deterministically when you run it locally using
|
||||||
E.g. `./tools/test-js-with-puppeteer compose.ts`? If so, you can
|
e.g., `./tools/test-js-with-puppeteer compose.ts`? If so, you can
|
||||||
iteratively debug to see the failure.
|
iteratively debug to see the failure.
|
||||||
- Does the test fail nondeterministically? If so, the problem is
|
- Does the test fail nondeterministically? If so, the problem is
|
||||||
likely that a `waitForSelector` statement is either missing or not
|
likely that a `waitForSelector` statement is either missing or not
|
||||||
|
@ -141,7 +141,7 @@ notes above:
|
||||||
`main`.
|
`main`.
|
||||||
- With black-box browser tests like these, it's very important to write your code
|
- With black-box browser tests like these, it's very important to write your code
|
||||||
to wait for browser's UI to update before taking any action that
|
to wait for browser's UI to update before taking any action that
|
||||||
assumes the last step was processed by the browser (E.g. after you
|
assumes the last step was processed by the browser (e.g., after you
|
||||||
click on a user's avatar, you need an explicit wait for the profile
|
click on a user's avatar, you need an explicit wait for the profile
|
||||||
popover to appear before you can try to click on a menu item in that
|
popover to appear before you can try to click on a menu item in that
|
||||||
popover). This means that before essentially every action in your
|
popover). This means that before essentially every action in your
|
||||||
|
|
|
@ -40,7 +40,7 @@ typically involve running subsets of the tests with commands like these:
|
||||||
```
|
```
|
||||||
|
|
||||||
The commands above will all run in just a few seconds. Many more
|
The commands above will all run in just a few seconds. Many more
|
||||||
useful options are discussed in each tool's documentation (e.g.
|
useful options are discussed in each tool's documentation (e.g.,
|
||||||
`./tools/test-backend --help`).
|
`./tools/test-backend --help`).
|
||||||
|
|
||||||
## Major test suites
|
## Major test suites
|
||||||
|
@ -117,7 +117,7 @@ reasons:
|
||||||
|
|
||||||
As a result, Zulip's major test suites should never access the
|
As a result, Zulip's major test suites should never access the
|
||||||
Internet directly. Since code in Zulip does need to access the
|
Internet directly. Since code in Zulip does need to access the
|
||||||
Internet (e.g. to access various third-party APIs), this means that
|
Internet (e.g., to access various third-party APIs), this means that
|
||||||
the Zulip tests use mocking to basically hardcode (for the purposes of
|
the Zulip tests use mocking to basically hardcode (for the purposes of
|
||||||
the test) what responses should be used for any outgoing Internet
|
the test) what responses should be used for any outgoing Internet
|
||||||
requests that Zulip would make in the code path being tested.
|
requests that Zulip would make in the code path being tested.
|
||||||
|
|
|
@ -71,7 +71,7 @@ Our plan is to order which modules we migrate carefully, starting with
|
||||||
those that:
|
those that:
|
||||||
|
|
||||||
- Appear frequently as reverse dependencies of other modules
|
- Appear frequently as reverse dependencies of other modules
|
||||||
(e.g. `people.js`). These are most valuable to do first because
|
(e.g., `people.js`). These are most valuable to do first because
|
||||||
then we have types on the data being interacted with by other
|
then we have types on the data being interacted with by other
|
||||||
modules when we migrate those.
|
modules when we migrate those.
|
||||||
- Don't have large open pull requests (to avoid merge conflicts); one
|
- Don't have large open pull requests (to avoid merge conflicts); one
|
||||||
|
@ -82,11 +82,11 @@ those that:
|
||||||
|
|
||||||
When migrating a module, we want to be especially thoughtful about
|
When migrating a module, we want to be especially thoughtful about
|
||||||
putting together a commit structure that makes mistakes unlikely and
|
putting together a commit structure that makes mistakes unlikely and
|
||||||
the changes easy to verify. E.g.:
|
the changes easy to verify. E.g.,:
|
||||||
|
|
||||||
- First a commit that just converts the language to TypeScript adding
|
- First a commit that just converts the language to TypeScript adding
|
||||||
types. The result may potentially have some violations of the
|
types. The result may potentially have some violations of the
|
||||||
long-term style we want (e.g. not using `const`). Depending on how
|
long-term style we want (e.g., not using `const`). Depending on how
|
||||||
we're handling linting, we set some override eslint rules at the top
|
we're handling linting, we set some override eslint rules at the top
|
||||||
of the module at this stage so CI still passes.
|
of the module at this stage so CI still passes.
|
||||||
- Then a commit just migrating use of `var` to `const/let` without
|
- Then a commit just migrating use of `var` to `const/let` without
|
||||||
|
|
|
@ -30,7 +30,7 @@ Message 可直译为“消息”、“信息”等,两者皆可,这里统一
|
||||||
|
|
||||||
- Stream - **频道**
|
- Stream - **频道**
|
||||||
|
|
||||||
There were several other optional translations, e.g. "群组(Group)", "
|
There were several other optional translations, e.g., "群组(Group)", "
|
||||||
主题(Subject)", and "栏目(Column)". The "频道(Channel)" is in use now,
|
主题(Subject)", and "栏目(Column)". The "频道(Channel)" is in use now,
|
||||||
which is inspired by the chat "Channel" in the game Ingress. Since
|
which is inspired by the chat "Channel" in the game Ingress. Since
|
||||||
"Stream" can be "Created/Deleted" or "Subscribed/Unsubscribed",
|
"Stream" can be "Created/Deleted" or "Subscribed/Unsubscribed",
|
||||||
|
@ -96,7 +96,7 @@ The perfect tense subscribed/unsubscribed is translated as "已订阅/已
|
||||||
scope of ...". The two words share the common meanings.
|
scope of ...". The two words share the common meanings.
|
||||||
|
|
||||||
2. "筛选" is a common computer phrase and has been well
|
2. "筛选" is a common computer phrase and has been well
|
||||||
accepted by public, e.g. the "Filter(筛选)" feature in Microsoft
|
accepted by public, e.g., the "Filter(筛选)" feature in Microsoft
|
||||||
Excel.
|
Excel.
|
||||||
|
|
||||||
In addition, in the searching context "Narrow to ..." is not
|
In addition, in the searching context "Narrow to ..." is not
|
||||||
|
|
|
@ -57,9 +57,9 @@ the reader and remember to capitalize _Du_.
|
||||||
|
|
||||||
**Prefer imperative over constructions with auxiliary verbs.**
|
**Prefer imperative over constructions with auxiliary verbs.**
|
||||||
|
|
||||||
For instructions, try to use the imperative (e.g. _"Gehe auf die Seite"_ -
|
For instructions, try to use the imperative (e.g., _"Gehe auf die Seite"_ -
|
||||||
_"Go to the page"_) instead of constructions with auxiliary verbs
|
_"Go to the page"_) instead of constructions with auxiliary verbs
|
||||||
(e.g. _"Du musst auf die Seite ... gehen"_ - _"You have to go the page ..."_).
|
(e.g., _"Du musst auf die Seite ... gehen"_ - _"You have to go the page ..."_).
|
||||||
This keeps the phrases short, less stiff and avoids unnecessary addressing
|
This keeps the phrases short, less stiff and avoids unnecessary addressing
|
||||||
of the reader.
|
of the reader.
|
||||||
|
|
||||||
|
@ -69,14 +69,14 @@ of the reader.
|
||||||
|
|
||||||
To be consistent with other online platforms, use continuous labels for buttons,
|
To be consistent with other online platforms, use continuous labels for buttons,
|
||||||
item titles, etc. with verbs in infinitive form,
|
item titles, etc. with verbs in infinitive form,
|
||||||
e.g. _Manage streams_ - _Kanäle verwalten_ instead of _Verwalte Kanäle_.
|
e.g., _Manage streams_ - _Kanäle verwalten_ instead of _Verwalte Kanäle_.
|
||||||
|
|
||||||
### Concatenation of words
|
### Concatenation of words
|
||||||
|
|
||||||
**Try to avoid it.**
|
**Try to avoid it.**
|
||||||
|
|
||||||
German is famous for its concatenations of nouns
|
German is famous for its concatenations of nouns
|
||||||
(e.g. _Heizölrückstoßdämpfung_, which means _fuel oil recoil attenuation_).
|
(e.g., _Heizölrückstoßdämpfung_, which means _fuel oil recoil attenuation_).
|
||||||
For the sake of correct rendering and simplicity, you should try to avoid such
|
For the sake of correct rendering and simplicity, you should try to avoid such
|
||||||
concatenations whenever possible, since they can break the layout of the Zulip
|
concatenations whenever possible, since they can break the layout of the Zulip
|
||||||
frontend. Try to stick to a maximum length of 20 characters and follow your
|
frontend. Try to stick to a maximum length of 20 characters and follow your
|
||||||
|
@ -99,7 +99,7 @@ so you should not be afraid of using them if they provide an advantage over
|
||||||
the German equivalent. Take the following two examples as a reference:
|
the German equivalent. Take the following two examples as a reference:
|
||||||
|
|
||||||
- Translating _Bot_: Use _Bot_, as a completely accurate German
|
- Translating _Bot_: Use _Bot_, as a completely accurate German
|
||||||
equivalent **doesn't** exist (e.g. _Roboter_) and the term _Bot_ is not
|
equivalent **doesn't** exist (e.g., _Roboter_) and the term _Bot_ is not
|
||||||
unknown to German speakers.
|
unknown to German speakers.
|
||||||
|
|
||||||
### Special characters
|
### Special characters
|
||||||
|
@ -133,7 +133,7 @@ Make sure to not walk into such a trap.
|
||||||
|
|
||||||
- Balance common verbs and nouns with specific IT-related translations
|
- Balance common verbs and nouns with specific IT-related translations
|
||||||
of English terms - this can be tricky, try to check how other resources
|
of English terms - this can be tricky, try to check how other resources
|
||||||
were translated (e.g. Gmail, Microsoft websites, Facebook) to decide
|
were translated (e.g., Gmail, Microsoft websites, Facebook) to decide
|
||||||
what wouldn't sound awkward / rude in German.
|
what wouldn't sound awkward / rude in German.
|
||||||
|
|
||||||
- For additional translation information, feel free to check out
|
- For additional translation information, feel free to check out
|
||||||
|
@ -152,7 +152,7 @@ _"Nachricht" (Facebook, WhatsApp, Transifex)_
|
||||||
- Direct Message (DM), Direct Messages (DMs) - **Direktnachricht (DM), Direktnachrichten (DMs)**
|
- Direct Message (DM), Direct Messages (DMs) - **Direktnachricht (DM), Direktnachrichten (DMs)**
|
||||||
|
|
||||||
While we try to avoid concatenating words whenever possible, "Direktnachricht" is used
|
While we try to avoid concatenating words whenever possible, "Direktnachricht" is used
|
||||||
by many other platforms (e.g. X/Twitter, Slack, Discord).
|
by many other platforms (e.g., X/Twitter, Slack, Discord).
|
||||||
Use _DM_ with its plural form _DMs_ rather than DN/DNs in line with other services.
|
Use _DM_ with its plural form _DMs_ rather than DN/DNs in line with other services.
|
||||||
|
|
||||||
_"Direktnachricht" (X/Twitter, Slack)_
|
_"Direktnachricht" (X/Twitter, Slack)_
|
||||||
|
@ -272,7 +272,7 @@ _"Deabonnieren" (YouTube, Transifex)_
|
||||||
Transifex has two different translations for "Narrow to" -
|
Transifex has two different translations for "Narrow to" -
|
||||||
"Schränke auf ... ein." and "Begrenze auf ... ." Both sound a bit strange to a
|
"Schränke auf ... ein." and "Begrenze auf ... ." Both sound a bit strange to a
|
||||||
German speaker, since they would expect grammatically correct sentences when
|
German speaker, since they would expect grammatically correct sentences when
|
||||||
using the imperative (e.g. "Schränke diesen Stream ein auf ... .") Since this
|
using the imperative (e.g., "Schränke diesen Stream ein auf ... .") Since this
|
||||||
would be too long for many labels, the infinitive "begrenzen auf" is preferable.
|
would be too long for many labels, the infinitive "begrenzen auf" is preferable.
|
||||||
"einschränken auf" sounds equally good, but Transifex shows more use cases for
|
"einschränken auf" sounds equally good, but Transifex shows more use cases for
|
||||||
"begrenzen auf".
|
"begrenzen auf".
|
||||||
|
@ -282,7 +282,7 @@ _"Schränke auf ... ein." (Transifex) "Begrenze auf ... ." (Transifex)_
|
||||||
- Filter - **Filtern**
|
- Filter - **Filtern**
|
||||||
|
|
||||||
A direct translation is fine here. Watch out to to use the infinitive instead
|
A direct translation is fine here. Watch out to to use the infinitive instead
|
||||||
of the imperative, e.g. "Nachrichten filtern" instead of "Filtere Nachrichten".
|
of the imperative, e.g., "Nachrichten filtern" instead of "Filtere Nachrichten".
|
||||||
|
|
||||||
_"Filtern" (Thunderbird, LinkedIn)_
|
_"Filtern" (Thunderbird, LinkedIn)_
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
- Use _आप_ as the second-person pronoun. Don't use तुम or तू.
|
- Use _आप_ as the second-person pronoun. Don't use तुम or तू.
|
||||||
(See [chat thread](https://chat.zulip.org/#narrow/channel/58-translation/topic/Hindi.20Translation/near/1762384).)
|
(See [chat thread](https://chat.zulip.org/#narrow/channel/58-translation/topic/Hindi.20Translation/near/1762384).)
|
||||||
|
|
||||||
- Imperative, active, and continuous verbs, e.g. _manage streams_ -
|
- Imperative, active, and continuous verbs, e.g., _manage streams_ -
|
||||||
_चैनल प्रबंधित करें_, not _चैनल प्रबंधन_.
|
_चैनल प्रबंधित करें_, not _चैनल प्रबंधन_.
|
||||||
|
|
||||||
- Warm and friendly phrasing whenever appropriate.
|
- Warm and friendly phrasing whenever appropriate.
|
||||||
|
@ -12,7 +12,7 @@
|
||||||
|
|
||||||
- Balance common verbs and nouns with specific IT-related translations
|
- Balance common verbs and nouns with specific IT-related translations
|
||||||
of English terms - this can be tricky, try to check how other
|
of English terms - this can be tricky, try to check how other
|
||||||
resources were translated (e.g. Gmail, Microsoft websites, Facebook)
|
resources were translated (e.g., Gmail, Microsoft websites, Facebook)
|
||||||
to decide what wouldn't sound awkward / rude in Hindi.
|
to decide what wouldn't sound awkward / rude in Hindi.
|
||||||
|
|
||||||
Some terms are very tricky to translate, so be sure to communicate
|
Some terms are very tricky to translate, so be sure to communicate
|
||||||
|
|
|
@ -13,7 +13,7 @@ principles are important in how we think about internationalization:
|
||||||
tagged for translation in both [HTML templates](#html-templates) and
|
tagged for translation in both [HTML templates](#html-templates) and
|
||||||
code, and our linters attempt to enforce this. There are some
|
code, and our linters attempt to enforce this. There are some
|
||||||
exceptions: we don't tag strings in Zulip's landing pages
|
exceptions: we don't tag strings in Zulip's landing pages
|
||||||
(e.g. /features/) and other documentation (e.g. /help/) for
|
(e.g., /features/) and other documentation (e.g., /help/) for
|
||||||
translation at this time (though we do aim for those pages to be
|
translation at this time (though we do aim for those pages to be
|
||||||
usable with tools like Google Translate).
|
usable with tools like Google Translate).
|
||||||
- Translating all the strings in Zulip for a language and maintaining
|
- Translating all the strings in Zulip for a language and maintaining
|
||||||
|
@ -41,12 +41,12 @@ their style guidelines.
|
||||||
There are a few critical details about human language that are important
|
There are a few critical details about human language that are important
|
||||||
to understand when implementing an internationalized application:
|
to understand when implementing an internationalized application:
|
||||||
|
|
||||||
- **Punctuation** varies between languages (e.g. Japanese doesn't use
|
- **Punctuation** varies between languages (e.g., Japanese doesn't use
|
||||||
`.`s at the end of sentences). This means that you should always
|
`.`s at the end of sentences). This means that you should always
|
||||||
include end-of-sentence symbols like `.` and `?` inside the
|
include end-of-sentence symbols like `.` and `?` inside the
|
||||||
to-be-translated strings, so that translators can correctly
|
to-be-translated strings, so that translators can correctly
|
||||||
translate the content.
|
translate the content.
|
||||||
- **Word order** varies between languages (e.g. some languages put
|
- **Word order** varies between languages (e.g., some languages put
|
||||||
subjects before verbs, others the other way around). This means
|
subjects before verbs, others the other way around). This means
|
||||||
that **concatenating translatable strings** produces broken results
|
that **concatenating translatable strings** produces broken results
|
||||||
(more details with examples are below).
|
(more details with examples are below).
|
||||||
|
@ -63,7 +63,7 @@ to understand when implementing an internationalized application:
|
||||||
find your string.
|
find your string.
|
||||||
|
|
||||||
There's a lot of other interesting differences that are important for
|
There's a lot of other interesting differences that are important for
|
||||||
i18n (e.g. Zulip has a "full name" field rather than "first name" and
|
i18n (e.g., Zulip has a "full name" field rather than "first name" and
|
||||||
"last name" because different cultures order the surnames and given
|
"last name" because different cultures order the surnames and given
|
||||||
names differently), but the above issues are likely to be relevant to
|
names differently), but the above issues are likely to be relevant to
|
||||||
most people working on Zulip.
|
most people working on Zulip.
|
||||||
|
@ -172,7 +172,7 @@ from django.utils.translation import gettext as _
|
||||||
Zulip expects all the error messages to be translatable as well. To
|
Zulip expects all the error messages to be translatable as well. To
|
||||||
ensure this, the error message passed to `JsonableError`
|
ensure this, the error message passed to `JsonableError`
|
||||||
should always be a literal string enclosed by `_()`
|
should always be a literal string enclosed by `_()`
|
||||||
function, e.g.:
|
function, e.g.,:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
JsonableError(_('English text'))
|
JsonableError(_('English text'))
|
||||||
|
@ -180,7 +180,7 @@ JsonableError(_('English text'))
|
||||||
|
|
||||||
If you're declaring a user-facing string at top level or in a class, you need to
|
If you're declaring a user-facing string at top level or in a class, you need to
|
||||||
use `gettext_lazy` instead, to ensure that the translation happens at
|
use `gettext_lazy` instead, to ensure that the translation happens at
|
||||||
request-processing time when Django knows what language to use, e.g.:
|
request-processing time when Django knows what language to use, e.g.,:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from zproject.backends import check_password_strength, email_belongs_to_ldap
|
from zproject.backends import check_password_strength, email_belongs_to_ldap
|
||||||
|
|
|
@ -2,22 +2,22 @@
|
||||||
|
|
||||||
Use semi-formal Polish for translation, some specifics:
|
Use semi-formal Polish for translation, some specifics:
|
||||||
|
|
||||||
- Informal "you" (_ty_) instead of more formal approaches (e.g. plural
|
- Informal "you" (_ty_) instead of more formal approaches (e.g., plural
|
||||||
"you" (_wy_), using any formal titles like _Państwo_, _Pan/Pani_).
|
"you" (_wy_), using any formal titles like _Państwo_, _Pan/Pani_).
|
||||||
|
|
||||||
- Gender-neutral forms of verbs, e.g. _unsubscribed_ - _odsubskrybowano_,
|
- Gender-neutral forms of verbs, e.g., _unsubscribed_ - _odsubskrybowano_,
|
||||||
not \*odsubskrybowałeś".
|
not \*odsubskrybowałeś".
|
||||||
|
|
||||||
- Imperative, active and continuous verbs, e.g. _manage streams_ -
|
- Imperative, active and continuous verbs, e.g., _manage streams_ -
|
||||||
_zarządzaj kanałami_, not _zarządź kanałami_.
|
_zarządzaj kanałami_, not _zarządź kanałami_.
|
||||||
|
|
||||||
- Not using reflexive _się_, e.g. _log out_ would be simply _wyloguj_,
|
- Not using reflexive _się_, e.g., _log out_ would be simply _wyloguj_,
|
||||||
not _wyloguj się_.
|
not _wyloguj się_.
|
||||||
|
|
||||||
- Warm and friendly phrasing whenever appropriate.
|
- Warm and friendly phrasing whenever appropriate.
|
||||||
|
|
||||||
- No slang or regional phrases that could be unclear or too informal,
|
- No slang or regional phrases that could be unclear or too informal,
|
||||||
e.g. _zajawka_.
|
e.g., _zajawka_.
|
||||||
|
|
||||||
- Consistent usage of Zulip-specific terms and common verbs for
|
- Consistent usage of Zulip-specific terms and common verbs for
|
||||||
actions, even if it means repeating - this is one of the key aspects
|
actions, even if it means repeating - this is one of the key aspects
|
||||||
|
@ -30,7 +30,7 @@ Use semi-formal Polish for translation, some specifics:
|
||||||
|
|
||||||
- Balance common verbs and nouns with specific IT-related translations
|
- Balance common verbs and nouns with specific IT-related translations
|
||||||
of English terms - this can be tricky, try to check how other
|
of English terms - this can be tricky, try to check how other
|
||||||
resources were translated (e.g. Gmail, Microsoft websites, Facebook)
|
resources were translated (e.g., Gmail, Microsoft websites, Facebook)
|
||||||
to decide what wouldn't sound awkward in Polish.
|
to decide what wouldn't sound awkward in Polish.
|
||||||
|
|
||||||
Some terms are very tricky to translate, so be sure to communicate
|
Some terms are very tricky to translate, so be sure to communicate
|
||||||
|
@ -69,7 +69,7 @@ and _dostosowanie do potrzeb klienta_ is too long
|
||||||
|
|
||||||
example:
|
example:
|
||||||
|
|
||||||
You can personalize Zulip in many ways, e.g. by pinning certain streams.
|
You can personalize Zulip in many ways, e.g., by pinning certain streams.
|
||||||
|
|
||||||
> Możesz spersonalizować Zulipa na wiele sposobów, np. przypinając niektóre kanały.
|
> Możesz spersonalizować Zulipa na wiele sposobów, np. przypinając niektóre kanały.
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@
|
||||||
Use informal Spanish for translation:
|
Use informal Spanish for translation:
|
||||||
|
|
||||||
- Informal "you" (_tú_) instead of formal form _usted_. Many top software
|
- Informal "you" (_tú_) instead of formal form _usted_. Many top software
|
||||||
companies (e.g. Google) use the informal one, because it's much more common in
|
companies (e.g., Google) use the informal one, because it's much more common in
|
||||||
the daily language and avoids making translations look like they were written
|
the daily language and avoids making translations look like they were written
|
||||||
by machines.
|
by machines.
|
||||||
|
|
||||||
- Imperative, active, and continuous verbs, e.g. _manage streams_ -
|
- Imperative, active, and continuous verbs, e.g., _manage streams_ -
|
||||||
_gestionar canales_, not _gestión de canales_.
|
_gestionar canales_, not _gestión de canales_.
|
||||||
|
|
||||||
- Not using reflexive _se_ e.g. _log out_ should be _salir_, not _salirse_,
|
- Not using reflexive _se_ e.g., _log out_ should be _salir_, not _salirse_,
|
||||||
whenever the infinitive form is possible without making the translation
|
whenever the infinitive form is possible without making the translation
|
||||||
awkward.
|
awkward.
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ Use informal Spanish for translation:
|
||||||
|
|
||||||
- Balance common verbs and nouns with specific IT-related translations
|
- Balance common verbs and nouns with specific IT-related translations
|
||||||
of English terms - this can be tricky, try to check how other
|
of English terms - this can be tricky, try to check how other
|
||||||
resources were translated (e.g. Gmail, Microsoft websites, Facebook)
|
resources were translated (e.g., Gmail, Microsoft websites, Facebook)
|
||||||
to decide what wouldn't sound awkward / rude in Spanish.
|
to decide what wouldn't sound awkward / rude in Spanish.
|
||||||
|
|
||||||
- Latest RAE rule ("solo" should
|
- Latest RAE rule ("solo" should
|
||||||
|
|
|
@ -32,7 +32,7 @@ Zulip:
|
||||||
:::{note}
|
:::{note}
|
||||||
Unless you plan to contribute country-specific translations, do not
|
Unless you plan to contribute country-specific translations, do not
|
||||||
select a country-specific language in the **Languages** menu when you sign
|
select a country-specific language in the **Languages** menu when you sign
|
||||||
up. E.g. use **English (United Kingdom)** if you plan to translate Zulip
|
up. E.g., use **English (United Kingdom)** if you plan to translate Zulip
|
||||||
into UK English, but select **Russian** rather than **Russian (Russia)** for
|
into UK English, but select **Russian** rather than **Russian (Russia)** for
|
||||||
general Russian translations.
|
general Russian translations.
|
||||||
:::
|
:::
|
||||||
|
@ -132,13 +132,13 @@ There are a few ways to see your translations in the Zulip UI:
|
||||||
- If your system has languages configured in your OS/browser, Zulip's
|
- If your system has languages configured in your OS/browser, Zulip's
|
||||||
portico (logged-out) pages will automatically use your configured
|
portico (logged-out) pages will automatically use your configured
|
||||||
language. Note that we only tag for translation strings in pages
|
language. Note that we only tag for translation strings in pages
|
||||||
that individual users need to use (e.g. `/login/`, `/register/`,
|
that individual users need to use (e.g., `/login/`, `/register/`,
|
||||||
etc.), not marketing pages like `/features/`.
|
etc.), not marketing pages like `/features/`.
|
||||||
- In case you need to understand how the above interact, Zulip figures
|
- In case you need to understand how the above interact, Zulip figures
|
||||||
out the language the user requests in a browser using the following
|
out the language the user requests in a browser using the following
|
||||||
prioritization (mostly copied from the Django docs):
|
prioritization (mostly copied from the Django docs):
|
||||||
|
|
||||||
1. It looks for the language code as a URL prefix (e.g. `/de/login/`).
|
1. It looks for the language code as a URL prefix (e.g., `/de/login/`).
|
||||||
1. It looks for the cookie named 'django_language'. You can set a
|
1. It looks for the cookie named 'django_language'. You can set a
|
||||||
different name through the `LANGUAGE_COOKIE_NAME` setting.
|
different name through the `LANGUAGE_COOKIE_NAME` setting.
|
||||||
1. It looks for the `Accept-Language` HTTP header in the HTTP request
|
1. It looks for the `Accept-Language` HTTP header in the HTTP request
|
||||||
|
@ -180,7 +180,7 @@ translation:
|
||||||
### Translation style guides
|
### Translation style guides
|
||||||
|
|
||||||
We maintain translation style guides for Zulip, giving guidance on how
|
We maintain translation style guides for Zulip, giving guidance on how
|
||||||
Zulip should be translated into specific languages (e.g. what word to
|
Zulip should be translated into specific languages (e.g., what word to
|
||||||
translate words like "channel" to), with reasoning, so that future
|
translate words like "channel" to), with reasoning, so that future
|
||||||
translators can understand and preserve those decisions:
|
translators can understand and preserve those decisions:
|
||||||
|
|
||||||
|
@ -223,6 +223,6 @@ The Zulip test suite enforces these capitalization guidelines in the
|
||||||
web app codebase [in our test
|
web app codebase [in our test
|
||||||
suite](../testing/testing.md#other-test-suites)
|
suite](../testing/testing.md#other-test-suites)
|
||||||
(`./tools/check-capitalization`; `tools/lib/capitalization.py` has
|
(`./tools/check-capitalization`; `tools/lib/capitalization.py` has
|
||||||
some exclude lists, e.g. `IGNORED_PHRASES`).
|
some exclude lists, e.g., `IGNORED_PHRASES`).
|
||||||
|
|
||||||
[translation-channel]: https://chat.zulip.org/#narrow/channel/58-translation
|
[translation-channel]: https://chat.zulip.org/#narrow/channel/58-translation
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
Use semi-formal Urdu for translation:
|
Use semi-formal Urdu for translation:
|
||||||
|
|
||||||
- Formal "you" (_آپ_) instead of informal form _تم_. Many top software
|
- Formal "you" (_آپ_) instead of informal form _تم_. Many top software
|
||||||
companies (e.g. Google, Facebook, Microsoft) use the formal one, because it's typically
|
companies (e.g., Google, Facebook, Microsoft) use the formal one, because it's typically
|
||||||
considered rude to use the informal one without an established acquaintance with someone.
|
considered rude to use the informal one without an established acquaintance with someone.
|
||||||
|
|
||||||
- Imperative, active, and continuous verbs, e.g. _manage streams_ -
|
- Imperative, active, and continuous verbs, e.g., _manage streams_ -
|
||||||
_سٹریمس کی رہنمائ کریں_, not _سٹریمس کی رہنمائ_.
|
_سٹریمس کی رہنمائ کریں_, not _سٹریمس کی رہنمائ_.
|
||||||
|
|
||||||
- Warm and friendly phrasing whenever appropriate.
|
- Warm and friendly phrasing whenever appropriate.
|
||||||
|
@ -15,7 +15,7 @@ Use semi-formal Urdu for translation:
|
||||||
|
|
||||||
- Balance common verbs and nouns with specific IT-related translations
|
- Balance common verbs and nouns with specific IT-related translations
|
||||||
of English terms - this can be tricky, try to check how other
|
of English terms - this can be tricky, try to check how other
|
||||||
resources were translated (e.g. Gmail, Microsoft websites, Facebook)
|
resources were translated (e.g., Gmail, Microsoft websites, Facebook)
|
||||||
to decide what wouldn't sound awkward/rude in Urdu.
|
to decide what wouldn't sound awkward/rude in Urdu.
|
||||||
|
|
||||||
Some terms are very tricky to translate, so be sure to communicate
|
Some terms are very tricky to translate, so be sure to communicate
|
||||||
|
|
|
@ -117,7 +117,7 @@ includes both views that serve HTML (new pages on Zulip) as well as new
|
||||||
API endpoints that serve JSON-formatted data.
|
API endpoints that serve JSON-formatted data.
|
||||||
|
|
||||||
**Testing:** At the very least, add a test of your event data flowing
|
**Testing:** At the very least, add a test of your event data flowing
|
||||||
through the system in `test_events.py` and an API test (e.g. for a
|
through the system in `test_events.py` and an API test (e.g., for a
|
||||||
Realm setting, in `test_realm.py`).
|
Realm setting, in `test_realm.py`).
|
||||||
|
|
||||||
### Frontend changes
|
### Frontend changes
|
||||||
|
@ -506,7 +506,7 @@ framework is `do_set_realm_property_test`, and in `test_realm.py`, it is
|
||||||
`do_test_realm_update_api`.
|
`do_test_realm_update_api`.
|
||||||
|
|
||||||
One still needs to add a test for whether the setting actually
|
One still needs to add a test for whether the setting actually
|
||||||
controls the feature it is supposed to control, however (e.g. for this
|
controls the feature it is supposed to control, however (e.g., for this
|
||||||
example feature, whether sending a message without a topic fails with
|
example feature, whether sending a message without a topic fails with
|
||||||
the setting enabled).
|
the setting enabled).
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ Linux/macOS environments (Unix shells). You can also use a tool, for example
|
||||||
|
|
||||||
When searching Google, or Zulip's docs, you'll find commands that begin
|
When searching Google, or Zulip's docs, you'll find commands that begin
|
||||||
with a dollar sign `$` or a dollar sign preceded by some text
|
with a dollar sign `$` or a dollar sign preceded by some text
|
||||||
(e.g. `(venv)john@laptop:~$`).
|
(e.g., `(venv)john@laptop:~$`).
|
||||||
|
|
||||||
This is called the **prompt**, and it's only an indicator that the shell is
|
This is called the **prompt**, and it's only an indicator that the shell is
|
||||||
awaiting new orders. The prompt can contain useful information, let's look
|
awaiting new orders. The prompt can contain useful information, let's look
|
||||||
|
@ -168,7 +168,7 @@ the shell provides two different separators:
|
||||||
|
|
||||||
Sometimes you end up with a very long command, that is hard to read and may
|
Sometimes you end up with a very long command, that is hard to read and may
|
||||||
be unclear. This is a problem, especially if you want to share that command,
|
be unclear. This is a problem, especially if you want to share that command,
|
||||||
e.g. in a documentation file.
|
e.g., in a documentation file.
|
||||||
|
|
||||||
In those cases, you can use a backslash at the end of each line, to inform the
|
In those cases, you can use a backslash at the end of each line, to inform the
|
||||||
shell "wait, there's more on the next line".
|
shell "wait, there's more on the next line".
|
||||||
|
@ -328,7 +328,7 @@ There are many more commands in the shell, besides the ones explained in this
|
||||||
file.
|
file.
|
||||||
[Here](https://www.git-tower.com/blog/command-line-cheat-sheet/) you can find
|
[Here](https://www.git-tower.com/blog/command-line-cheat-sheet/) you can find
|
||||||
a simple yet useful cheatsheet, created by Tower, that could help you
|
a simple yet useful cheatsheet, created by Tower, that could help you
|
||||||
understand and remember what other common commands do (e.g. `ls`).
|
understand and remember what other common commands do (e.g., `ls`).
|
||||||
|
|
||||||
## Git
|
## Git
|
||||||
|
|
||||||
|
|
|
@ -193,7 +193,7 @@ REQ also helps us with request variable validation. For example:
|
||||||
not automatically marshall the input from JSON).
|
not automatically marshall the input from JSON).
|
||||||
|
|
||||||
- Since there is no need to JSON-encode strings, usually simply
|
- Since there is no need to JSON-encode strings, usually simply
|
||||||
`my_string=REQ()` is correct. One can pass e.g.
|
`my_string=REQ()` is correct. One can pass e.g.,
|
||||||
`str_validator=check_string_in(...)` where one wants to run a
|
`str_validator=check_string_in(...)` where one wants to run a
|
||||||
validator on the value of a string.
|
validator on the value of a string.
|
||||||
|
|
||||||
|
@ -252,7 +252,7 @@ code (i.e. all 400 type errors are thrown there), and the actions code
|
||||||
is responsible for atomically executing the change (this is usually
|
is responsible for atomically executing the change (this is usually
|
||||||
signalled by having the actions function have a name starting with
|
signalled by having the actions function have a name starting with
|
||||||
`do_`. So in most cases, errors in an actions function will be the
|
`do_`. So in most cases, errors in an actions function will be the
|
||||||
result of an operational problem (e.g. lost connection to the
|
result of an operational problem (e.g., lost connection to the
|
||||||
database) and lead to a 500 error. If an actions function is
|
database) and lead to a 500 error. If an actions function is
|
||||||
responsible for validation as well, it should have a name starting
|
responsible for validation as well, it should have a name starting
|
||||||
with `check_`.
|
with `check_`.
|
||||||
|
|
Loading…
Reference in New Issue