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
|
||||
you were expecting.
|
||||
- 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.
|
||||
- Is the new UI aligned correctly with the elements around it, both vertically and
|
||||
horizontally?
|
||||
- If the PR adds or modifies a clickable element, does it have a hover behavior
|
||||
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
|
||||
UI elements?
|
||||
- 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:
|
||||
|
||||
- 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.
|
||||
- Use proper capitalization and punctuation.
|
||||
- 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.
|
||||
|
||||
- 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
|
||||
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
|
||||
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 reviewing my PR! ... ”
|
||||
|
@ -101,7 +101,7 @@ to try something new.
|
|||
|
||||
- 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
|
||||
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
|
||||
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`.
|
||||
|
||||
- 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`).
|
||||
|
||||
- `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**:
|
||||
|
||||
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
|
||||
haven't already).
|
||||
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
|
||||
|
||||
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
|
||||
certificate. While `run-dev` doesn't support that, you can do this
|
||||
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
|
||||
```
|
||||
|
||||
1. Open `/etc/rabbitmq/rabbitmq-env.conf` using e.g.:
|
||||
1. Open `/etc/rabbitmq/rabbitmq-env.conf` using e.g.,:
|
||||
|
||||
```console
|
||||
$ 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
|
||||
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
|
||||
subcommands that failed. Once you've resolved the problem, you can
|
||||
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
|
||||
complex, e.g.:
|
||||
complex, e.g.,:
|
||||
|
||||
```text
|
||||
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
|
||||
|
||||
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
|
||||
HOST_PORT 9971
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
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
|
||||
using `vagrant destroy` and then `vagrant up`. This will usually be
|
||||
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
|
||||
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
|
||||
when you recreate it. To address this, you can create a script called
|
||||
`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
|
||||
|
||||
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
|
||||
into the installer.
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ the development environment][authentication-dev-server].
|
|||
## Common
|
||||
|
||||
- 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
|
||||
on an old version of the Zulip codebase (leading to unnecessary
|
||||
merge conflicts).
|
||||
|
|
|
@ -354,7 +354,7 @@ it? There's several major benefits to this system:
|
|||
pre-substituted for the user.
|
||||
- We're able to share implementation language and visual styling with
|
||||
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
|
||||
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
|
||||
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
|
||||
documentation in `zerver/openapi/zulip.yaml`, e.g.:
|
||||
documentation in `zerver/openapi/zulip.yaml`, e.g.,:
|
||||
|
||||
```yaml
|
||||
/user_uploads:
|
||||
|
|
|
@ -19,7 +19,7 @@ and a handful of longer guides. The feature articles serve a few different purpo
|
|||
organization settings.
|
||||
|
||||
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
|
||||
on ReadTheDocs, since Zulip supports running a server completely disconnected
|
||||
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.
|
||||
|
||||
- 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
|
||||
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
|
||||
documentation. It's worth remembering that for most articles, almost 100% of
|
||||
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.
|
||||
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.
|
||||
|
@ -208,7 +208,7 @@ as guidance when documenting Zulip's features.
|
|||
### User interface
|
||||
|
||||
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
|
||||
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>`).
|
||||
|
||||
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
|
||||
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.
|
||||
|
@ -290,7 +290,7 @@ your documentation to help improve its readability:
|
|||
### Images
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -435,7 +435,7 @@ languages in API docs, etc. To create a tab switcher, write:
|
|||
{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
|
||||
[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 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
|
||||
Zulip development environment provisioning, and you can build the
|
||||
documentation using:
|
||||
|
@ -58,7 +58,7 @@ documentation using:
|
|||
and then opening `http://127.0.0.1:9991/docs/index.html` in your
|
||||
browser. The raw files are available at
|
||||
`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).
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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)
|
||||
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: 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: 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
|
||||
are merging other users' commits into a Zulip repository. After doing
|
||||
`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:
|
||||
|
||||
- Getting CI to run and enabling you to use the GitHub "Merge" buttons
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# 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
|
||||
[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
|
||||
|
@ -125,7 +125,7 @@ You can find many examples in the
|
|||
working on, not just issue/PR numbers.
|
||||
|
||||
- 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
|
||||
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
|
||||
|
@ -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
|
||||
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
|
||||
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.
|
||||
|
|
|
@ -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,
|
||||
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.
|
||||
|
||||
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/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
|
||||
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
|
||||
|
@ -256,7 +256,7 @@ administrator, e.g., in case of outages.
|
|||
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
|
||||
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
|
||||
`/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
|
||||
closing on some keypresses.
|
||||
- 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 the gear menu staying open after clicking on “plan management”.
|
||||
- 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
|
||||
file uploads backend.
|
||||
- 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
|
||||
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.
|
||||
|
@ -1813,7 +1813,7 @@ _Released 2021-05-13_
|
|||
`zulip::foo` to `zulip::profile::foo`. Configuration referencing
|
||||
these `/etc/zulip/zulip.conf` will be automatically updated during
|
||||
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
|
||||
[docker-zulip][docker-zulip]), you'll want to manually update the
|
||||
`puppet_classes` variable.
|
||||
|
@ -1895,7 +1895,7 @@ _Released 2021-05-13_
|
|||
unsubscribe links.
|
||||
- Password forms now have a "Show password" widget.
|
||||
- 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 numerous rare exceptions when running Zulip at scale.
|
||||
- Fixed several subtle installer bugs.
|
||||
|
@ -3439,7 +3439,7 @@ _Released 2017-10-25_
|
|||
- Switched from npm to yarn for downloading JS packages.
|
||||
- Switched the function of the 'q' and 'w' search hotkeys.
|
||||
- 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".
|
||||
- Improved title and alt text for Unicode emoji.
|
||||
- Added development tools to make iterating on emails and error pages easy.
|
||||
|
@ -3657,7 +3657,7 @@ _Released 2017-02-06_
|
|||
notifications.
|
||||
- Added buttons to download .zuliprc files.
|
||||
- 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
|
||||
Zulip version.
|
||||
- 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 text overflow in stream subscriptions.
|
||||
- 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 annoying @-mentions in Jira integration.
|
||||
- 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
|
||||
in settings.py.
|
||||
- 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 Codeship, Pingdom, Taiga, TeamCity, and Yo integrations.
|
||||
- Added Nagios plugins to the main distribution.
|
||||
|
|
|
@ -92,7 +92,7 @@ Django context (i.e. with database access).
|
|||
|
||||
- `zerver/management/commands/`
|
||||
[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).
|
||||
|
||||
- `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.
|
||||
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
|
||||
production accidentally (e.g. things that delete the Zulip database
|
||||
production accidentally (e.g., things that delete the Zulip database
|
||||
without prompting).
|
||||
|
||||
- `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.
|
||||
- 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,
|
||||
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).
|
||||
- [New major releases][blog-major-releases], like Zulip 7.0, are
|
||||
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/).
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
`/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
|
||||
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 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
|
||||
Python dictionary:
|
||||
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.
|
||||
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
|
||||
|
@ -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
|
||||
`ZulipDummyBackend` - which is the final layer of the authentication
|
||||
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.
|
||||
:::
|
||||
|
||||
|
|
|
@ -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
|
||||
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].
|
||||
|
||||
[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
|
||||
|
||||
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
|
||||
corporate email system), you will likely need to use something like
|
||||
these setting values:
|
||||
|
@ -118,7 +118,7 @@ how to make it work:
|
|||
["less secure"](https://support.google.com/accounts/answer/6010255);
|
||||
Gmail doesn't allow servers to send outgoing email by default.
|
||||
- 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
|
||||
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
|
||||
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`).
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
`/etc/zulip/settings.py` to configure the host to suit the new host's needs,
|
||||
then restore with `--keep-settings`:
|
||||
|
@ -197,7 +197,7 @@ emails to send). You can check whether these queues are empty using
|
|||
#### Backup details
|
||||
|
||||
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
|
||||
included in the backups generated by Zulip's standard tools. The
|
||||
data includes:
|
||||
|
@ -213,7 +213,7 @@ data includes:
|
|||
will be stored in that directory and you'll want to back it up.
|
||||
|
||||
- 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
|
||||
able to verify their cookies. If you lose `avatar_salt`, any
|
||||
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
|
||||
(`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
|
||||
`<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
|
||||
```
|
||||
|
||||
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
|
||||
./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`
|
||||
in the management shell before deleting the organization from the
|
||||
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
|
||||
rm -rf /home/zulip/uploads/*/2/
|
||||
|
|
|
@ -54,14 +54,14 @@ unlikely to ever need to interact with that realm.)
|
|||
Unless you are
|
||||
[hosting multiple organizations on your Zulip server](multiple-organizations.md),
|
||||
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
|
||||
zulip@zulip:~$ /home/zulip/deployments/current/manage.py show_admins -r ''
|
||||
```
|
||||
|
||||
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`.
|
||||
|
||||
## 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
|
||||
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
|
||||
[zulip.com](https://zulip.com)).
|
||||
- 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.
|
||||
|
||||
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,
|
||||
we support changes in stable release branches as though they were
|
||||
released.
|
||||
|
@ -190,8 +190,8 @@ upgrade to Zulip `main` using [upgrade-zulip-from-git][]. Before
|
|||
upgrading to `main`, make sure you understand:
|
||||
|
||||
- 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
|
||||
"older" than the next major release (E.g. `3.0` or `4.0`).
|
||||
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`).
|
||||
- The `main` branch is under very active development; dozens of new
|
||||
changes are integrated into it on most days. The `main` branch
|
||||
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 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`.
|
||||
|
||||
Web security standards mean that one subdomain per organization is
|
||||
|
@ -81,12 +81,12 @@ into the database.
|
|||
### 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
|
||||
"subdomain".
|
||||
|
||||
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
|
||||
organizations, because the auth cookies for the root domain are
|
||||
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
|
||||
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
|
||||
`SOCIAL_AUTH_SUBDOMAIN = 'auth'` in `/etc/zulip/settings.py`, so that
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ on hardware requirements for larger organizations.
|
|||
features](https://zulip.com/help/allow-image-link-previews).
|
||||
- Outgoing SMTP access (usually port 587) to your [SMTP
|
||||
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
|
||||
certificates [with Certbot][doc-certbot], and to enable other
|
||||
services such as Google authentication, public DNS name is simpler,
|
||||
|
@ -143,7 +143,7 @@ certificate documentation](ssl-certificates.md).
|
|||
#### Outgoing email
|
||||
|
||||
- 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
|
||||
reset, etc.). If you don't have an existing outgoing SMTP solution,
|
||||
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
|
||||
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)
|
||||
- total user accounts (can be much larger)
|
||||
- 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
|
||||
`/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.
|
||||
|
||||
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
|
||||
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`
|
||||
and then run
|
||||
`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
|
||||
that can be quite difficult to debug. Be sure to declare your
|
||||
`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
|
||||
IPv6 configuration).
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ strength allowed is controlled by two settings in
|
|||
already been sent. As a general philosophy, our policies provide
|
||||
hard limits on the ways in which message content can be changed or
|
||||
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:
|
||||
|
||||
- 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
|
||||
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
|
||||
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.)
|
||||
|
||||
- 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.
|
||||
- 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
|
||||
notifications, or create other bots).
|
||||
- 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
|
||||
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`
|
||||
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.)
|
||||
|
||||
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
|
||||
access control verified (confirming that the browser is logged into
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
|
|
|
@ -87,11 +87,11 @@ that version of Zulip.
|
|||
|
||||
Branches with names like `2.1.x` are stable release branches,
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
and try again.
|
||||
- Especially when using `upgrade-zulip-from-git`, systems with the
|
||||
|
@ -197,7 +197,7 @@ in any reports.
|
|||
|
||||
### 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
|
||||
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:
|
||||
|
||||
- `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`
|
||||
(e.g. `7.0-beta3-2-gdc158b18f2`).
|
||||
release name (e.g., `7.0` or `7.0-beta3`) or the output from `git describe`
|
||||
(e.g., `7.0-beta3-2-gdc158b18f2`).
|
||||
- `ZULIP_NEW_VERSION`: The version being upgraded to, in the same format as
|
||||
`ZULIP_OLD_VERSION`.
|
||||
|
||||
|
@ -258,7 +258,7 @@ hooks included with Zulip.
|
|||
|
||||
:::{warning}
|
||||
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`.
|
||||
:::
|
||||
|
||||
|
@ -292,7 +292,7 @@ and the latter for `server` contexts.
|
|||
## Upgrading the operating system
|
||||
|
||||
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
|
||||
below.
|
||||
|
||||
|
@ -314,7 +314,7 @@ instructions for other supported platforms.
|
|||
```
|
||||
|
||||
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
|
||||
successfully:
|
||||
|
||||
|
@ -367,7 +367,7 @@ instructions for other supported platforms.
|
|||
```
|
||||
|
||||
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
|
||||
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
|
||||
`/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
|
||||
`/etc/zulip/settings.py` (add a `#` at the start of the line).
|
||||
|
||||
1. If you are using a non-AWS block storage provider,
|
||||
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`
|
||||
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
|
||||
take effect
|
||||
|
|
|
@ -7,7 +7,7 @@ designed around the following goals:
|
|||
|
||||
- Minimal impact on scalability and service complexity.
|
||||
- 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.
|
||||
- Storage size smaller than the size of the main Message/UserMessage
|
||||
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)
|
||||
frequency. The time interval is determined by the `CountStat`.
|
||||
- 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
|
||||
`RealmCount` table, this is the number of active humans or bots (depending
|
||||
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
|
||||
in Zulip) rather than the ORM.
|
||||
- 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
|
||||
each user, we just query for each user, and then add up the numbers for
|
||||
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
|
||||
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
|
||||
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
|
||||
`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
|
||||
verified.
|
||||
- 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
|
||||
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.
|
||||
|
@ -211,7 +211,7 @@ Tips and tricks:
|
|||
isn't documented well.
|
||||
- `'paper'` as a Plotly option refers to the bounding box of the graph (or
|
||||
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
|
||||
on top of it. But if you hunt around the document tree you should be able
|
||||
to find it.
|
||||
|
|
|
@ -47,7 +47,7 @@ work.
|
|||
As a side note, the policy of using these accessor functions wherever
|
||||
possible is a good idea, regardless of caching, because the functions
|
||||
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
|
||||
places invariably ends up buggy in some of those places, and 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
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -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,
|
||||
`generate_bulk_cached_fetch`, which is super magical and handles this
|
||||
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).
|
||||
|
||||
## In-process caching in Django
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
`zerver.models.Client` is Zulip's analogue of the HTTP User-Agent
|
||||
header (and is populated from User-Agent). It exists for use in
|
||||
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?).
|
||||
|
||||
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.
|
||||
Since we have a few different installation targets, we maintain
|
||||
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
|
||||
majority of packages common to prod and development, etc.). We use
|
||||
`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
|
||||
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
|
||||
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
|
||||
our instructions for
|
||||
[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
|
||||
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`
|
||||
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
|
||||
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
|
||||
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
|
||||
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).
|
||||
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
|
||||
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.
|
||||
|
|
|
@ -64,15 +64,15 @@ to be consumed by the delivery system.
|
|||
|
||||
Usually, this list of users is one of 3 things:
|
||||
|
||||
- A single user (e.g. for user-level settings changes).
|
||||
- Everyone in the realm (e.g. for organization-level settings changes,
|
||||
- A single user (e.g., for user-level settings changes).
|
||||
- Everyone in the realm (e.g., for organization-level settings changes,
|
||||
like new realm emoji).
|
||||
- Everyone who would receive a given message (for messages, emoji
|
||||
reactions, message editing, etc.); i.e. the subscribers to a channel
|
||||
or the people on a direct message thread.
|
||||
|
||||
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
|
||||
organization. However, if an event isn't sent to enough clients,
|
||||
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
|
||||
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,
|
||||
messages, etc. (aka the "initial state").
|
||||
- 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
|
||||
was created.
|
||||
- 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
|
||||
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:
|
||||
|
||||
- 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.
|
||||
- Check the events generated are documented in the [OpenAPI
|
||||
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
|
||||
issues with the mobile and terminal projects to notify them.
|
||||
- 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
|
||||
supports old clients connecting to a modern server. See our
|
||||
[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
|
||||
commit. We attempt to contain that sort of logic in the `from_dict`
|
||||
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
|
||||
`client_capabilities` entry should be marked with a
|
||||
`# TODO/compatibility: ...` comment noting when it can be safely deleted;
|
||||
we grep for these comments entries during major releases.
|
||||
- Schema changes are a sensitive operation, and like with database
|
||||
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
|
||||
to actually process a pre-upgrade event and verify via the browser
|
||||
console what came out.
|
||||
|
|
|
@ -30,9 +30,9 @@ different flows:
|
|||
- The user uses the "back" button in their browser (basically
|
||||
equivalent to the previous one, as a _link_ out of the browser history
|
||||
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
|
||||
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
|
||||
animation (etc.).
|
||||
- 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
|
||||
deployed, or when a user comes back after being idle for a while,
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
- `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.
|
||||
- `hashchange.do_hashchange_normal` handles most cases, like loading the main
|
||||
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
|
||||
the new CSS looks good at a wide range of screen widths, from very
|
||||
wide screen (e.g. 1920px) all the way down to narrow phone screens
|
||||
(e.g. 480px).
|
||||
wide screen (e.g., 1920px) all the way down to narrow phone screens
|
||||
(e.g., 480px).
|
||||
|
||||
For complex changes, it's definitely worth testing in a few different
|
||||
browsers to make sure things look the same.
|
||||
|
@ -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
|
||||
`app` and `common` bundles.
|
||||
- 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
|
||||
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
|
||||
`templates/zerver/base.html`) in the relevant Jinja2 template to
|
||||
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
|
||||
server is restarted, files are copied into that directory.
|
||||
- We use the VFL (versioned file layout) strategy, where each file in
|
||||
the codebase (e.g. `favicon.ico`) gets a new name
|
||||
(e.g. `favicon.c55d45ae8c58.ico`) that contains a hash in it. Each
|
||||
the codebase (e.g., `favicon.ico`) gets a new name
|
||||
(e.g., `favicon.c55d45ae8c58.ico`) that contains a hash in it. Each
|
||||
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
|
||||
benefit of this VFL approach is that all the static files for past
|
||||
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
|
||||
any incremental rollout strategy where different clients get
|
||||
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
|
||||
without breaking the rendering of old messages (or doing a
|
||||
mass-rerender of old messages).
|
||||
|
|
|
@ -111,7 +111,7 @@ The format of this output is:
|
|||
- HTTP method
|
||||
- HTTP status code
|
||||
- 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,
|
||||
etc.)
|
||||
- Endpoint/URL from zproject/urls.py
|
||||
|
@ -200,7 +200,7 @@ Blueslip supports several error levels:
|
|||
than returning execution to the caller.
|
||||
- `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
|
||||
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).
|
||||
- `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
|
||||
|
@ -208,7 +208,7 @@ Blueslip supports several error levels:
|
|||
production.
|
||||
- `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
|
||||
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).
|
||||
- `blueslip.debug`: Similar to `blueslip.log`, but are not printed to
|
||||
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
|
||||
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.
|
||||
- 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.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
old email address).
|
||||
- For a sysadmin to easily interact with and script common possible
|
||||
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
|
||||
|
||||
|
|
|
@ -147,10 +147,10 @@ object and other arguments passed into `do_convert` (`sent_by_bot`,
|
|||
`translate_emoticons`, `mention_data`, etc.). Because
|
||||
Python-Markdown doesn't support directly passing arguments into the
|
||||
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.
|
||||
|
||||
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,
|
||||
or rendering custom profile fields), one needs to just pass in a
|
||||
`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
|
||||
successful in products ranging from blogs to wikis to bug trackers:
|
||||
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
|
||||
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
|
||||
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
|
||||
results).
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ as follows:
|
|||
|
||||
- `do_send_messages` is the synchronous message-sending code path,
|
||||
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`
|
||||
table's `flags` structure, which is in turn passed into
|
||||
`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
|
||||
current events system clients registered to receive `message`
|
||||
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).
|
||||
- The `receiver_is_off_zulip` check is effectively repeated when
|
||||
event queues are garbage-collected (in `missedmessage_hook`) by
|
||||
|
@ -89,7 +89,7 @@ as follows:
|
|||
notifications in cases like a mention added during message
|
||||
editing.
|
||||
- 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
|
||||
editing a message to add/remove a mention.
|
||||
- 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?
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -53,7 +53,7 @@ channels.)
|
|||
|
||||
### 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
|
||||
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
|
||||
|
|
|
@ -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
|
||||
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
|
||||
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
|
||||
using Zulip).
|
||||
|
||||
|
@ -36,7 +36,7 @@ about that data structure:
|
|||
- 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
|
||||
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?
|
||||
Because this correctly handles the race conditions. For example, if
|
||||
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
|
||||
useful sample code; the `OFFLINE_THRESHOLD_SECS` check is critical
|
||||
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
|
||||
only want to parse the "aggregated" key, which shows the summary
|
||||
answer for "is this user online".
|
||||
|
|
|
@ -5,11 +5,11 @@ used for a variety of purposes:
|
|||
|
||||
- Asynchronously doing expensive operations like sending email
|
||||
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).
|
||||
|
||||
- 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.
|
||||
|
||||
- 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
|
||||
environment (`tools/run-dev` will automatically restart the queue processors
|
||||
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
|
||||
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
|
||||
```
|
||||
|
||||
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.
|
||||
|
|
|
@ -5,12 +5,12 @@ preparing a new 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
|
||||
`requirements` to latest upstream versions so they can burn in (use
|
||||
`pip list --outdated`).
|
||||
- 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`
|
||||
- [Upload strings to
|
||||
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
|
||||
a guessable Git branch name for the pull request (the deployment
|
||||
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.
|
||||
|
||||
### 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
|
||||
DigitalOcean marketplace.
|
||||
- _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
|
||||
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
|
||||
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
|
||||
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
|
||||
to both zulip.git and zulip-internal.git to get a correct version
|
||||
number for future Cloud deployments.
|
||||
- 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
|
||||
`.github/workflows/production-suite.yml`.
|
||||
- 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
|
||||
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
|
||||
version, as well as the changelog changes from the release branch.
|
||||
- _Prereleases only (e.g. 7.0-beta3):_
|
||||
- Atop the prerelease commit (e.g. `7.0-beta3`), make a commit
|
||||
- _Prereleases only (e.g., 7.0-beta3):_
|
||||
- Atop the prerelease commit (e.g., `7.0-beta3`), make a commit
|
||||
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
|
||||
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.
|
||||
|
|
|
@ -49,7 +49,7 @@ migrations.
|
|||
migration that exists on the release branch. This should be
|
||||
followed, on `main`, by a migration which merges the two resulting
|
||||
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
|
||||
to the table, performing data backfills, or building indexes. We
|
||||
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
|
||||
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
|
||||
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
|
||||
feature][migrations-non-atomic] that makes it possible to add
|
||||
`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
|
||||
between, so that we don't block other operations from finishing.
|
||||
- **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
|
||||
migration without doing a bunch of hand investigation. Ideally,
|
||||
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
|
||||
the new column, to ensure that the two data stores agree.
|
||||
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.
|
||||
|
||||
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.
|
||||
- A `message_list` is built on top of `message_list_data` and
|
||||
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.).
|
||||
- A `message_list_view` is built on top of `message_list` and
|
||||
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
|
||||
this article. But it also does a decent amount of client-side
|
||||
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
|
||||
use `@**all**` or mention a user who is not subscribed to the current
|
||||
channel, etc.).
|
||||
|
@ -62,12 +62,12 @@ This section details the ways in which it is different:
|
|||
[queue](queuing.md) to actually send the message.
|
||||
See `maybe_enqueue_notifications` and `zerver/lib/notification_data.py` for
|
||||
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.
|
||||
- Handling the [local echo details](#local-echo).
|
||||
- Handling certain client configuration options that affect
|
||||
messages. E.g. determining whether to send the
|
||||
plaintext/Markdown raw content or the rendered HTML (e.g. the
|
||||
messages. E.g., determining whether to send the
|
||||
plaintext/Markdown raw content or the rendered HTML (e.g., the
|
||||
`apply_markdown` and `client_gravatar` features in our
|
||||
[events API docs](https://zulip.com/api/register-queue)).
|
||||
- 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
|
||||
make queries to the database directly.
|
||||
- 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.
|
||||
- Every query is designed to be a bulk query; we carefully
|
||||
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
|
||||
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
|
||||
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
|
||||
unique value within that namespace identifying the message.
|
||||
- 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
|
||||
means that the settings files are Python programs that set a lot of
|
||||
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
|
||||
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
|
||||
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
|
||||
$ ./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
|
||||
server-specific settings, such as how to send outgoing email, the
|
||||
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
|
||||
access to a Zulip server is to put a default in
|
||||
`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
|
||||
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.).
|
||||
|
||||
In a development environment, we have `zproject/settings.py`, and
|
||||
|
@ -106,7 +106,7 @@ additionally:
|
|||
features like [authentication
|
||||
options](../development/authentication.md) that require secrets to
|
||||
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
|
||||
add additional settings of this form if needed.
|
||||
|
||||
|
@ -152,11 +152,11 @@ want those 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
|
||||
for settings which are checked at runtime, not settings which are only
|
||||
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.
|
||||
|
||||
[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
|
||||
this to other parts of the codebase soon). You can use
|
||||
`#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
|
||||
|
||||
|
|
|
@ -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
|
||||
are both correct.
|
||||
- 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
|
||||
functions.
|
||||
- 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
|
||||
only differs as intended: Done well, it helps avoid the otherwise
|
||||
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
|
||||
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
|
||||
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
`UploadSerializeMixin` manages some of the cleanup work for
|
||||
`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.
|
||||
`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
|
||||
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. Wait for WebStorm to connect to Vagrant. This will be displayed
|
||||
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. Hit `OK` 2 times to get back to the `Run/Debug Configurations` window.
|
||||
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:
|
||||
|
||||
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`
|
||||
(i.e. where the `zulip` Git repository is mounted in the Vagrant guest).
|
||||
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
|
||||
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
|
||||
because of navigation (E.g. login) or because we want to verify the
|
||||
interaction between Zulip logic and browser behavior (E.g. copy/paste,
|
||||
because of navigation (e.g., login) or because we want to verify the
|
||||
interaction between Zulip logic and browser behavior (e.g., copy/paste,
|
||||
keyboard shortcuts, etc.).
|
||||
|
||||
## Running tests
|
||||
|
@ -74,7 +74,7 @@ integration](continuous-integration.md):
|
|||
affects any of the selectors used in the tests? If so, the test may
|
||||
just need to be updated for your changes.
|
||||
- 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.
|
||||
- Does the test fail nondeterministically? If so, the problem is
|
||||
likely that a `waitForSelector` statement is either missing or not
|
||||
|
@ -141,7 +141,7 @@ notes above:
|
|||
`main`.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
|
|
|
@ -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
|
||||
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`).
|
||||
|
||||
## Major test suites
|
||||
|
@ -117,7 +117,7 @@ reasons:
|
|||
|
||||
As a result, Zulip's major test suites should never 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 test) what responses should be used for any outgoing Internet
|
||||
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:
|
||||
|
||||
- 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
|
||||
modules when we migrate those.
|
||||
- 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
|
||||
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
|
||||
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
|
||||
of the module at this stage so CI still passes.
|
||||
- Then a commit just migrating use of `var` to `const/let` without
|
||||
|
|
|
@ -30,7 +30,7 @@ Message 可直译为“消息”、“信息”等,两者皆可,这里统一
|
|||
|
||||
- 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,
|
||||
which is inspired by the chat "Channel" in the game Ingress. Since
|
||||
"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.
|
||||
|
||||
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.
|
||||
|
||||
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.**
|
||||
|
||||
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
|
||||
(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
|
||||
of the reader.
|
||||
|
||||
|
@ -69,14 +69,14 @@ of the reader.
|
|||
|
||||
To be consistent with other online platforms, use continuous labels for buttons,
|
||||
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
|
||||
|
||||
**Try to avoid it.**
|
||||
|
||||
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
|
||||
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
|
||||
|
@ -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:
|
||||
|
||||
- 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.
|
||||
|
||||
### 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
|
||||
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.
|
||||
|
||||
- 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)**
|
||||
|
||||
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.
|
||||
|
||||
_"Direktnachricht" (X/Twitter, Slack)_
|
||||
|
@ -272,7 +272,7 @@ _"Deabonnieren" (YouTube, Transifex)_
|
|||
Transifex has two different translations for "Narrow to" -
|
||||
"Schränke auf ... ein." and "Begrenze auf ... ." Both sound a bit strange to a
|
||||
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.
|
||||
"einschränken auf" sounds equally good, but Transifex shows more use cases for
|
||||
"begrenzen auf".
|
||||
|
@ -282,7 +282,7 @@ _"Schränke auf ... ein." (Transifex) "Begrenze auf ... ." (Transifex)_
|
|||
- Filter - **Filtern**
|
||||
|
||||
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)_
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
- 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).)
|
||||
|
||||
- Imperative, active, and continuous verbs, e.g. _manage streams_ -
|
||||
- Imperative, active, and continuous verbs, e.g., _manage streams_ -
|
||||
_चैनल प्रबंधित करें_, not _चैनल प्रबंधन_.
|
||||
|
||||
- Warm and friendly phrasing whenever appropriate.
|
||||
|
@ -12,7 +12,7 @@
|
|||
|
||||
- Balance common verbs and nouns with specific IT-related translations
|
||||
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.
|
||||
|
||||
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
|
||||
code, and our linters attempt to enforce this. There are some
|
||||
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
|
||||
usable with tools like Google Translate).
|
||||
- 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
|
||||
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
|
||||
include end-of-sentence symbols like `.` and `?` inside the
|
||||
to-be-translated strings, so that translators can correctly
|
||||
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
|
||||
that **concatenating translatable strings** produces broken results
|
||||
(more details with examples are below).
|
||||
|
@ -63,7 +63,7 @@ to understand when implementing an internationalized application:
|
|||
find your string.
|
||||
|
||||
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
|
||||
names differently), but the above issues are likely to be relevant to
|
||||
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
|
||||
ensure this, the error message passed to `JsonableError`
|
||||
should always be a literal string enclosed by `_()`
|
||||
function, e.g.:
|
||||
function, e.g.,:
|
||||
|
||||
```python
|
||||
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
|
||||
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
|
||||
from zproject.backends import check_password_strength, email_belongs_to_ldap
|
||||
|
|
|
@ -2,22 +2,22 @@
|
|||
|
||||
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_).
|
||||
|
||||
- Gender-neutral forms of verbs, e.g. _unsubscribed_ - _odsubskrybowano_,
|
||||
- Gender-neutral forms of verbs, e.g., _unsubscribed_ - _odsubskrybowano_,
|
||||
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_.
|
||||
|
||||
- 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ę_.
|
||||
|
||||
- Warm and friendly phrasing whenever appropriate.
|
||||
|
||||
- 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
|
||||
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
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
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.
|
||||
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
Use informal Spanish for translation:
|
||||
|
||||
- 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
|
||||
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_.
|
||||
|
||||
- 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
|
||||
awkward.
|
||||
|
||||
|
@ -20,7 +20,7 @@ Use informal Spanish for translation:
|
|||
|
||||
- Balance common verbs and nouns with specific IT-related translations
|
||||
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.
|
||||
|
||||
- Latest RAE rule ("solo" should
|
||||
|
|
|
@ -32,7 +32,7 @@ Zulip:
|
|||
:::{note}
|
||||
Unless you plan to contribute country-specific translations, do not
|
||||
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
|
||||
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
|
||||
portico (logged-out) pages will automatically use your configured
|
||||
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/`.
|
||||
- In case you need to understand how the above interact, Zulip figures
|
||||
out the language the user requests in a browser using the following
|
||||
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
|
||||
different name through the `LANGUAGE_COOKIE_NAME` setting.
|
||||
1. It looks for the `Accept-Language` HTTP header in the HTTP request
|
||||
|
@ -180,7 +180,7 @@ translation:
|
|||
### Translation style guides
|
||||
|
||||
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
|
||||
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
|
||||
suite](../testing/testing.md#other-test-suites)
|
||||
(`./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
|
||||
|
|
|
@ -3,10 +3,10 @@
|
|||
Use semi-formal Urdu for translation:
|
||||
|
||||
- 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.
|
||||
|
||||
- Imperative, active, and continuous verbs, e.g. _manage streams_ -
|
||||
- Imperative, active, and continuous verbs, e.g., _manage streams_ -
|
||||
_سٹریمس کی رہنمائ کریں_, not _سٹریمس کی رہنمائ_.
|
||||
|
||||
- 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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
**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`).
|
||||
|
||||
### 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`.
|
||||
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
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.
|
||||
[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
|
||||
understand and remember what other common commands do (e.g. `ls`).
|
||||
understand and remember what other common commands do (e.g., `ls`).
|
||||
|
||||
## Git
|
||||
|
||||
|
|
|
@ -193,7 +193,7 @@ REQ also helps us with request variable validation. For example:
|
|||
not automatically marshall the input from JSON).
|
||||
|
||||
- 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
|
||||
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
|
||||
signalled by having the actions function have a name starting with
|
||||
`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
|
||||
responsible for validation as well, it should have a name starting
|
||||
with `check_`.
|
||||
|
|
Loading…
Reference in New Issue