docs: Extract a Writing Documentation top-level section.

This should make this easier to find, and also makes "Subsystems" a
bit smaller of a catch-all.
This commit is contained in:
Tim Abbott
2019-05-29 15:39:50 -07:00
parent 1a68ef2951
commit fa37c5cee1
14 changed files with 20 additions and 12 deletions

View File

@@ -0,0 +1,232 @@
# Documenting an integration
Every Zulip integration must be documented in
`zerver/webhooks/mywebhook/doc.md` (or
`templates/zerver/integrations/<integration_name>.md`, for non-webhook
integrations).
Usually, this involves a few steps:
* Add text explaining all of the steps required to setup the
integration, including what URLs to use, etc. See
[Writing guidelines](#writing-guidelines) for detailed writing guidelines.
Zulip's pre-defined Markdown macros can be used for some of these steps.
See [Markdown macros](#markdown-macros) for further details.
* Make sure you've added your integration to
`zerver/lib/integrations.py`; this results in your integration
appearing on the `/integrations` page.
* You'll need to add a SVG graphic
of your integration's logo under the
`static/images/integrations/logos/<name>.svg`, where `<name>` is the
name of the integration, all in lower case; you can usually find them in the
product branding or press page. Make sure to optimize the SVG graphic by
running `svgo -f path-to-file`.
If you cannot find a SVG graphic of the logo, please find and include a PNG
image of the logo instead.
* Finally, generate a message sent by the integration and take a
screenshot of the message to provide an example message in the
documentation. If your new integration is an incoming webhook
integration, you can generate such a message from your test
fixtures using `send_webhook_fixture_message`:
```
./manage.py send_webhook_fixture_message \
--fixture=zerver/webhooks/pingdom/fixtures/imap_down_to_up.json \
'--url=/api/v1/external/pingdom?stream=stream_name&api_key=api_key'
```
When generating the screenshot of a sample message, give your test
bot a nice name like "GitHub Bot", use the project's logo as the
bot's avatar, and take the screenshot showing the stream/topic bar
for the message, not just the message body.
## Markdown macros
**Macros** are elements in the format of `{!macro.md!}` that insert common
phrases and steps at the location of the macros. Macros help eliminate
repeated content in our documentation.
The source for macros is the Markdown files under
`templates/zerver/help/include` in the
[main Zulip server repository](https://github.com/zulip/zulip). If you find
multiple instances of particular content in the documentation, you can
always create a new macro by adding a new file to that folder.
Here are a few common macros used to document Zulip's integrations:
* `{!create-stream.md!}` macro - Recommends that users create a dedicated
stream for a given integration. Usually the first step in setting up an
integration or incoming webhook. For an example rendering, see **Step 1** of
[the docs for Zulip's GitHub integration][GitHub].
* `{!create-bot-construct-url.md!}` macro - Instructs users to create a bot
for a given integration and construct a webhook URL using the bot API key
and stream name. The URL is generated automatically for every incoming webhook
by using attributes in the [WebhookIntegration][1] class.
This macro is usually used right after `{!create-stream!}`. For an example
rendering, see **Step 2** of [the docs for Zulip's GitHub integration][GitHub].
**Note:** If special configuration is
required to set up the URL and you can't use this macro, be sure to use the
`{{ api_url }}` template variable, so that your integration
documentation will provide the correct URL for whatever server it is
deployed on. If special configuration is required to set the `SITE`
variable, you should document that too.
* `{!append-stream-name.md!}` macro - Recommends appending `&stream=stream_name`
to a URL in cases where supplying a stream name in the URL is optional.
Supplying a stream name is optional for most Zulip integrations. If you use
`{!create-bot-construct-url.md!}`, this macro need not be used.
* `{!append-topic.md!}` macro - Recommends appending `&topic=my_topic` to a URL
to supply a custom topic for webhook notification messages. Supplying a custom
topic is optional for most Zulip integrations. If you use
`{!create-bot-construct-url.md!}`, this macro need not be used.
* `{!congrats.md!}` macro - Inserts congratulatory lines signifying the
successful setup of a given integration. This macro is usually used at
the end of the documentation, right before the sample message screenshot.
For an example rendering, see the end of
[the docs for Zulip's GitHub integration][GitHub].
* `{!download-python-bindings.md!}` macro - Links to Zulip's
[API page](https://zulipchat.com/api/) to download and install Zulip's
API bindings. This macro is usually used in non-webhook integration docs under
`templates/zerver/integrations/<integration_name>.md`. For an example
rendering, see **Step 2** of
[the docs for Zulip's Codebase integration][codebase].
* `{!change-zulip-config-file.md!}` macro - Instructs users to create a bot and
specify said bot's credentials in the config file for a given non-webhook
integration. This macro is usually used in non-webhook integration docs under
`templates/zerver/integrations/<integration_name>.md`. For an example
rendering, see **Step 4** of
[the docs for Zulip's Codebase integration][codebase].
* `{!git-append-branches.md!}` and `{!git-webhook-url-with-branches.md!}` -
These two macros explain how to specify a list of branches in the webhook URL
to filter notifications in our Git-related webhooks. For an example rendering,
see the last paragraph of **Step 2** in
[the docs for Zulip's GitHub integration][GitHub].
* `{!webhook-url.md!}` - Used internally by `{!create-bot-construct-url.md!}`
to generate the webhook URL.
* `{!zulip-config.md!}` - Used internally by `{!change-zulip-config-file.md!}`
to specify the lines in the config file for a non-webhook integration.
* `{!webhook-url-with-bot-email.md!}` - Used in certain non-webhook integrations
to generate URLs of the form:
```
https://bot_email:bot_api_key@yourZulipDomain.zulipchat.com/api/v1/external/beanstalk
```
For an example rendering, see
[Zulip's Beanstalk integration](https://zulipchat.com/integrations/doc/beanstalk).
[GitHub]: https://zulipchat.com/integrations/doc/github
[codebase]: https://zulipchat.com/integrations/doc/codebase
[beanstalk]: https://zulipchat.com/integrations/doc/beanstalk
[1]: https://github.com/zulip/zulip/blob/708f3a4bb19c8e823c9ea1e577d360ac4229b199/zerver/lib/integrations.py#L78
## Writing guidelines
For the vast majority of integrations, you should just copy the docs for a
similar integration and edit it. [Basecamp][basecamp] is a good one to copy.
[basecamp]: https://zulipchat.com/integrations/doc/basecamp
### General writing guidelines
At at high level, the goals are for the instructions to feel simple, be easy to
follow, and be easy to maintain. Easier said than done, but here are a few
concrete guidelines.
##### Feel simple
- Use simple language.
- Use the imperative tense.
- Only describe things as much as necessary. For example: "Select **Project settings**."
is better than "Select **Project settings** from the dropdown."
- Cut unnecessary words. For example, do not start steps with transition words
like "Next", "First", "Now", etc. Each step should be structurally
independent.
##### Be easy to follow
- Actions should appear in order, including implicit ones. So "Under
**Webhooks**, click **Add Webhook**." not "Click **Add Webhook** in the
**Webhooks** section." "Under **Webhooks**" is an action, since its basically
the same as "Find the Webhooks section".
- UI elements in third-party websites should be **bolded**.
- Trailing punctuation can be stripped from bolded elements. For example,
"**Enable this checkbox**" instead of "**Enable this checkbox?**".
Starting punctuation such as the "**+**" in "**+ New Notification**" should
be preserved.
- You can use a screenshot if a step is particularly complicated
(see [Screenshots](#screenshots) below).
##### Be easy to maintain
- Follow the organization and wording of existing docs as much as possible.
### Guidelines for specific steps
Most doc files should start with a generic sentence about the
integration, for example, "Get `webhook name` notifications in Zulip!"
A typical doc will then have the following steps.
##### "Create the stream" step
- Use the `create-stream` macro. This step should be omitted if the
integration only supports notifications via PMs.
##### "Create the bot" step
- Typically, use the `create-bot-construct-url` macro.
- [Existing macros](#markdown-macros) should be used for this if they exist, but if the macro
defaults dont work, it may make sense to write something custom for the
integration in question. This step is mandatory for all integrations.
##### "Navigate to this screen" step
- In general, this should be one step, even if it takes multiple clicks.
- Begin by mentioning the third-party service being documented with language
such as "Go to your Taiga project", "Go to your GitHub repository",
"On your X project", etc. Assume the user is already logged in to their
account.
- If a UI element is difficult to spot, you can use additional cues like
"Click on **Settings** in the top-right corner" or "On the left, click
**Webhooks**.". Only do this if the element is actually difficult to spot.
- If this step includes more than 5 sentences, it may need to be split up
into multiple steps.
##### "Fill out form and save" step
- Filling out a form and clicking **Save** should generally be one step, even if
there are multiple fields to fill out.
- Its fine to say things like "Follow the on-screen instructions to create an
app" if they have a sequence of steps they guide you through that are pretty
clear.
Lastly, end with the `congrats.md` macro and a screenshot of a sample message
within Zulip.
### Screenshots
Screenshots are hard to maintain, so we generally err on the side of not
including screenshots. That being said, screenshots may be used to aid the
process if the third-party UI is confusing or a specific UI element is hard
to find. A few things to keep in mind:
- Screenshots should be small and should mainly include the third-party UI that
the text is referring to that is difficult to locate.
- Screenshots should never include the entirety of a third-party websites page.
- Each screenshot should come after the step that refers to it.

View File

@@ -0,0 +1,192 @@
# OpenAPI REST API documentation
The [OpenAPI](http://swagger.io/specification/) (formerly known as
Swagger) specification is a standardized way to describe how an API
functions. This description then can then be used by any tool that
supports the standard.
Zulip uses the Swagger spec to generate an API reference from the
`zulip.yaml` file. This page is a basic introduction to the format of
this file and how to add content to it.
In a Swagger file, every configuration section is an object. Objects
may contain other objects, or reference objects defined
elsewhere. Larger API specifications may be split into multiple
files. There are more types of objects than mentioned here, you can
find the complete details at
[Swagger/OpenAPI specification page](http://swagger.io/specification).
This library isn't in production use yet, but it is our current plan
for how Zulip's API documentation will work.
## Working with the `zulip.yaml` file
A Swagger specification file has three general parts: information and
configuration, endpoint definitions, and object schemas referenced by
other objects (as an alternative to defining everything inline.)
References can either specify an individual object, using `$ref:`, or
compose a larger definition from individual objects with `allOf:`
(which may itself contain a `$ref`.)
### Configuration
These objects, at the top of `zulip.yaml`, identify the API, define
the backend host for the working examples, list supported schemes and
types of authentication, and configure other settings. Once defined,
information in this section rarely changes.
For example, the `swagger` and `info` objects look like this:
```
# Basic Swagger UI info
swagger: '2.0'
info:
version: '1.0.0'
title: Zulip REST API
description: Powerful open source group chat
contact:
url: https://zulip.org/
license:
name: Apache 2.0
url: https://www.apache.org/licenses/LICENSE-2.0.html
```
### Endpoint definitions
The [Paths Object](http://swagger.io/specification/#pathsObject)
contains
[Path Item Objects](http://swagger.io/specification/#pathItemObject)
for each endpoint. It describes in detail the methods and parameters
the endpoint accepts and responses it returns.
There is one Path Item Object for each supported method, containing a
[Parameters Definition Object](http://swagger.io/specification/#parametersDefinitionObject)
describing the required and optional inputs. A
[Response Object](http://swagger.io/specification/#responseObject)
similarly specifies the content of the response. They may reference
schemas from a global Definitions Object (see [Schemas](#schemas),
below.)
Example:
The `/users/{user}/presence` endpoint (defined in a
[Path Item Object](http://swagger.io/specification/#pathItemObject))
expects a GET request with one
[parameter](http://swagger.io/specification/#parameterObject), HTTP
Basic authentication, and returns a JSON response containing `msg`,
`result`, and `presence` values.
```
/users/{user}/presence:
get:
description: Get presence data for another user.
operationId: getPresence
parameters:
- name: user
in: path
description: Enter email address
required: true
type: string
security:
- basicAuth: []
responses:
'200':
description: The response from a successful call
schema:
type: object
required:
- msg
- result
- presence
properties:
msg:
type: string
result:
type: string
presence:
type: array
```
### Schemas
The
[Definitions Object](http://swagger.io/specification/#definitionsObject)
contains schemas referenced by other objects. For example,
`MessageResponse`, the response from the `/messages` endpoint,
contains three required parameters. Two are strings, and one is an
integer.
```
MessageResponse:
type: object
required:
- msg
- result
- id
properties:
msg:
type: string
result:
type: string
id:
type: integer
format: int64
```
You can find more examples, including GET requests and nested objects, in
`/static/yaml/zulip.yaml`.
## Zulip Swagger YAML style:
We're collecting decisions we've made on how our Swagger YAML files
should be organized here:
* Use shared definitions and YAML anchors to avoid duplicating content
where possible.
## Tips for working with YAML:
You can edit YAML files in any text editor. Indentation defines
blocks, so whitespace is important (as it is in Python.) TAB
characters are not permitted. If your editor has an option to replace
tabs with spaces, this is helpful.
You can also use the
[Swagger Editor](http://swagger.io/swagger-editor), which validates
YAML and understands the Swagger specification. Download and run it
locally, or use the online version. If you aren't using a YAML-aware
editor, make small changes and check your additions often.
Note: if you are working with
[Swagger UI](http://swagger.io/swagger-ui/) in a local development
environment, it uses an online validator that must be able to access
your file. You may see a red "ERROR" button at the bottom of your API
docs page instead of the green "VALID" one even if your file is
correct.
### Formatting help:
* Comments begin with a # character.
* Descriptions do not need to be in quotes, and may use common
Markdown format options like inline code \` (backtick) and `#`
headings.
* A single `|` (pipe) character begins a multi-line description on the
next line. Single spaced lines (one newline at the end of each) are
joined. Use an extra blank line for a paragraph break.
### Examples:
```
Description: This is a single line description.
```
```
Description: |
This description has multiple lines.
Sometimes descriptions can go on for
several sentences.
A description might have multiple paragraphs
as well.
```

View File

@@ -0,0 +1,139 @@
# Documentation systems
Zulip has three major documentation systems:
* Developer and sysadmin documentation: Documentation for people
actually interacting with the Zulip codebase (either by developing
it or installing it), and written in Markdown.
* Core website documentation: Complete webpages for complex topics,
written in HTML, JavaScript, and CSS (using the Django templating
system). These roughly correspond to the documentation someone
might look at when deciding whether to use Zulip. We don't expect
to ever have more than about 10 pages written using this system.
* User-facing documentation: Our scalable system for documenting
Zulip's huge collection of specific features without a lot of
overhead or duplicated code/syntax, written in Markdown. We have
several hundred pages written using this system. There are 3
branches of this documentation: user documentation (with a target
audience of individual Zulip users), integrations documentation
(with an audience of IT folks setting up integrations), and API
documentaiton (with an audience of developers writing code to extend
Zulip).
These three systems are documented in detail.
## Developer and sysadmin documentation
What you are reading right now is part of the collection of
documentation targeted at developers and people running their own
Zulip servers. These docs are written in
[Commonmark Markdown](http://commonmark.org/) with a small bit of rST.
We've chosen Markdown because it is
[easy to write](http://commonmark.org/help). The source for Zulip's
developer documentation is at `docs/` in the Zulip git repository, and
they are served in production at
[zulip.readthedocs.io](https://zulip.readthedocs.io/en/latest/).
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:
```
./tools/build-docs
```
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
the root of your Zulip checkout).
If you are adding a new page to the table of contents, you will want
to modify `docs/index.rst` and run `make clean` before `make html`, so
that other docs besides your new one also get the new entry in the
table of contents.
You can also usually test your changes by pushing a branch to GitHub
and looking at the content on the GitHub web UI, since GitHub renders
Markdown, though that won't be as faithful as the `make html`
approach.
When editing dependencies for the Zulip documentation, you should edit
`requirements/docs.in` and then run `tools/update-locked-requirements`
which updates docs.txt file (which is used by ReadTheDocs to build the
Zulip developer documentation, without installing all of Zulip's
dependencies).
## Core website documentation
Zulip has around 10 HTML documentation pages under `templates/zerver`
for specific major topics, like the features list, client apps,
integrations, hotkeys, API bindings, etc. These documents often have
somewhat complex HTML and JavaScript, without a great deal of common
pattern between them other than inheriting from the `portico.html`
template. We generally avoid adding new pages to this collection
unless there's a good reason, but we don't intend to migrate them,
either, since this system gives us the flexibility to express these
important elements of the product clearly.
## User facing documentation
All of these systems use a common Markdown-based framework with
various extensions for macros and variable interpolation,
(`render_markdown_path` in the code), designed to make it convenient
to do the things one does a lot in each type of documentation.
### General user documentation
To learn more about Zulip's general user documentation,
[visit it on zulipchat.com](https://zulipchat.com/help/) or
[read our guide on writing user documentation](user.html).
### Integrations documentation
To learn more about Zulip's integrations documentation,
[visit it on zulipchat.com](https://zulipchat.com/integrations/) or
[read our guide on writing user documentation](integrations.html).
### API documentation
To learn more about Zulip's API documentation,
[visit it on zulipchat.com](https://zulipchat.com/api/) or
[read our tutorial on writing user documentation](../tutorials/documenting-api-endpoints.html).
## Automated testing
Zulip has several automated test suites that we run in CI and
recommend running locally when making significant edits:
* `tools/lint` catches a number of common mistakes, and we highly
recommend
[using our linter pre-commit hook](../git/zulip-tools.html#set-up-git-repo-script).
See the [main linter doc](../testing/linters.html) for more details.
* The ReadTheDocs docs are built and the links tested by
`tools/test-documentation`, which runs `build-docs` and then checks
all the links.
There's an exclude list for the link testing at this horrible path:
`tools/documentation_crawler/documentation_crawler/spiders/common/spiders.py`,
which is relevant for flaky links.
* The API docs are tested by `tools/test-api`, which does some basic
payload verification. Note that this test does not check for broken
links (those are checked by `test-help-documentation`).
* `tools/test-help-documentation` checks `/help/`, `/api/`,
`/integrations/`, and the Core website ("portico") documentation for
broken links. Note that the "portico" documentation check has a
manually maintained whitelist of pages, so if you add a new page to
this site, you will need to edit `PorticoDocumentationSpider` to add it.
* `tools/test-backend test_docs.py` tests various internal details of
the variable substitution logic, as well as rendering. It's
essential when editing the documentation framework, but not
something you'll usually need to interact with when editing
documentation.

216
docs/documentation/user.md Normal file
View File

@@ -0,0 +1,216 @@
# User documentation
Our goal is for Zulip to have complete, high-quality
documentation about Zulip's features and how to perform certain tasks, such
as setting up an organization.
There are two types of documents: articles about specific features, and a
handful of longer guides.
The feature articles serve a few different purposes:
* Feature discovery, for someone browsing the `/help` page, and looking at
the set of titles.
* Public documentation of our featureset, for someone googling "can zulip do .."
* Canned responses to support questions; if someone emails a zulip admin
asking "how do I change my name", they can reply with a link to the doc.
* Feature explanations for new Zulip users and admins, especially for
organization settings.
This system is designed to make writing and maintaining such documentation
highly efficient. We link to the docs extensively from the landing pages and
in-product, so it's important to keep the docs up to date.
## Editing and testing
The user documentation is available under `/help/` on any Zulip server;
(e.g. <https://chat.zulip.org/help/> or `http://localhost:9991/help/` in
the Zulip development environment). The user 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
environment.
The source for this user documentation is the Markdown files under
`templates/zerver/help/` in the
[main Zulip server repository](https://github.com/zulip/zulip). The file
`foo.md` is automatically rendered by the `render_markdown_path` function in
`zerver/templatetags/app_filters.py` when the user accesses a URL of the
form `/help/foo`; with special cases for `/help/` going to `index.md` and
`/help/unknown_article` going to `missing.md` (with a 404 response). Images
are usually linked from `static/images/help/`.
This means that you can contribute to the Zulip user documentation by just
adding to or editing the collection of markdown files under
`templates/zerver/help`. If you have the Zulip development environment
setup, you simply need to reload your browser on
`http://localhost:9991/help/foo` to see the latest version of `foo.md`
rendered.
## Writing documentation
Writing documentation is a different form of writing than most people have
experience with.
Tips for adding a new article:
* Find an existing article in the same section of the help documentation,
and copy the format, wording, style, etc as closely as you can.
* Fewer words is better than more. Many Zulip users have English as a second
language.
* Try to put yourself in the shoes of a new Zulip user. What would you want
to know?
* The goal of user-facing documentation is not to be comprehensive. The goal
is to give the right bits of information for the intended audience.
### 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,
**Change password** button, **Email** field). No quotation marks should be
used.
Keep in mind that the UI may change — dont describe it in more detail than
is needed. **Never identify or refer to a button by its color.**
### Voice
Do not use `we` to refer to Zulip or its creators; e.g. "Zulip also
allows .." rather than "we also allow ..". `You` is ok and used liberally.
## Features
Zulip's Markdown processor allows you to include several special features in
your documentation to help improve its readibility:
* Since raw HTML is supported in Markdown, you can include arbitrary
HTML/CSS in your documentation as needed.
* Code blocks allow you to highlight syntax, similar to Zulip's own markdown.
* Anchor tags can be used to link to headers in other documents.
* [Images](#images) of Zulip UI can be added to documentation.
* Inline [icons](#icons) used to refer to features in the Zulip UI.
* You can utilize [macros](#macros) to limit repeated content in the
documentation.
* You can create special highlight warning blocks using
[tips and warnings](#tips-and-warnings).
### Images
Images and screenshots should be included in user documentation only
if it 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
only thing on the page, but images can be included to show the end
result of an interaction with the UI.
Using too many screenshots creates maintainability problems (we have
to update them every time the UI is changed) and also can make the
instructions for something simple look long and complicated.
When taking screenshots, the image should never include the whole
Zulip browser window in a screenshot; instead, it should only show
relevant parts of the app. In addition, the screenshot should always
come *after* the text that describes it, never before.
Images are often a part of a numbered step and must be indented four spaces
to be formatted correctly.
### Icons
You can refer to features in the Zulip UI by referencing their names
and their [FontAwesome](https://fontawesome.com/v4.7.0/) (version 4.7.0) text
icons within parentheses. **Note:** We have completed migrating away from older
base class `icon-vector` and have dropped support for it. We now only support
icons from [FontAwesome](https://fontawesome.com/v4.7.0/) (version 4.7.0) which
make use of `fa` as a base class.
* cog (<i class="fa fa-cog"></i>) icon — `cog (<i
class="fa fa-cog"></i>) icon`
* down chevron (<i class="fa fa-chevron-down"></i>) icon —
`down chevron (<i class="fa fa-chevron-down"></i>) icon`
* eye (<i class="fa fa-eye"></i>) icon — `eye (<i
class="fa fa-eye"></i>) icon`
* file (<i class="fa fa-file-text-o"></i>) icon — `file (<i
class="fa fa-file-text-o"></i>) icon`
* filled star (<i class="fa fa-star"></i>) icon —
`filled star (<i class="fa fa-star"></i>) icon`
* formatting (<i class="fa fa-font"></i>) icon —
`formatting (<i class="fa fa-font"></i>) icon`
* menu (<i class="fa fa-bars"></i>) icon — `menu (<i
class="fa fa-bars"></i>) icon`
* overflow ( <i class="fa fa-ellipsis-v"></i> ) icon —
`overflow ( <i class="fa fa-ellipsis-v"></i> ) icon`
* paperclip (<i class="fa fa-paperclip"></i>) icon —
`paperclip (<i class="fa fa-paperclip"></i>) icon`
* pencil (<i class="fa fa-pencil"></i>) icon —
`pencil (<i class="fa fa-pencil"></i>) icon`
* pencil and paper (<i class="fa fa-pencil-square-o"></i>) icon —
`pencil and paper (<i class="fa fa-pencil-square-o"></i>) icon`
* plus (<i class="fa fa-plus"></i>) icon —
`plus (<i class="fa fa-plus"></i>) icon`
* smiley face (<i class="fa fa-smile-o"></i>) icon —
`smiley face (<i class="fa fa-smile-o"></i>) icon`
* star (<i class="fa fa-star-o"></i>) icon —
`star (<i class="fa fa-star-o"></i>) icon`
* trash (<i class="fa fa-trash-o"></i>) icon —
`trash (<i class="fa fa-trash-o"></i>) icon`
* video-camera (<i class="fa fa-video-camera"></i>) icon —
`video-camera (<i class="fa fa-video-camera"></i>) icon`
* x (<i class="fa fa-times"></i>) icon —
`x (<i class="fa fa-times"></i>) icon`
### Macros
**Macros** are elements in the format of `{!macro.md!}` that insert common
phrases and steps at the location of the macros. Macros help eliminate
repeated content in our documentation.
The source for macros is the Markdown files under
`templates/zerver/help/include` in the
[main Zulip server repository](https://github.com/zulip/zulip).
* **Administrator only feature** `{!admin-only.md!}`: Notes that the feature
is only available to organization administrators.
* **Message actions** `{!message-actions.md!}`: First step to navigating to
the on-hover message actions.
* **Message actions menu** `{!message-actions-menu.md!}`: Navigate to the
message actions menu.
* **Save changes** `{!save-changes.md!}`: Save changes after modifying
organization settings.
* **Stream actions** `{!stream-actions.md!}`: Navigate to the stream actions
menu from the left sidebar.
* **Start composing** `{!start-composing.md!}`: Open the compose box.
### Tips and warnings
A **tip** is any suggestion for the user that is not part of the main set of
instructions. For instance, it may address a common problem users may
encounter while following the instructions, or point to an option for power
users.
```
!!! tip ""
If you've forgotten your password, see the
[Change your password](/help/change-your-password) page for
instructions on how to reset it.
```
A **warning** is a note on what happens when there is some kind of problem.
Tips are more common than warnings.
```
!!! warn ""
**Note:** If you attempt to input a nonexistent stream name, an error
message will appear.
```
All tips/warnings should appear inside tip/warning blocks. There should be
only one tip/warning inside each block.They usually be formatted as a
continuation of a numbered step.