diff --git a/docs/contributing/code-reviewing.md b/docs/contributing/code-reviewing.md index a4a276850d..7d42f43f58 100644 --- a/docs/contributing/code-reviewing.md +++ b/docs/contributing/code-reviewing.md @@ -236,8 +236,8 @@ We also strongly recommend reviewers to go through the following resources. article by James J. Porter - [Zulip code of conduct](../code-of-conduct.md) -[code-style]: ../contributing/code-style.md -[commit-messages]: ../contributing/version-control.html#commit-messages +[code-style]: code-style.md +[commit-messages]: version-control.html#commit-messages [test-writing]: ../testing/testing.md [mypy]: ../testing/mypy.md [git tool]: ../git/zulip-tools.html#fetch-a-pull-request-and-rebase diff --git a/docs/contributing/gsoc.md b/docs/contributing/gsoc.md index 3f920f9191..a124f01bb7 100644 --- a/docs/contributing/gsoc.md +++ b/docs/contributing/gsoc.md @@ -54,7 +54,7 @@ maintainers. To learn more about the experience of doing GSoC with Zulip, check out our [Zulip's Google Summer of Code 2021 blog post](https://blog.zulip.com/2021/09/30/google-summer-of-code-2021/). Our [guide -for having a great summer with Zulip](../contributing/summer-with-zulip.md) will +for having a great summer with Zulip](summer-with-zulip.md) will also give you a feel for what it's like to do GSoC with us. > _“It has been the best summer I've ever had! I'm thankful to my mentors, my diff --git a/docs/development/authentication.md b/docs/development/authentication.md index 5b3a1b2891..9eb758ce96 100644 --- a/docs/development/authentication.md +++ b/docs/development/authentication.md @@ -138,9 +138,9 @@ details worth understanding: Some OAuth providers (such as Facebook) require HTTPS on the callback URL they post back to, which isn't supported directly by the Zulip development environment. If you run a -[remote Zulip development server](../development/remote.md), we have +[remote Zulip development server](remote.md), we have instructions for -[an nginx reverse proxy with SSL](../development/remote.html#using-an-nginx-reverse-proxy) +[an nginx reverse proxy with SSL](remote.html#using-an-nginx-reverse-proxy) that you can use for your development efforts. ## Testing LDAP in development diff --git a/docs/development/overview.md b/docs/development/overview.md index 20778b7cf3..7c3f1cad91 100644 --- a/docs/development/overview.md +++ b/docs/development/overview.md @@ -76,12 +76,12 @@ machine, take a look at our tips for [developing remotely][dev-remote]. [dev-remote]: remote.md -[install-direct]: ../development/setup-advanced.html#installing-directly-on-ubuntu-debian-centos-or-fedora -[install-vagrant]: ../development/setup-vagrant.md +[install-direct]: setup-advanced.html#installing-directly-on-ubuntu-debian-centos-or-fedora +[install-vagrant]: setup-vagrant.md [self-install-remote]: #installing-remotely [self-slow-internet]: #slow-internet-connections -[configure-proxy]: ../development/setup-vagrant.html#specifying-a-proxy +[configure-proxy]: setup-vagrant.html#specifying-a-proxy [using-dev-env]: using.md [testing]: ../testing/testing.md [ci]: ../git/cloning.html#step-3-configure-continuous-integration-for-your-fork -[install-via-wsl]: ../development/setup-advanced.html#installing-directly-on-windows-10-with-wsl-2 +[install-via-wsl]: setup-advanced.html#installing-directly-on-windows-10-with-wsl-2 diff --git a/docs/development/remote.md b/docs/development/remote.md index 6ecd013bd0..27516db347 100644 --- a/docs/development/remote.md +++ b/docs/development/remote.md @@ -270,8 +270,8 @@ Next, read the following to learn more about developing for Zulip: - [Using the development environment][rtd-using-dev-env] - [Testing][rtd-testing] -[install-direct]: ../development/setup-advanced.html#installing-directly-on-ubuntu-debian-centos-or-fedora -[install-vagrant]: ../development/setup-vagrant.md +[install-direct]: setup-advanced.html#installing-directly-on-ubuntu-debian-centos-or-fedora +[install-vagrant]: setup-vagrant.md [rtd-git-guide]: ../git/index.md [rtd-using-dev-env]: using.md [rtd-testing]: ../testing/testing.md diff --git a/docs/development/request-remote.md b/docs/development/request-remote.md index f72c594157..d3331aea3e 100644 --- a/docs/development/request-remote.md +++ b/docs/development/request-remote.md @@ -70,13 +70,13 @@ Once your remote dev instance is ready: Once you've confirmed you can connect to your remote server, take a look at: -- [developing remotely](../development/remote.md) for tips on using the remote dev +- [developing remotely](remote.md) for tips on using the remote dev instance, and - our [Git & GitHub guide](../git/index.md) to learn how to use Git with Zulip. Next, read the following to learn more about developing for Zulip: -- [Using the development environment](../development/using.md) +- [Using the development environment](using.md) - [Testing](../testing/testing.md) [github-join]: https://github.com/join diff --git a/docs/development/setup-advanced.md b/docs/development/setup-advanced.md index 80f0831b9d..cd6010c44e 100644 --- a/docs/development/setup-advanced.md +++ b/docs/development/setup-advanced.md @@ -21,9 +21,9 @@ that's running one of: You can just run the Zulip provision script on your machine. **Note**: You should not use the `root` user to run the installation. -If you are using a [remote server](../development/remote.md), see +If you are using a [remote server](remote.md), see the -[section on creating appropriate user accounts](../development/remote.html#setting-up-user-accounts). +[section on creating appropriate user accounts](remote.html#setting-up-user-accounts). :::{warning} There is no supported uninstallation process with this @@ -50,7 +50,7 @@ source /srv/zulip-py3-venv/bin/activate Once you've done the above setup, you can pick up the [documentation on using the Zulip development -environment](../development/setup-vagrant.html#step-4-developing), +environment](setup-vagrant.html#step-4-developing), ignoring the parts about `vagrant` (since you're not using it). ## Installing directly on Windows 10 with WSL 2 @@ -151,7 +151,7 @@ installation method described here. to open VSCode connected to your WSL environment. 1. You're done! You can pick up the [documentation on using the - Zulip development environment](../development/setup-vagrant.html#step-4-developing), + Zulip development environment](setup-vagrant.html#step-4-developing), ignoring the parts about `vagrant` (since you're not using it). WSL 2 can be uninstalled by following [Microsoft's documentation][uninstall-wsl] diff --git a/docs/development/setup-vagrant.md b/docs/development/setup-vagrant.md index e61a76bc9a..9ab3f0a0d7 100644 --- a/docs/development/setup-vagrant.md +++ b/docs/development/setup-vagrant.md @@ -151,7 +151,7 @@ Debian](https://docs.docker.com/install/linux/docker-ce/debian/). #### Windows 10 :::{note} -We recommend using [WSL 2 for Windows development](../development/setup-advanced.html#installing-directly-on-windows-10-with-wsl-2). +We recommend using [WSL 2 for Windows development](setup-advanced.html#installing-directly-on-windows-10-with-wsl-2). ::: 1. Install [Git for Windows][git-bash], which installs _Git BASH_. @@ -1041,7 +1041,7 @@ remove the `GUEST_CPUS` and `GUEST_MEMORY_MB` lines from [cygwin-dl]: https://cygwin.com/ [vagrant-dl]: https://www.vagrantup.com/downloads.html [vbox-dl]: https://www.virtualbox.org/wiki/Downloads -[install-advanced]: ../development/setup-advanced.md +[install-advanced]: setup-advanced.md [rtd-git-guide]: ../git/index.md [rtd-testing]: ../testing/testing.md [rtd-using-dev-env]: using.md diff --git a/docs/development/using.md b/docs/development/using.md index 178a9b44ce..0f760fbdd3 100644 --- a/docs/development/using.md +++ b/docs/development/using.md @@ -93,7 +93,7 @@ See the mobile project's documentation on [using a development server for mobile development][mobile-dev-server]. [rest-api]: https://zulip.com/api/rest -[authentication-dev-server]: ./authentication.md +[authentication-dev-server]: authentication.md [django-runserver]: https://docs.djangoproject.com/en/3.2/ref/django-admin/#runserver [new-feature-tutorial]: ../tutorials/new-feature-tutorial.md [testing-docs]: ../testing/testing.md diff --git a/docs/documentation/api.md b/docs/documentation/api.md index 599d077596..d228a15e5b 100644 --- a/docs/documentation/api.md +++ b/docs/documentation/api.md @@ -27,10 +27,10 @@ the validation Zulip has today. Our API documentation is defined by a few sets of files: - The primary source of our API documentation is the Zulip server's - [OpenAPI description](../documentation/openapi.md) at + [OpenAPI description](openapi.md) at `zerver/openapi/zulip.yaml`. - The documentation is written the same Markdown framework that powers - our [help center docs](../documentation/helpcenter.md), with some special + our [help center docs](helpcenter.md), with some special extensions for rendering nice code blocks and example responses. Most API endpoints share a common template, `templates/zerver/api/api-doc-template.md`, which renders the @@ -218,7 +218,7 @@ This section offers a step-by-step process for adding documentation for a new API endpoint. It assumes you've read and understood the above. -1. Start by adding [OpenAPI format](../documentation/openapi.md) +1. Start by adding [OpenAPI format](openapi.md) data to `zerver/openapi/zulip.yaml` for the endpoint. If you copy-paste (which is helpful to get the indentation structure right), be sure to update all the content that you copied to diff --git a/docs/documentation/openapi.md b/docs/documentation/openapi.md index 634e1b3525..6e89adaba7 100644 --- a/docs/documentation/openapi.md +++ b/docs/documentation/openapi.md @@ -10,7 +10,7 @@ for that file to fully describe every endpoint in the Zulip API, and for the Zulip test suite to fail should the API every change without a corresponding adjustment to the documentation. In particular, essentially all content in Zulip's [REST API -documentation](../documentation/api.md) is generated from our OpenAPI +documentation](api.md) is generated from our OpenAPI file. In an OpenAPI Swagger file, every configuration section is an object. diff --git a/docs/documentation/overview.md b/docs/documentation/overview.md index 9b4f6485ea..ffee6610a7 100644 --- a/docs/documentation/overview.md +++ b/docs/documentation/overview.md @@ -124,7 +124,7 @@ with Zulip. This documentation also serves as our main mechanism for Zulip server developers to communicate with client developers about how the Zulip API works. -See the [API documentation tutorial](../documentation/api.md) for +See the [API documentation tutorial](api.md) for details on how to contribute to this documentation. ## Automated testing diff --git a/docs/git/cheat-sheet.md b/docs/git/cheat-sheet.md index 16910b881a..878d6ddb6f 100644 --- a/docs/git/cheat-sheet.md +++ b/docs/git/cheat-sheet.md @@ -113,4 +113,4 @@ See also [fixing commits][fix-commit] [fix-commit]: fixing-commits.md [git-config-clone]: cloning.html#step-1b-clone-to-your-machine -[git-overview]: ./overview.md +[git-overview]: overview.md diff --git a/docs/git/cloning.md b/docs/git/cloning.md index 50c875077a..e40e223e18 100644 --- a/docs/git/cloning.md +++ b/docs/git/cloning.md @@ -137,4 +137,4 @@ You can check the `Actions` tab of your repository to see the builds. [github-actions]: https://docs.github.com/en/actions [zulip-rtd-dev-first-time]: ../development/setup-vagrant.md [zulip-rtd-dev-overview]: ../development/overview.md -[zulip-rtd-tools-setup]: ../git/zulip-tools.html#set-up-git-repo-script +[zulip-rtd-tools-setup]: zulip-tools.html#set-up-git-repo-script diff --git a/docs/git/collaborate.md b/docs/git/collaborate.md index a7b8e54bcd..e11f81bfdd 100644 --- a/docs/git/collaborate.md +++ b/docs/git/collaborate.md @@ -56,4 +56,4 @@ tools/fetch-pull-request ``` [github-help-co-pr-locally]: https://help.github.com/en/articles/checking-out-pull-requests-locally -[tools-pr]: ../git/zulip-tools.html#fetch-a-pull-request-and-rebase +[tools-pr]: zulip-tools.html#fetch-a-pull-request-and-rebase diff --git a/docs/git/overview.md b/docs/git/overview.md index d70e531ef2..2988f5f92f 100644 --- a/docs/git/overview.md +++ b/docs/git/overview.md @@ -59,7 +59,7 @@ Git workflow, or if you'd like a Git refresher. [github-zulip]: https://github.com/zulip/ [github-zulip-zulip]: https://github.com/zulip/zulip/ [continuous-integration]: ../testing/continuous-integration.md -[zulip-git-guide-fork-ci]: ../git/cloning.html#step-3-configure-continuous-integration-for-your-fork +[zulip-git-guide-fork-ci]: cloning.html#step-3-configure-continuous-integration-for-your-fork [zulip-rtd-code-style]: ../contributing/code-style.md [zulip-rtd-commit-discipline]: ../contributing/version-control.html#commit-discipline [zulip-rtd-commit-messages]: ../contributing/version-control.html#commit-messages @@ -67,5 +67,5 @@ Git workflow, or if you'd like a Git refresher. [zulip-rtd-lint-tools]: ../contributing/code-style.html#lint-tools [zulip-rtd-mypy]: ../testing/mypy.md [zulip-rtd-testing]: ../testing/testing.md -[zulip-rtd-zulip-tools]: ../git/zulip-tools.md +[zulip-rtd-zulip-tools]: zulip-tools.md [zulip-rtd-zulipbot-usage]: ../contributing/zulipbot-usage.md diff --git a/docs/git/pull-requests.md b/docs/git/pull-requests.md index 3dba7536de..e0288b6602 100644 --- a/docs/git/pull-requests.md +++ b/docs/git/pull-requests.md @@ -158,7 +158,7 @@ for another review. [github-help-about-pr]: https://help.github.com/en/articles/about-pull-requests [github-help-create-pr-fork]: https://help.github.com/en/articles/creating-a-pull-request-from-a-fork [images-create-pr]: ../images/zulip-open-pr.png -[keep-up-to-date]: ../git/using.html#keep-your-fork-up-to-date -[self-push-commits]: ../git/using.html#push-your-commits-to-github +[keep-up-to-date]: using.html#keep-your-fork-up-to-date +[self-push-commits]: using.html#push-your-commits-to-github [screenshots-gifs]: ../tutorials/screenshot-and-gif-software.md [wip-prs]: #work-in-progress-pull-requests diff --git a/docs/git/troubleshooting.md b/docs/git/troubleshooting.md index 76059e7444..150018a678 100644 --- a/docs/git/troubleshooting.md +++ b/docs/git/troubleshooting.md @@ -275,8 +275,8 @@ keep,** you'll need to use `git log FETCH_HEAD` to identify that hashes of the commits you want to keep and then `git cherry-pick ` those commits into whichever branch you need to update. -[clone-to-your-machine]: ../git/cloning.html#step-1b-clone-to-your-machine -[connect-upstream]: ../git/cloning.html#step-1c-connect-your-fork-to-zulip-upstream +[clone-to-your-machine]: cloning.html#step-1b-clone-to-your-machine +[connect-upstream]: cloning.html#step-1c-connect-your-fork-to-zulip-upstream [gitbook-advanced-merging]: https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_advanced_merging [gitbook-basic-merge-conflicts]: https://git-scm.com/book/en/v2/Git-Branching-Basic-Branching-and-Merging#Basic-Merge-Conflicts [gitbook-git-cherry-pick]: https://git-scm.com/docs/git-cherry-pick diff --git a/docs/git/using.md b/docs/git/using.md index 7acc6c08a7..ec0e8d2d4d 100644 --- a/docs/git/using.md +++ b/docs/git/using.md @@ -450,8 +450,8 @@ complicated rebase. [github-help-push]: https://help.github.com/en/articles/pushing-to-a-remote [github-help-rebase]: https://help.github.com/en/articles/using-git-rebase [github-help-sync-fork]: https://help.github.com/en/articles/syncing-a-fork -[how-git-is-different]: ./the-git-difference.md -[self-multiple-computers]: ../git/troubleshooting.html#working-from-multiple-computers +[how-git-is-different]: the-git-difference.md +[self-multiple-computers]: troubleshooting.html#working-from-multiple-computers [zulip-git-guide-up-to-date]: #keep-your-fork-up-to-date [zulip-rtd-commit-discipline]: ../contributing/version-control.html#commit-discipline [zulip-rtd-commit-messages]: ../contributing/version-control.html#commit-messages diff --git a/docs/git/working-copies.md b/docs/git/working-copies.md index ba7b8826f8..524a7b4667 100644 --- a/docs/git/working-copies.md +++ b/docs/git/working-copies.md @@ -7,7 +7,7 @@ repository that you are generally concerned with: repository](https://github.com/zulip/zulip) on GitHub. You probably don't have write access to this repository. - The **origin** remote: Your personal remote repository on GitHub. - You'll use this to share your code and create [pull requests](../git/pull-requests.md). + You'll use this to share your code and create [pull requests](pull-requests.md). - local copy: This lives on your laptop or your remote dev instance, and is what you'll use to make changes and create commits. @@ -45,6 +45,6 @@ working copies: - `git remote`: This helps you configure short names for remotes. - `git pull`: This pulls code, but by default creates a merge commit (which you definitely don't want). However, if you've followed our - [cloning documentation](../git/cloning.md), this will do + [cloning documentation](cloning.md), this will do `git pull --rebase` instead, which is the only mode you'll want to use when working on Zulip. diff --git a/docs/git/zulip-tools.md b/docs/git/zulip-tools.md index 4a1148e0d1..756b3a1869 100644 --- a/docs/git/zulip-tools.md +++ b/docs/git/zulip-tools.md @@ -176,5 +176,5 @@ git rebase --continue ``` [github-zulip-zulip]: https://github.com/zulip/zulip/ -[zulip-git-guide-fetch-pr]: ../git/collaborate.html#check-out-a-pull-request-locally -[zulip-git-guide-ci]: ../git/cloning.html#step-3-configure-continuous-integration-for-your-fork +[zulip-git-guide-fetch-pr]: collaborate.html#check-out-a-pull-request-locally +[zulip-git-guide-ci]: cloning.html#step-3-configure-continuous-integration-for-your-fork diff --git a/docs/overview/architecture-overview.md b/docs/overview/architecture-overview.md index d8f835bde0..bba3bb7125 100644 --- a/docs/overview/architecture-overview.md +++ b/docs/overview/architecture-overview.md @@ -7,7 +7,7 @@ contains the Zulip backend (written in Python 3.x and Django), the web app (written in JavaScript and TypeScript) and our library of incoming webhook [integrations](https://zulip.com/integrations) with other services and applications (see [the directory structure -guide](../overview/directory-structure.md)). +guide](directory-structure.md)). [Zulip Mobile](https://github.com/zulip/zulip-mobile) is the official mobile Zulip client supporting both iOS and Android, written in @@ -109,7 +109,7 @@ feed. For more details on the frontend, see our documentation on [translation](../translating/translating.md), [templates](../subsystems/html-css.html#html-templates), -[directory structure](../overview/directory-structure.md), and +[directory structure](directory-structure.md), and [the static asset pipeline](../subsystems/html-css.html#static-asset-pipeline). [jinja2]: http://jinja.pocoo.org/ diff --git a/docs/overview/changelog.md b/docs/overview/changelog.md index c1993dbd4b..e37d797723 100644 --- a/docs/overview/changelog.md +++ b/docs/overview/changelog.md @@ -1,7 +1,7 @@ # Version history This page the release history for the Zulip server. See also the -[Zulip release lifecycle](../overview/release-lifecycle.md). +[Zulip release lifecycle](release-lifecycle.md). ## Zulip 5.x series @@ -402,7 +402,7 @@ log][commit-log] for an up-to-date list of raw changes. #### Full feature changelog -- Added new [release lifecycle documentation](../overview/release-lifecycle.md). +- Added new [release lifecycle documentation](release-lifecycle.md). - Added support for subscribing another stream's membership to a stream. - Added RealmAuditLog for most settings state changes in Zulip; this data will facilitate future features showing a log of activity by diff --git a/docs/production/authentication-methods.md b/docs/production/authentication-methods.md index 7b2f7309f0..b5deaaca1a 100644 --- a/docs/production/authentication-methods.md +++ b/docs/production/authentication-methods.md @@ -384,7 +384,7 @@ it as follows: the "SAML ACS url" in SAML terminology. If you're - [hosting multiple organizations](../production/multiple-organizations.html#authentication), + [hosting multiple organizations](multiple-organizations.html#authentication), you need to use `SOCIAL_AUTH_SUBDOMAIN`. For example, if `SOCIAL_AUTH_SUBDOMAIN="auth"` and `EXTERNAL_HOST=zulip.example.com`, this should be `https://auth.zulip.example.com/complete/saml/`. @@ -478,7 +478,7 @@ it as follows: profile fields during login, not during account creation; we consider this [a bug](https://github.com/zulip/zulip/issues/18746). -1. [Restart the Zulip server](../production/settings.md) to ensure +1. [Restart the Zulip server](settings.md) to ensure your settings changes take effect. The Zulip login page should now have a button for SAML authentication that you can use to log in or create an account (including when creating a new organization). @@ -817,7 +817,7 @@ self-hosted servers. To do so, you'll need to do the following: [apple-developer]: https://developer.apple.com/account/resources/ [apple-create-private-key]: https://help.apple.com/developer-account/?lang=en#/dev77c875b7e [apple-get-started]: https://developer.apple.com/sign-in-with-apple/get-started/ -[outgoing-email]: ../production/email.md +[outgoing-email]: email.md ## OpenID Connect @@ -876,4 +876,4 @@ passwordless login as any user in a development environment. It's mentioned on this page only for completeness. [custom-profile-fields]: https://zulip.com/help/add-custom-profile-fields -[update-inline-comments]: ../production/upgrade-or-modify.html#updating-settings-py-inline-documentation +[update-inline-comments]: upgrade-or-modify.html#updating-settings-py-inline-documentation diff --git a/docs/production/deployment.md b/docs/production/deployment.md index b818d7aa84..28a440d27d 100644 --- a/docs/production/deployment.md +++ b/docs/production/deployment.md @@ -18,8 +18,8 @@ git clone https://github.com/zulip/zulip.git zulip-server-git ``` and then -[continue the normal installation instructions](../production/install.html#step-2-install-zulip). -You can also [upgrade Zulip from Git](../production/upgrade-or-modify.html#upgrading-from-a-git-repository). +[continue the normal installation instructions](install.html#step-2-install-zulip). +You can also [upgrade Zulip from Git](upgrade-or-modify.html#upgrading-from-a-git-repository). The most common use case for this is upgrading to `main` to get a feature that hasn't made it into an official release yet (often @@ -33,14 +33,14 @@ In particular, we are always very glad to investigate problems with installing Zulip from `main`; they are rare and help us ensure that our next major release has a reliable install experience. -[upgrade-to-main]: ../production/upgrade-or-modify.html#upgrading-to-main -[upgrade-to-future-release]: ../production/upgrade-or-modify.html#upgrading-to-future-releases +[upgrade-to-main]: upgrade-or-modify.html#upgrading-to-main +[upgrade-to-future-release]: upgrade-or-modify.html#upgrading-to-future-releases ## Zulip in Docker Zulip has an officially supported, experimental [docker image](https://github.com/zulip/docker-zulip). Please note -that Zulip's [normal installer](../production/install.md) has been +that Zulip's [normal installer](install.md) has been extremely reliable for years, whereas the Docker image is new and has rough edges, so we recommend the normal installer unless you have a specific reason to prefer Docker. @@ -49,7 +49,7 @@ specific reason to prefer Docker. The Zulip installer supports the following advanced installer options as well as those mentioned in the -[install](../production/install.html#installer-options) documentation: +[install](install.html#installer-options) documentation: - `--postgresql-version`: Sets the version of PostgreSQL that will be installed. We currently support PostgreSQL 10, 11, 12, 13, and 14. @@ -83,7 +83,7 @@ as well as those mentioned in the Zulip's installation process assumes it is the only application running on the server; though installing alongside other applications is not recommended, we do have [some notes on the -process](../production/install-existing-server.md). +process](install-existing-server.md). ## Running Zulip's service dependencies on different machines @@ -132,7 +132,7 @@ below. #### Step 1: Set up Zulip -Follow the [standard instructions](../production/install.md), with one +Follow the [standard instructions](install.md), with one change. When running the installer, pass the `--no-init-db` flag, e.g.: @@ -535,7 +535,7 @@ configuration of `pg_hba.conf` and client certificates on the replica. [warm-standby]: https://www.postgresql.org/docs/current/warm-standby.html -[wal-g]: ../production/export-and-import.html#backup-details +[wal-g]: export-and-import.html#backup-details ## System and deployment configuration @@ -575,7 +575,7 @@ that include: - **`zulip::profile::rabbitmq`** If you are using a [Apache as a single-sign-on -authenticator](../production/authentication-methods.html#apache-based-sso-with-remote-user), +authenticator](authentication-methods.html#apache-based-sso-with-remote-user), you will need to add **`zulip::apache_sso`** to the list. #### `pgroonga` @@ -604,7 +604,7 @@ for servers that are upgraded frequently by core Zulip developers. #### `git_repo_url` Default repository URL used when [upgrading from a Git -repository](../production/upgrade-or-modify.html#upgrading-from-a-git-repository). +repository](upgrade-or-modify.html#upgrading-from-a-git-repository). ### `[application_server]` @@ -626,7 +626,7 @@ configure `settings.py` and set this to true to configure `nginx`. Remove this field to return to the local uploads backend (any non-empty value is currently equivalent to true). -[s3-uploads]: ../production/upload-backends.html#s3-backend-configuration +[s3-uploads]: upload-backends.html#s3-backend-configuration #### `queue_workers_multiprocess` @@ -669,7 +669,7 @@ more than 3.5GiB of RAM, 4 on hosts with less. #### `mailname` The hostname that [Postfix should be configured to receive mail -at](../production/email-gateway.html#local-delivery-setup). +at](email-gateway.html#local-delivery-setup). ### `[postgresql]` @@ -694,7 +694,7 @@ Set to true to enable replication to enable [log shipping replication between PostgreSQL servers](#postgresql-warm-standby). This should be enabled on the primary, as well as any replicas, and further requires configuration of -[wal-g](../production/export-and-import.html#backup-details). +[wal-g](export-and-import.html#backup-details). #### `replication_primary` @@ -726,7 +726,7 @@ connections. #### `version` The version of PostgreSQL that is in use. Do not set by hand; use the -[PostgreSQL upgrade tool](../production/upgrade-or-modify.html#upgrading-postgresql). +[PostgreSQL upgrade tool](upgrade-or-modify.html#upgrading-postgresql). ### `[memcached]` diff --git a/docs/production/email-gateway.md b/docs/production/email-gateway.md index 95ab110c5d..44274cefe7 100644 --- a/docs/production/email-gateway.md +++ b/docs/production/email-gateway.md @@ -96,7 +96,7 @@ using an [HTTP reverse proxy][reverse-proxy]). Congratulations! The integration should be fully operational. -[reverse-proxy]: ../production/deployment.html#putting-the-zulip-application-behind-a-reverse-proxy +[reverse-proxy]: deployment.html#putting-the-zulip-application-behind-a-reverse-proxy ## Polling setup diff --git a/docs/production/export-and-import.md b/docs/production/export-and-import.md index 1526c80bc6..52fe0974e7 100644 --- a/docs/production/export-and-import.md +++ b/docs/production/export-and-import.md @@ -48,9 +48,9 @@ service (or back): decommissioning a Zulip organization. - It's possible to set up [PostgreSQL streaming - replication](../production/deployment.html#postgresql-warm-standby) + replication](deployment.html#postgresql-warm-standby) and the [S3 file upload - backend](../production/upload-backends.html#s3-backend-configuration) + backend](upload-backends.html#s3-backend-configuration) as part of a high availability environment. ## Backups @@ -99,7 +99,7 @@ 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 -need to [update `EXTERNAL_HOST`](../production/settings.md) and then +need to [update `EXTERNAL_HOST`](settings.md) and then restart the Zulip server (after backup restoration completes). Until you do, your Zulip server will think its user-facing hostname is @@ -118,7 +118,7 @@ extracting the entire archive. tar -Oaxf /path/to/archive/zulip-backup-rest.tar.gz zulip-backup/zulip-version ``` -[install-server]: ../production/install.md +[install-server]: install.md ### What is included @@ -134,7 +134,7 @@ and you may want to back up separately: the rest of the data for a Zulip server. - Files uploaded with the Zulip - [S3 file upload backend](../production/upload-backends.md). We + [S3 file upload backend](upload-backends.md). We don't include these for two reasons. First, the uploaded file data in S3 can easily be many times larger than the rest of the backup, and downloading it all to a server doing a backup could easily @@ -193,7 +193,7 @@ data includes: filenames are computed using a hash of `avatar_salt` and user's email), etc. -[export-import]: ../production/export-and-import.md +[export-import]: export-and-import.md ### Restore from manual backups @@ -285,7 +285,7 @@ archive of all the organization's uploaded files. ## Import into a new Zulip server -1. [Install a new Zulip server](../production/install.md), +1. [Install a new Zulip server](install.md), **skipping Step 3** (you'll create your Zulip organization via the data import tool instead). @@ -320,7 +320,7 @@ archive of all the organization's uploaded files. `/etc/zulip/zulip-secrets.conf` (details below). - If you copy `zulip_org_id` and `zulip_org_key` (the credentials for the [mobile push notifications - service](../production/mobile-push-notifications.md)), you should + service](mobile-push-notifications.md)), you should be very careful to make sure the no users had their IDs renumbered during the import process (this can be checked using `manage.py shell` with some care). The push notifications @@ -365,7 +365,7 @@ cd /home/zulip/deployments/current This could take several minutes to run depending on how much data you're importing. -[upgrade-zulip-from-git]: ../production/upgrade-or-modify.html#upgrading-from-a-git-repository +[upgrade-zulip-from-git]: upgrade-or-modify.html#upgrading-from-a-git-repository #### Import options @@ -411,10 +411,10 @@ delete the test import data from your Zulip server before doing a final import. You can **permanently delete** all data from a Zulip organization using the following procedure: -- Start a [Zulip management shell](../production/management-commands.html#manage-py-shell) +- Start a [Zulip management shell](management-commands.html#manage-py-shell) - In the management shell, run the following commands, replacing `""` with the subdomain if [you are hosting the organization on a - subdomain](../production/multiple-organizations.md): + subdomain](multiple-organizations.md): ```python realm = Realm.objects.get(string_id="") @@ -430,7 +430,7 @@ Now, exit the management shell and run this to clear Zulip's cache: ``` Assuming you're using the -[local file uploads backend](../production/upload-backends.md), you +[local file uploads backend](upload-backends.md), you can additionally delete all file uploads, avatars, and custom emoji on a Zulip server (across **all organizations**) with the following command: diff --git a/docs/production/install.md b/docs/production/install.md index b2ec93ef85..09c19fd975 100644 --- a/docs/production/install.md +++ b/docs/production/install.md @@ -1,11 +1,11 @@ # Production installation You'll need an Ubuntu or Debian system that satisfies -[the installation requirements](../production/requirements.md). Alternatively, +[the installation requirements](requirements.md). Alternatively, you can use a preconfigured [DigitalOcean droplet](https://marketplace.digitalocean.com/apps/zulip?refcode=3ee45da8ee26), or Zulip's -[experimental Docker image](../production/deployment.html#zulip-in-docker). +[experimental Docker image](deployment.html#zulip-in-docker). Note that if you're developing for Zulip, you should install Zulip's [development environment](../development/overview.md) instead. If @@ -27,7 +27,7 @@ tar -xf zulip-server-latest.tar.gz - If you'd like to verify the download, we [publish the sha256sums of our release tarballs](https://download.zulip.com/server/SHA256SUMS.txt). - You can also - [install a pre-release version of Zulip](../production/deployment.html#installing-zulip-from-git) + [install a pre-release version of Zulip](deployment.html#installing-zulip-from-git) using code from our [repository on GitHub](https://github.com/zulip/zulip/). ## Step 2: Install Zulip @@ -72,10 +72,10 @@ If the script gives an error, consult [Troubleshooting](#troubleshooting) below. You can see the more advanced installer options in our [deployment options][doc-deployment-options] documentation. -[doc-settings]: ../production/settings.md -[doc-certbot]: ../production/ssl-certificates.html#certbot-recommended -[doc-ssl-manual]: ../production/ssl-certificates.html#manual-install -[doc-deployment-options]: ../production/deployment.html#advanced-installer-options +[doc-settings]: settings.md +[doc-certbot]: ssl-certificates.html#certbot-recommended +[doc-ssl-manual]: ssl-certificates.html#manual-install +[doc-deployment-options]: deployment.html#advanced-installer-options ## Step 3: Create a Zulip organization, and log in @@ -85,7 +85,7 @@ or another Zulip server, you should stop here and return to the import instructions. [slack-import]: https://zulip.com/help/import-from-slack -[zulip-backups]: ../production/export-and-import.html#backups +[zulip-backups]: export-and-import.html#backups Otherwise, open the link in a browser. Follow the prompts to set up your organization, and your own user account as an administrator. @@ -117,8 +117,8 @@ Learning more: releases](../overview/release-lifecycle.md) and security issues. - Follow [Zulip on Twitter](https://twitter.com/zulip). - Learn how to [configure your Zulip server settings](settings.md). -- Learn about [Backups, export and import](../production/export-and-import.md) - and [upgrading](../production/upgrade-or-modify.md) a production Zulip +- Learn about [Backups, export and import](export-and-import.md) + and [upgrading](upgrade-or-modify.md) a production Zulip server. [realm-admin-docs]: https://zulip.com/help/getting-your-organization-started-with-zulip diff --git a/docs/production/maintain-secure-upgrade.md b/docs/production/maintain-secure-upgrade.md index b951779cc8..d174cf8371 100644 --- a/docs/production/maintain-secure-upgrade.md +++ b/docs/production/maintain-secure-upgrade.md @@ -9,33 +9,33 @@ have since all moved to dedicated pages: ### Monitoring -Moved to [Troubleshooting](../production/troubleshooting.html#monitoring). +Moved to [Troubleshooting](troubleshooting.html#monitoring). ### Securing your Zulip server -Moved to [Security model](../production/security-model.md). +Moved to [Security model](security-model.md). ### Upgrading -Moved to [Upgrading to a release](../production/upgrade-or-modify.html#upgrading-to-a-release). +Moved to [Upgrading to a release](upgrade-or-modify.html#upgrading-to-a-release). ### Upgrading from a Git repository Moved to [Upgrading from a Git -repository](../production/upgrade-or-modify.html#upgrading-from-a-git-repository). +repository](upgrade-or-modify.html#upgrading-from-a-git-repository). ### Upgrading the operating system Moved to [Upgrading the operating -system](../production/upgrade-or-modify.html#upgrading-the-operating-system). +system](upgrade-or-modify.html#upgrading-the-operating-system). ### Scalability -Moved to [Scalability](../production/requirements.html#scalability). +Moved to [Scalability](requirements.html#scalability). ### Management commands -Moved to [Management commands](../production/management-commands.md). +Moved to [Management commands](management-commands.md). ### API and your Zulip URL diff --git a/docs/production/management-commands.md b/docs/production/management-commands.md index 972654220d..8d1b281dff 100644 --- a/docs/production/management-commands.md +++ b/docs/production/management-commands.md @@ -52,7 +52,7 @@ containing system-internal bots like `Notification Bot`; you are unlikely to ever need to interact with that realm.) Unless you are -[hosting multiple organizations on your Zulip server](../production/multiple-organizations.md), +[hosting multiple organizations on your Zulip server](multiple-organizations.md), your single Zulip organization on the root domain will have the empty string (`''`) as its `string_id`. So you can run e.g.: @@ -123,7 +123,7 @@ There are dozens of useful management commands under UI](https://zulip.com/help/change-a-users-role)) or give bots the `can_forge_sender` permission, which is needed for certain special API features. - `./manage.py export_single_user`: does a limited version of the [main - export tools](../production/export-and-import.md) containing just + export tools](export-and-import.md) containing just the messages accessible by a single user. - `./manage.py reactivate_realm`: Reactivates a realm. - `./manage.py deactivate_user`: Deactivates a user. This can be done @@ -171,12 +171,12 @@ the Zulip server. Instead, we recommend deploying custom management commands either via the [modifying Zulip][modifying-zulip] process or by storing them in `/etc/zulip` (so they are included in -[backups](../production/export-and-import.html#backups)) and then +[backups](export-and-import.html#backups)) and then symlinking them into `/home/zulip/deployments/current/zerver/management/` after each upgrade. -[modifying-zulip]: ../production/upgrade-or-modify.html#modifying-zulip +[modifying-zulip]: upgrade-or-modify.html#modifying-zulip [writing-bots]: https://zulip.com/api/writing-bots [integrations]: https://zulip.com/integrations [zulip-api]: https://zulip.com/api/rest diff --git a/docs/production/mobile-push-notifications.md b/docs/production/mobile-push-notifications.md index 3d8efa4acf..13d7033d31 100644 --- a/docs/production/mobile-push-notifications.md +++ b/docs/production/mobile-push-notifications.md @@ -18,7 +18,7 @@ support forwarding push notifications to a central push notification forwarding service. Accessing this service requires outgoing HTTPS access to the public Internet; if that is restricted by a proxy, you will need to [configure Zulip to use your outgoing HTTP -proxy](../production/deployment.html#customizing-the-outgoing-http-proxy) +proxy](deployment.html#customizing-the-outgoing-http-proxy) first. You can enable this for your Zulip server as follows: @@ -27,7 +27,7 @@ You can enable this for your Zulip server as follows: `PUSH_NOTIFICATION_BOUNCER_URL = 'https://push.zulipchat.com'` line in your `/etc/zulip/settings.py` file (i.e. remove the `#` at the start of the line), and [restart your Zulip - server](../production/settings.html#making-changes). If you + server](settings.html#making-changes). If you installed your Zulip server with a version older than 1.6, you'll need to add the line (it won't be there to uncomment). diff --git a/docs/production/multiple-organizations.md b/docs/production/multiple-organizations.md index 2f08dd2701..dccb96253a 100644 --- a/docs/production/multiple-organizations.md +++ b/docs/production/multiple-organizations.md @@ -55,7 +55,7 @@ the homepage for the server is a copy of the Zulip homepage. You'll need to install an SSL certificate valid for all the (sub)domains you're using your Zulip server with. You can get an SSL certificate covering several domains for free by using -[our Certbot wrapper tool](../production/ssl-certificates.html#after-zulip-is-already-installed), +[our Certbot wrapper tool](ssl-certificates.html#after-zulip-is-already-installed), though if you're going to host a large number of organizations, you may want to get a wildcard certificate. You can also get a wildcard certificate for diff --git a/docs/production/password-strength.md b/docs/production/password-strength.md index 78a4f11a18..b5bc844e5f 100644 --- a/docs/production/password-strength.md +++ b/docs/production/password-strength.md @@ -8,7 +8,7 @@ When a user tries to set a password, we use [zxcvbn][zxcvbn] to check that it isn't a weak one. See discussion in [our main docs for server -admins](../production/security-model.html#passwords). This doc explains in more +admins](security-model.html#passwords). This doc explains in more detail how we set the default threshold (`PASSWORD_MIN_GUESSES`) we use. First, read the doc section there. (It's short.) diff --git a/docs/production/postgresql.md b/docs/production/postgresql.md index f42b2439b0..2a8ffeb245 100644 --- a/docs/production/postgresql.md +++ b/docs/production/postgresql.md @@ -10,7 +10,7 @@ included with the base operating system (E.g. PostgreSQL 12 on Ubuntu PostgreSQL releases [upgrade to PostgreSQL 14][upgrade-postgresql], as we may drop support for older PostgreSQL in a future release. -[upgrade-postgresql]: ../production/upgrade-or-modify.html#upgrading-postgresql +[upgrade-postgresql]: upgrade-or-modify.html#upgrading-postgresql #### Remote PostgreSQL database diff --git a/docs/production/requirements.md b/docs/production/requirements.md index 64ecdacf9c..feecff1dc0 100644 --- a/docs/production/requirements.md +++ b/docs/production/requirements.md @@ -16,7 +16,7 @@ To run a Zulip server, you will need: For details on each of these requirements, see below. -[upgrade-from-git]: ../production/upgrade-or-modify.html#upgrading-from-a-git-repository +[upgrade-from-git]: upgrade-or-modify.html#upgrading-from-a-git-repository ## Server @@ -52,7 +52,7 @@ sudo apt update ``` [docker-zulip-homepage]: https://github.com/zulip/docker-zulip#readme -[upgrade-os]: ../production/upgrade-or-modify.html#upgrading-the-operating-system +[upgrade-os]: upgrade-or-modify.html#upgrading-the-operating-system [ubuntu-repositories]: https://help.ubuntu.com/community/Repositories/Ubuntu [enable-universe]: https://help.ubuntu.com/community/Repositories/CommandLine#Adding_the_Universe_and_Multiverse_Repositories @@ -77,13 +77,13 @@ on hardware requirements for larger organizations. #### Network and security specifications - Incoming HTTPS access (usually port 443, though this is - [configurable](../production/deployment.html#using-an-alternate-port)) + [configurable](deployment.html#using-an-alternate-port)) from the networks where your users are (usually, the public Internet). - Incoming port 80 access (optional). Zulip only serves content over HTTPS, and will redirect HTTP requests to HTTPS. - Incoming port 25 if you plan to enable Zulip's [incoming email - integration](../production/email-gateway.md). + integration](email-gateway.md). - Incoming port 4369 should be protected by a firewall to prevent exposing `epmd`, an Erlang service which does not support binding only to localhost. Leaving this exposed will allow unauthenticated @@ -95,7 +95,7 @@ on hardware requirements for larger organizations. [disable those features](https://zulip.com/help/allow-image-link-previews). - Outgoing SMTP access (usually port 587) to your [SMTP - server](../production/email.md) so that Zulip can send emails. + server](email.md) so that Zulip can send emails. - A domain name (e.g. `zulip.example.com`) that your users will use to access the Zulip server. In order to generate valid SSL certificates [with Certbot][doc-certbot], and to enable other @@ -111,8 +111,8 @@ on hardware requirements for larger organizations. Zulip supports using that instead. [ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery -[smokescreen-proxy]: ../production/deployment.html#customizing-the-outgoing-http-proxy -[reverse-proxy]: ../production/deployment.html#putting-the-zulip-application-behind-a-reverse-proxy +[smokescreen-proxy]: deployment.html#customizing-the-outgoing-http-proxy +[reverse-proxy]: deployment.html#putting-the-zulip-application-behind-a-reverse-proxy [email-mirror-code]: https://github.com/zulip/zulip/blob/main/zerver/management/commands/email_mirror.py ## Credentials needed @@ -145,7 +145,7 @@ certificate documentation](ssl-certificates.md). [free outgoing SMTP options and options for prototyping](email.html#free-outgoing-email-services). Once you have met these requirements, see [full instructions for installing -Zulip in production](../production/install.md). +Zulip in production](install.md). [trusty-eol]: https://wiki.ubuntu.com/Releases @@ -167,7 +167,7 @@ server services, Django dominates the resource requirements. One can run every service on its own system (as [docker-zulip](https://github.com/zulip/docker-zulip) does) but for most use cases, there's little scalability benefit to doing so. See -[deployment options](../production/deployment.md) for details on +[deployment options](deployment.md) for details on installing Zulip with a dedicated database server. - **Dedicated database**. For installations with hundreds of daily @@ -240,6 +240,6 @@ For readers interested in technical details around what features impact Zulip's scalability, this [performance and scalability design document](../subsystems/performance.md) may also be of interest. -[s3-uploads]: ../production/upload-backends.html#s3-backend-configuration -[streaming-replication]: ../production/deployment.html#postgresql-warm-standby +[s3-uploads]: upload-backends.html#s3-backend-configuration +[streaming-replication]: deployment.html#postgresql-warm-standby [contact-support]: https://zulip.com/help/contact-support diff --git a/docs/production/security-model.md b/docs/production/security-model.md index 002aa94a36..5595783afc 100644 --- a/docs/production/security-model.md +++ b/docs/production/security-model.md @@ -38,7 +38,7 @@ announcement). - The preferred way to log in to Zulip is using a single sign-on (SSO) solution like Google authentication, LDAP, or similar, but Zulip also supports password authentication. See [the authentication - methods documentation](../production/authentication-methods.md) for + methods documentation](authentication-methods.md) for details on Zulip's available authentication methods. ### Passwords @@ -67,7 +67,7 @@ strength allowed is controlled by two settings in By default, `PASSWORD_MIN_GUESSES` is 10000. This provides significant protection against online attacks, while limiting the burden imposed on users choosing a password. See - [password strength](../production/password-strength.md) for an extended + [password strength](password-strength.md) for an extended discussion on how we chose this value. Estimating the guessability of a password is a complex problem and @@ -272,8 +272,8 @@ strength allowed is controlled by two settings in [go-camo]: https://github.com/cactus/go-camo [ssrf]: https://owasp.org/www-community/attacks/Server_Side_Request_Forgery -[smokescreen-setup]: ../production/deployment.html#customizing-the-outgoing-http-proxy -[proxy.enable_for_camo]: ../production/deployment.html#enable-for-camo +[smokescreen-setup]: deployment.html#customizing-the-outgoing-http-proxy +[proxy.enable_for_camo]: deployment.html#enable-for-camo ## Final notes and security response diff --git a/docs/production/settings.md b/docs/production/settings.md index 2b9320a53d..ab614655d2 100644 --- a/docs/production/settings.md +++ b/docs/production/settings.md @@ -28,7 +28,7 @@ from an old version of Zulip, we recommend [carefully updating your comment documentation for new configuration settings after upgrading to each new major release. -[update-settings-docs]: ../production/upgrade-or-modify.html#updating-settings-py-inline-documentation +[update-settings-docs]: upgrade-or-modify.html#updating-settings-py-inline-documentation [settings-py-template]: https://github.com/zulip/zulip/blob/main/zproject/prod_settings_template.py Since Zulip's settings file is a Python script, there are a number of @@ -61,7 +61,7 @@ If you want an additional or different authentication backend, you will need to uncomment one or more and then do any additional configuration required for that backend as documented in the `settings.py` file. See the -[section on authentication](../production/authentication-methods.md) for more +[section on authentication](authentication-methods.md) for more detail on the available authentication backends and how to configure them. @@ -112,9 +112,9 @@ Some popular settings in `/etc/zulip/settings.py` include: - The Twitter integration, which provides pretty inline previews of tweets. -- The [email gateway](../production/email-gateway.md), which lets +- The [email gateway](email-gateway.md), which lets users send emails into Zulip. -- The [Video call integrations](../production/video-calls.md). +- The [Video call integrations](video-calls.md). ## Zulip announcement list @@ -132,5 +132,5 @@ request; we love even small contributions, and we'd love to make the Zulip documentation cover everything anyone might want to know about running Zulip in production. -Next: [Backups, export and import](../production/export-and-import.md) and -[upgrading](../production/upgrade-or-modify.md) Zulip in production. +Next: [Backups, export and import](export-and-import.md) and +[upgrading](upgrade-or-modify.md) Zulip in production. diff --git a/docs/production/ssl-certificates.md b/docs/production/ssl-certificates.md index 182322309b..3bce35cec4 100644 --- a/docs/production/ssl-certificates.md +++ b/docs/production/ssl-certificates.md @@ -81,7 +81,7 @@ Internet. If you need to configure a multiple domain certificate, you can generate one as described in the section below after installing Zulip. -[doc-install-script]: ../production/install.html#step-2-install-zulip +[doc-install-script]: install.html#step-2-install-zulip ### After Zulip is already installed diff --git a/docs/production/upgrade-or-modify.md b/docs/production/upgrade-or-modify.md index 87aa459ef2..a0d27069e5 100644 --- a/docs/production/upgrade-or-modify.md +++ b/docs/production/upgrade-or-modify.md @@ -60,7 +60,7 @@ involved (these will be documented in the [release notes](../overview/changelog.md), and usually can be avoided with some care). If downtime is problematic for your organization, consider testing the upgrade on a -[backup](../production/export-and-import.html#backups) in advance, +[backup](export-and-import.html#backups) in advance, doing the final upgrade at off hours, or buying a support contract. See the [troubleshooting guide](#troubleshooting-and-rollback) if you @@ -156,13 +156,13 @@ suggest using that updated template to update su zulip -c '/home/zulip/deployments/current/scripts/restart-server' ``` -[backups]: ../production/export-and-import.html#backups +[backups]: export-and-import.html#backups [changelog]: ../overview/changelog.md ## Troubleshooting and rollback See also the general Zulip server [troubleshooting -guide](../production/troubleshooting.md). +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: @@ -800,7 +800,7 @@ upgrading to `main`, make sure you understand: - We do not support downgrading from `main` to earlier versions, so if downtime for your Zulip server is unacceptable, make sure you have a current - [backup](../production/export-and-import.html#backups) in case the + [backup](export-and-import.html#backups) in case the upgrade fails. - Our changelog contains [draft release notes](../overview/changelog.md) available listing major changes diff --git a/docs/subsystems/api-release-checklist.md b/docs/subsystems/api-release-checklist.md index d51e7d46de..d576e176d2 100644 --- a/docs/subsystems/api-release-checklist.md +++ b/docs/subsystems/api-release-checklist.md @@ -50,7 +50,7 @@ checklist of things one must do before making a PyPI release: See [the tag][example-tag] and [the commit][example-commit] for the 0.8.1 release to see an example. -Now it is time to [update the dependencies](../subsystems/dependencies) in the +Now it is time to [update the dependencies](dependencies) in the [Zulip server repository][zulip-repo]: 1. Increment `PROVISION_VERSION` in `version.py`. A minor version bump should suffice in diff --git a/docs/subsystems/caching.md b/docs/subsystems/caching.md index 2afcec0f74..fab3ffb1c6 100644 --- a/docs/subsystems/caching.md +++ b/docs/subsystems/caching.md @@ -256,7 +256,7 @@ avatars, similar details for streams, recent message history, etc. This data is fetched in the `/register` endpoint (or `page_params` for the web app), and kept correct over time. The key to keeping these state up to date is Zulip's -[real-time events system](../subsystems/events-system.md), which +[real-time events system](events-system.md), which allows the server to notify clients whenever state that might be cached by clients is changed. Clients are responsible for handling the events, updating their state, and rerendering any UI components diff --git a/docs/subsystems/client.md b/docs/subsystems/client.md index 742fff4241..ee9cc82eb9 100644 --- a/docs/subsystems/client.md +++ b/docs/subsystems/client.md @@ -13,7 +13,7 @@ of Zulip; it's primarily intended to assist debugging. A `Client` is used to sort messages into client categories such as `ZulipElectron` on the `/stats` page. For more information see, -[Analytics](../subsystems/analytics.md). +[Analytics](analytics.md). ## Integrations diff --git a/docs/subsystems/dependencies.md b/docs/subsystems/dependencies.md index fdd8939718..a63fe29c3b 100644 --- a/docs/subsystems/dependencies.md +++ b/docs/subsystems/dependencies.md @@ -232,7 +232,7 @@ reasoning here. dependencies in the `yarn.lock` file; `yarn install` updates the `yarn.lock` files. - `tools/update-prod-static`. This process is discussed in detail in - the [static asset pipeline](../subsystems/html-css.html#static-asset-pipeline) + the [static asset pipeline](html-css.html#static-asset-pipeline) article, but we don't use the `node_modules` directories directly in production. Instead, static assets are compiled using our static asset pipeline and it is the compiled assets that are served @@ -290,7 +290,7 @@ Zulip uses the [iamcal emoji data package][iamcal] for its emoji data and sprite sheets. We download this dependency using `npm`, and then have a tool, `tools/setup/build_emoji`, which reformats the emoji data into the files under `static/generated/emoji`. Those files are in -turn used by our [Markdown processor](../subsystems/markdown.md) and +turn used by our [Markdown processor](markdown.md) and `tools/update-prod-static` to make Zulip's emoji work in the various environments where they need to be displayed. diff --git a/docs/subsystems/email.md b/docs/subsystems/email.md index 6ff0a82d44..1cdd30f11e 100644 --- a/docs/subsystems/email.md +++ b/docs/subsystems/email.md @@ -44,7 +44,7 @@ Email takes about a quarter second per email to process and send. Generally speaking, if you're sending just one email, doing it in the current process is fine. If you're sending emails in a loop, you probably want to send it from a queue. Documentation on our queueing system is available -[here](../subsystems/queuing.md). +[here](queuing.md). ## Development and testing diff --git a/docs/subsystems/emoji.md b/docs/subsystems/emoji.md index bf71396e82..d15a9c0a1a 100644 --- a/docs/subsystems/emoji.md +++ b/docs/subsystems/emoji.md @@ -64,7 +64,7 @@ The `build_emoji` tool generates the set of files under `static/generated/emoji` is a symlink to that tree; we do this in order to cache old versions to make provisioning and production deployments super fast in the common case that we haven't changed the -emoji tooling). See [our dependencies document](../subsystems/dependencies.md) +emoji tooling). See [our dependencies document](dependencies.md) for more details on this strategy. The emoji tree generated by this process contains several import elements: @@ -80,7 +80,7 @@ The emoji tree generated by this process contains several import elements: - `images/emoji/*.png`: A farm of symlinks from emoji names to the `images/emoji/unicode/` tree. This is used to serve individual emoji images, as well as for the - [backend Markdown processor](../subsystems/markdown.md) to know which emoji + [backend Markdown processor](markdown.md) to know which emoji names exist and what Unicode emoji / images they map to. In this tree, we currently include all of the emoji in `emoji-map.json`; this means that if you send `:angry_face:`, it won't autocomplete, diff --git a/docs/subsystems/events-system.md b/docs/subsystems/events-system.md index 816c2818f6..9574a041e5 100644 --- a/docs/subsystems/events-system.md +++ b/docs/subsystems/events-system.md @@ -162,7 +162,7 @@ its data, clients would recover, just as if they had lost Internet access briefly (there is some DoS risk to manage, though). Note that the garbage-collection system has hooks that are important -for the implementation of [notifications](../subsystems/notifications.md). +for the implementation of [notifications](notifications.md). (The event queue server is designed to save any event queues to disk and reload them when the server is restarted, and catches exceptions @@ -407,7 +407,7 @@ correctly, clients are responsible for discarding events related to messages that the client has not yet fetched. Additionally, see -[the main documentation on sending messages](../subsystems/sending-messages.md). +[the main documentation on sending messages](sending-messages.md). ## Schema changes diff --git a/docs/subsystems/hashchange-system.md b/docs/subsystems/hashchange-system.md index 697829a6b8..4ffa6395f3 100644 --- a/docs/subsystems/hashchange-system.md +++ b/docs/subsystems/hashchange-system.md @@ -121,4 +121,4 @@ box as a draft). [testing-with-puppeteer]: ../testing/testing-with-puppeteer.md [self-server-reloads]: #server-initiated-reloads -[events-system]: ../subsystems/events-system.md +[events-system]: events-system.md diff --git a/docs/subsystems/html-css.md b/docs/subsystems/html-css.md index 9e5e2693f8..295aac3791 100644 --- a/docs/subsystems/html-css.md +++ b/docs/subsystems/html-css.md @@ -145,7 +145,7 @@ developing new features for Zulip that require front-end changes, especially those that involve adding new files. For a more general overview, see the [new feature tutorial](../tutorials/new-feature-tutorial.md). -Our [dependencies documentation](../subsystems/dependencies.md) has useful +Our [dependencies documentation](dependencies.md) has useful relevant background as well. ### Primary build process diff --git a/docs/subsystems/logging.md b/docs/subsystems/logging.md index 6f873d79b8..869530ae55 100644 --- a/docs/subsystems/logging.md +++ b/docs/subsystems/logging.md @@ -167,7 +167,7 @@ and report to the server the following whenever a message is sent: - Whether the message was locally echoed. - If so, whether there was a disparity between the echoed content and the server-rendered content, which can be used for statistics on how - effective our [local echo system](../subsystems/markdown.md) is. + effective our [local echo system](markdown.md) is. The code is all in `zerver/lib/report.py` and `static/js/sent_messages.js`. diff --git a/docs/subsystems/notifications.md b/docs/subsystems/notifications.md index bdc165887b..fcdc1d63ce 100644 --- a/docs/subsystems/notifications.md +++ b/docs/subsystems/notifications.md @@ -3,7 +3,7 @@ This is a design document aiming to provide context for developers working on Zulip's email notifications and mobile push notifications code paths. We recommend first becoming familiar with [sending -messages](../subsystems/sending-messages.md); this document expands on +messages](sending-messages.md); this document expands on the details of the email/mobile push notifications code path. ## Important corner cases @@ -43,7 +43,7 @@ as follows: structure ignores users for whom the message is not notifiable, which is important to avoid this being thousands of `user_ids` for messages to large streams with few currently active users. -- The Tornado [event queue system](../subsystems/events-system.md) +- The Tornado [event queue system](events-system.md) processes that data, as well as data about each user's active event queues, to (1) push an event to each queue needing that message and (2) for notifiable messages, pushing an event onto the @@ -64,7 +64,7 @@ as follows: if a user was present 1 minute before a message was sent, and then closed their laptop, the user will not be in `presence_idle_user_ids` (because it takes a - [few minutes](../subsystems/presence.md) of being idle for Zulip + [few minutes](presence.md) of being idle for Zulip clients to declare to the server that the user is actually idle), and so without an additional mechanism, messages sent shortly after a user leaves would never trigger a notification (!). diff --git a/docs/subsystems/performance.md b/docs/subsystems/performance.md index 032a59ea52..12cfdfd0e1 100644 --- a/docs/subsystems/performance.md +++ b/docs/subsystems/performance.md @@ -38,7 +38,7 @@ of load profiles: example for this, with more than 15K total user accounts, of which only several hundred have logged in during the last few weeks. Zulip has many important optimizations, including [soft - deactivation](../subsystems/sending-messages.html#soft-deactivation) + deactivation](sending-messages.html#soft-deactivation) to ensure idle users have minimal impact on both server-side scalability and request latency. - Fulltime teams, like your typical corporate Zulip installation, @@ -114,7 +114,7 @@ is negligible. ### Tornado Zulip's Tornado-based [real-time push -system](../subsystems/events-system.md), and in particular +system](events-system.md), and in particular `GET /events`, accounts for something like 50% of all HTTP requests to a production Zulip server. Despite `GET /events` being extremely high-volume, the typical request takes 1-3ms to process, and doesn't @@ -149,7 +149,7 @@ thousands of concurrent users. presence information and return the information for all other active users in the organization, account for about 36% of all HTTP requests on production Zulip servers. See -[presence](../subsystems/presence.md) for details on this system and +[presence](presence.md) for details on this system and how it's optimized. For this article, it's important to know that presence is one of the most important scalability concerns for any chat system, because it cannot be cached long, and is structurally a @@ -249,7 +249,7 @@ it does a large number of these requests: zulip.com, this can result in a thundering herd effect for both `/` and `GET /messages`. A great deal of care has been taking in designing this [auto-reload - system](../subsystems/hashchange-system.html#server-initiated-reloads) + system](hashchange-system.html#server-initiated-reloads) to spread most of that herd over several minutes. Typical requests consume 20-100ms to process, much of which is waiting @@ -295,7 +295,7 @@ as it navigates around the app. ### Sending and editing messages -[Sending new messages](../subsystems/sending-messages.md) (including +[Sending new messages](sending-messages.md) (including incoming webhooks) represents less than 0.5% of total request volume. That this number is small should not be surprising even though sending messages is intuitively the main feature of a chat service: a message @@ -303,7 +303,7 @@ sent to 50 users triggers ~50 `GET /events` requests. A typical message-send request takes 20-70ms, with more expensive requests typically resulting from [Markdown -rendering](../subsystems/markdown.md) of more complex syntax. As a +rendering](markdown.md) of more complex syntax. As a result, these requests are not material to Zulip's scalability. Editing messages and adding emoji reactions are very similar to sending them for the purposes of performance and scalability, since @@ -335,7 +335,7 @@ scalability of a Zulip server. The above doesn't cover all of the work that a production Zulip server does; various tasks like sending outgoing emails or recording the data that powers [/stats](https://zulip.com/help/analytics) are run by -[queue processors](../subsystems/queuing.md) and cron jobs, not in +[queue processors](queuing.md) and cron jobs, not in response to incoming HTTP requests. In practice, all of these have been written such that they are immaterial to total load and thus architectural scalability, though we do from time to time need to do @@ -358,7 +358,7 @@ Python/CPU time (being harder to scale horizontally). Most optimizations to make an endpoint cheaper will start with optimizing the database queries and/or employing -[caching](../subsystems/caching.md), and then continue as needed with +[caching](caching.md), and then continue as needed with profiling of the Python code and any memcached queries. For a handful of the critical code paths listed above, we further @@ -367,7 +367,7 @@ for narrow sections; typically this is sufficient to result in the database query time dominating that spent by the Python application server process. -Zulip's [server logs](../subsystems/logging.md) are designed to +Zulip's [server logs](logging.md) are designed to provide insight when a request consumes significant database or memcached resources, which is useful both in development and in production. diff --git a/docs/subsystems/sending-messages.md b/docs/subsystems/sending-messages.md index d85d53c2c8..d26165fb3d 100644 --- a/docs/subsystems/sending-messages.md +++ b/docs/subsystems/sending-messages.md @@ -7,7 +7,7 @@ experience. This document aims to explain conceptually what happens when a message is sent in Zulip, and why that is correct behavior. It assumes the reader is familiar with our -[real-time sync system](../subsystems/events-system.md) for +[real-time sync system](events-system.md) for server-to-client communication and [new application feature tutorial](../tutorials/new-feature-tutorial.md), and we generally don't repeat the content discussed there. @@ -53,13 +53,13 @@ This section details the ways in which it is different: function in `zerver/tornado/event_queue.py`. This custom code has a number of purposes: - Triggering [email and mobile push - notifications](../subsystems/notifications.md) for any users who + notifications](notifications.md) for any users who do not have active clients and have settings of the form "push notifications when offline". In order to avoid doing any real computational work inside the Tornado codebase, this logic aims to just do the check for whether a notification should be generated, and then put an event into an appropriate - [queue](../subsystems/queuing.md) to actually send the message. + [queue](queuing.md) to actually send the message. See `maybe_enqueue_notifications` and `zerver/lib/notification_data.py` for this part of the logic. - Splicing user-dependent data (E.g. `flags` such as when the user @@ -73,7 +73,7 @@ This section details the ways in which it is different: - Following our standard naming convention, input validation is done inside the `check_message` function in `zerver/lib/actions.py`, which is responsible for validating the user can send to the recipient, - [rendering the Markdown](../subsystems/markdown.md), etc. -- + [rendering the Markdown](markdown.md), etc. -- basically everything that can fail due to bad user input. - The core `do_send_messages` function (which handles actually sending the message) in `zerver/lib/actions.py` is one of the most optimized and thus complex parts of @@ -89,7 +89,7 @@ This section details the ways in which it is different: open organizations. - Do all the database queries to fetch relevant data for and then send a `message` event to the - [events system](../subsystems/events-system.md) containing the + [events system](events-system.md) containing the data it will need for the calculations described above. This step adds a lot of complexity, because the events system cannot make queries to the database directly. @@ -115,7 +115,7 @@ browser, and then replace it with data from the server when it changes. Zulip aims for a near-perfect local echo experience, which requires is -why our [Markdown system](../subsystems/markdown.md) requires both +why our [Markdown system](markdown.md) requires both an authoritative (backend) Markdown implementation and a secondary (frontend) Markdown implementation, the latter used only for the local echo feature. Read our Markdown documentation for all the tricky @@ -151,7 +151,7 @@ messages. unique value within that namespace identifying the message. - The `do_send_messages` backend code path includes the `queue_id` and `local_id` in the data it passes to the - [events system](../subsystems/events-system.md). The events + [events system](events-system.md). The events system will extend the `message` event dictionary it delivers to the client containing the `queue_id` with `local_message_id` field, containing the `local_id` that the relevant client used when sending @@ -238,7 +238,7 @@ users. message without including the URL embeds/previews, but it will add a deferred work item into the `embed_links` queue. -- The [queue processor](../subsystems/queuing.md) for the +- The [queue processor](queuing.md) for the `embed_links` queue will fetch the URLs, and then if they return results, rerun the Markdown processor and notify clients of the updated message `rendered_content`. @@ -286,7 +286,7 @@ latency was unacceptable: The server backend was introducing a latency of about 1 second per 2000 users subscribed to receive the message. While these delays may not be immediately obvious to users (Zulip, like many other chat applications, -[local echoes](../subsystems/markdown.md) messages that a user sends +[local echoes](markdown.md) messages that a user sends as soon as the user hits “Send”), latency beyond a second or two significantly impacts the feeling of interactivity in a chat experience (i.e. it feels like everyone takes a long time to reply to @@ -378,7 +378,7 @@ the extra 4500 inactive subscribers didn’t exist. There are a few details that require special care with this system: - [Email and mobile push - notifications](../subsystems/notifications.md). We need to make + notifications](notifications.md). We need to make sure these are still correctly delivered to soft-deactivated users; making this work required careful work for those code paths that assumed a `UserMessage` row would always exist for a message that diff --git a/docs/subsystems/typing-indicators.md b/docs/subsystems/typing-indicators.md index 7692edb070..ef14635dec 100644 --- a/docs/subsystems/typing-indicators.md +++ b/docs/subsystems/typing-indicators.md @@ -69,7 +69,7 @@ how long they pause to think, and how frequently they get interrupted. The server piece of typing notifications is currently pretty straightforward, since we take advantage of Zulip's -[events system](../subsystems/events-system.md). +[events system](events-system.md). We deliberately designed the server piece to be stateless, which minimizes the possibility of backend bugs and gives clients diff --git a/docs/testing/continuous-integration.md b/docs/testing/continuous-integration.md index 199d068bdd..e8ab18cca9 100644 --- a/docs/testing/continuous-integration.md +++ b/docs/testing/continuous-integration.md @@ -64,7 +64,7 @@ depend on the version of the base OS and/or Python. Our code for running the tests in CI lives under `tools/ci`; but that logic is mostly thin wrappers around [Zulip's test -suites](../testing/testing.md) or production installer. +suites](testing.md) or production installer. The `Legacy OS` tests are designed to ensure we give good error messages when trying to upgrade Zulip servers running on very old base diff --git a/docs/testing/linters.md b/docs/testing/linters.md index 98473bd8ea..8a03bbe150 100644 --- a/docs/testing/linters.md +++ b/docs/testing/linters.md @@ -101,7 +101,7 @@ find limitations in either the Zulip home-grown stuff or our third party tools, feedback will be highly appreciated. Finally, one way to clean up your code is to thoroughly exercise it -with tests. The [Zulip test documentation](../testing/testing.md) +with tests. The [Zulip test documentation](testing.md) describes our test system in detail. ## Lint checks @@ -120,7 +120,7 @@ following checks: - Check CSS for parsability and formatting. - Check JavaScript code for addClass calls. - Running `mypy` to check static types in Python code. Our - [documentation on using mypy](../testing/mypy.md) covers mypy in + [documentation on using mypy](mypy.md) covers mypy in more detail. - Running `tsc` to compile TypeScript code. Our [documentation on TypeScript](typescript.md) covers TypeScript in more detail. diff --git a/docs/testing/testing-with-node.md b/docs/testing/testing-with-node.md index 25678a0187..57d06a1ecc 100644 --- a/docs/testing/testing-with-node.md +++ b/docs/testing/testing-with-node.md @@ -2,7 +2,7 @@ Our node-based unit tests system is the preferred way to test JavaScript/TypeScript code in Zulip. We prefer it over the [Puppeteer -black-box whole-app testing](../testing/testing-with-puppeteer.md), +black-box whole-app testing](testing-with-puppeteer.md), system since it is much (>100x) faster and also easier to do correctly than the Puppeteer system. @@ -50,7 +50,7 @@ A good first test to read is ## How the node tests work -Unlike the [Puppeteer unit tests](../testing/testing-with-puppeteer.md), +Unlike the [Puppeteer unit tests](testing-with-puppeteer.md), which use a headless Chromium browser connected to a running Zulip development server, our node unit tests don't have a browser, don't talk to a server, and generally don't use a complete virtual DOM (a diff --git a/docs/testing/testing-with-puppeteer.md b/docs/testing/testing-with-puppeteer.md index 77abd44a36..26f801ccbf 100644 --- a/docs/testing/testing-with-puppeteer.md +++ b/docs/testing/testing-with-puppeteer.md @@ -1,6 +1,6 @@ # Web frontend black-box Puppeteer tests -While our [node test suite](../testing/testing-with-node.md) is the +While our [node test suite](testing-with-node.md) is the preferred way to test most frontend code because they are easy to 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 @@ -64,7 +64,7 @@ familiar with [async/await][learn-async-await]. The following questions are useful when debugging Puppeteer test failures you might see in [continuous -integration](../testing/continuous-integration.md): +integration](continuous-integration.md): - Does the flow being tested work properly in the Zulip browser UI? Test failures can reflect real bugs, and often it's easier and more @@ -159,7 +159,7 @@ notes above: - The test suite uses a smaller set of default user accounts and other data initialized in the database than the normal development environment; specifically, it uses the same setup as the [backend - tests](../testing/testing-with-django.md). To see what differs from + tests](testing-with-django.md). To see what differs from the development environment, check out the conditions on `options["test_suite"]` in `zilencer/management/commands/populate_db.py`. diff --git a/docs/testing/testing.md b/docs/testing/testing.md index 916961a02b..b980256608 100644 --- a/docs/testing/testing.md +++ b/docs/testing/testing.md @@ -8,9 +8,9 @@ similar. This page focused on the mechanics of running automated tests in a [development environment](../development/overview.md); you may also -want to read about our [testing philosophy](../testing/philosophy.md) +want to read about our [testing philosophy](philosophy.md) and [continuous integration -setup](../testing/continuous-integration.md). +setup](continuous-integration.md). Manual testing with a web browser is primarily discussed in the docs on [using the development environment](../development/using.md). @@ -48,11 +48,11 @@ useful options are discussed in each tool's documentation (e.g. Zulip has a handful of major tests suite that every developer will eventually work with, each with its own page detailing how it works: -- [Linters](../testing/linters.md): Our dozen or so linters run in parallel. -- [Django](../testing/testing-with-django.md): Server/backend Python tests. -- [Node](../testing/testing-with-node.md): JavaScript tests for the +- [Linters](linters.md): Our dozen or so linters run in parallel. +- [Django](testing-with-django.md): Server/backend Python tests. +- [Node](testing-with-node.md): JavaScript tests for the frontend run via node.js. -- [Puppeteer](../testing/testing-with-puppeteer.md): End-to-end +- [Puppeteer](testing-with-puppeteer.md): End-to-end UI tests run via a Chromium browser. ## Other test suites @@ -126,7 +126,7 @@ This is easy to do using test fixtures (a fancy word for fixed data used in tests) and the `mock.patch` function to specify what HTTP response should be used by the tests for every outgoing HTTP (or other network) request. Consult -[our guide on mocking](../testing/testing-with-django.html#zulip-mocking-practices) to +[our guide on mocking](testing-with-django.html#zulip-mocking-practices) to learn how to mock network requests easily; there are also a number of examples throughout the codebase. diff --git a/docs/testing/typescript.md b/docs/testing/typescript.md index 5b30a0d1e8..b2fab274dc 100644 --- a/docs/testing/typescript.md +++ b/docs/testing/typescript.md @@ -4,7 +4,7 @@ Zulip is early in the process of migrating our codebase to use [TypeScript](https://www.typescriptlang.org/), the leading static type system for JavaScript. It works as an extension of the ES6 JavaScript standard, and provides similar benefits to our use of -[the mypy static type system for Python](../testing/mypy.md). +[the mypy static type system for Python](mypy.md). We expect to eventually migrate the entire JavaScript codebase to TypeScript, though our current focus is on getting the tooling and diff --git a/docs/translating/internationalization.md b/docs/translating/internationalization.md index 011d7bd8b7..d9ee9eae1a 100644 --- a/docs/translating/internationalization.md +++ b/docs/translating/internationalization.md @@ -26,7 +26,7 @@ principles are important in how we think about internationalization: element needs to be built in a way that supports i18n. - This is more about string consistency in general, but we have a "Sentence case" [capitalization - policy](../translating/translating.html#capitalization) that we enforce using linters + policy](translating.html#capitalization) that we enforce using linters that check all strings tagged for translation in Zulip. This article aims to provide a brief introduction. We recommend the @@ -108,7 +108,7 @@ The end-to-end tooling process for translations in Zulip is as follows. Transifex API tool, `tx pull`, internally). If you're interested, you may also want to check out the [translators' -workflow](../translating/translating.html#translators-workflow), just so you have a +workflow](translating.html#translators-workflow), just so you have a sense of how everything fits together. ## Translation resource files diff --git a/docs/translating/translating.md b/docs/translating/translating.md index 3686582b12..9332c25c1f 100644 --- a/docs/translating/translating.md +++ b/docs/translating/translating.md @@ -13,7 +13,7 @@ greatly appreciated! If you are interested in knowing about the technical end-to-end tooling and processes for tagging strings for translation and syncing translations in Zulip, read about [Internationalization for -Developers](../translating/internationalization.md). +Developers](internationalization.md). ## Translators' workflow @@ -115,7 +115,7 @@ can usually just deploy the latest translations there. - First, download the updated resource files from Transifex using the `tools/i18n/sync-translations` command (it will require some [initial - setup](../translating/internationalization.html#transifex-cli-setup)). This + setup](internationalization.html#transifex-cli-setup)). This command will download the resource files from Transifex and replace your local resource files with them, and then compile them. You can now test your translation work in the Zulip UI. diff --git a/docs/tutorials/writing-views.md b/docs/tutorials/writing-views.md index b066579391..1a919bb797 100644 --- a/docs/tutorials/writing-views.md +++ b/docs/tutorials/writing-views.md @@ -3,14 +3,14 @@ ## What this covers This page documents how views work in Zulip. You may want to read the -[new feature tutorial](../tutorials/new-feature-tutorial.md) +[new feature tutorial](new-feature-tutorial.md) and treat this as a reference. If you have experience with Django, much of this will be familiar, but you may want to read about how REST requests are dispatched, and how request authentication works. -This document supplements the [new feature tutorial](../tutorials/new-feature-tutorial.md) +This document supplements the [new feature tutorial](new-feature-tutorial.md) and the [testing](../testing/testing.md) documentation.