Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# How to update Apostrophe CMS documentation


This project contains [the documentation site](https://docs.apostrophecms.org/)
This project contains [the documentation site](https://apostrophecms.com/docs)
for [ApostropheCMS](https://apostrophecms.com).

You don't need to read this page to read the documentation! This page
Expand Down
15 changes: 8 additions & 7 deletions deploy
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

if [ -z "$ENV" ]; then
echo "💁‍♀️ Usage: ENV=staging npm run deploy"
echo "(or as appropriate)"
echo "(or prod, NOT production, must match act)"
echo
rm -rf ./dist
exit 1
Expand All @@ -11,17 +11,18 @@ fi
if [ $ENV == "staging" ]
then
FOLDER=docs-staging
elif [ $ENV == "production" ]
then
FOLDER=docs
# Support our typical syntax
BRANCH=develop
elif [ $ENV == "prod" ]
then
FOLDER=docs
BRANCH=main
else
echo "🤷‍♀️ Target unknown"
exit 1
fi

rsync -av --delete --exclude '.git' --exclude '**/node_modules' ./docs/.vitepress/dist [email protected]:/opt/static/$FOLDER &&
echo "Synced up to $ENV"
npm run build &&

(tar -C ./docs/.vitepress/dist -zcf - . | ssh [email protected] "cat > /opt/static/static/$ENV-docs.tar.gz") &&

echo "Now run: CLOUD=website-$ENV act redeploy"
4 changes: 2 additions & 2 deletions docs/.vitepress/components/AposAISearchResults.vue
Original file line number Diff line number Diff line change
Expand Up @@ -325,8 +325,8 @@ onMounted(() => {
}

const websocketURLs = {
'docs-staging.apos.dev': 'https://chatbot-staging.apos.dev',
'docs.apostrophecms.org': 'https://chatbot.apos.dev'
'staging.apostrophecms.com': 'https://chatbot-staging.apos.dev',
'apostrophecms.com': 'https://chatbot.apos.dev'
};

// Get the current hostname
Expand Down
2 changes: 1 addition & 1 deletion docs/.vitepress/components/AposRefExtends.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<p>
<strong>Extends:</strong> <code>{{ module }}</code> <a href="/guide/modules.html#module-inheritance">ℹ️</a>
<strong>Extends:</strong> <code>{{ module }}</code> <a href="/docs/guide/modules.html#module-inheritance">ℹ️</a>
</p>
</template>

Expand Down
45 changes: 32 additions & 13 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,24 @@ const umamiWebsiteId = process.env.UMAMI_WEBSITE_ID || 'testing';
const DEBUG_TRACKING = process.env.DEBUG_TRACKING || 'false';
const ENV = process.env.ENV || 'production';

// package.json sets ENV to one of these, otherwise we're doing local testing and
// a domain + port in the URL will just be a pain in the butt -Tom
const hostnames = {
staging: 'https://staging.apostrophecms.com',
production: 'https://apostrophecms.com',
dev: ''
};

const base = '/docs/';

const hostname = hostnames[process.env.ENV || 'dev' ];

export default defineConfig({
title: 'ApostropheCMS',
description: 'Documentation for ApostropheCMS',

ignoreDeadLinks: 'localhostLinks',
base,
vite: {
resolve: {
alias: [
Expand Down Expand Up @@ -74,7 +87,7 @@ export default defineConfig({
rel: 'icon',
type: 'image/png',
sizes: '32x32',
href: '/images/favicon/favicon-32.png'
href: '/docs/images/favicon/favicon-32.png'
}
],
[
Expand All @@ -83,7 +96,7 @@ export default defineConfig({
rel: 'icon',
type: 'image/png',
sizes: '128x128',
href: '/images/favicon/favicon-128.png'
href: '/docs/images/favicon/favicon-128.png'
}
],
[
Expand All @@ -92,7 +105,7 @@ export default defineConfig({
rel: 'icon',
type: 'image/png',
sizes: '192x192',
href: '/images/favicon/favicon-192.png'
href: '/docs/images/favicon/favicon-192.png'
}
],
[
Expand All @@ -101,7 +114,7 @@ export default defineConfig({
rel: 'shortcut icon',
type: 'image/png',
sizes: '196x196',
href: '/images/favicon/favicon-196.png'
href: '/docs/images/favicon/favicon-196.png'
}
],
[
Expand All @@ -110,7 +123,7 @@ export default defineConfig({
rel: 'apple-touch-icon',
type: 'image/png',
sizes: '152x152',
href: '/images/favicon/favicon-152.png'
href: '/docs/images/favicon/favicon-152.png'
}
],
[
Expand All @@ -119,7 +132,7 @@ export default defineConfig({
rel: 'apple-touch-icon',
type: 'image/png',
sizes: '167x167',
href: '/images/favicon/favicon-167.png'
href: '/docs/images/favicon/favicon-167.png'
}
],
[
Expand All @@ -128,14 +141,20 @@ export default defineConfig({
rel: 'apple-touch-icon',
type: 'image/png',
sizes: '180x180',
href: '/images/favicon/favicon-180.png'
href: '/docs/images/favicon/favicon-180.png'
}
]
],
sitemap: {
hostname: 'https://docs.apostrophecms.org/',
// here a hostname is not optional, we want one to be
// generated for review even in dev
hostname: (hostname || 'http://localhost:4173'),
transformItems: (items) => {
items.forEach(page => {
// We need to add
// the base because vitepress doesn't do that automatically
// for sitemaps as of today
page.url = `${base}${page.url}`;
page.changefreq = 'monthly';
});
return items;
Expand All @@ -147,7 +166,7 @@ export default defineConfig({
const { pageData } = context;

const relativePath = pageData.relativePath;
const absolutePath = `https://docs.apostrophecms.org/${relativePath.replace('.md', '.html')}`;
const absolutePath = `${hostname}/docs/${relativePath.replace('.md', '.html')}`;

const head = [
[
Expand Down Expand Up @@ -231,7 +250,7 @@ export default defineConfig({
'meta',
{
property: 'og:image',
content: 'https://docs.apostrophecms.org/images/og-docs-image.png'
content: '/docs/images/og-docs-image.png'
}
],
[
Expand Down Expand Up @@ -259,7 +278,7 @@ export default defineConfig({
'meta',
{
name: 'twitter:domain',
content: 'docs.apostrophecms.org'
content: 'apostrophecms.com'
}
],
[
Expand Down Expand Up @@ -287,7 +306,7 @@ export default defineConfig({
'meta',
{
property: 'twitter:image',
content: 'https://docs.apostrophecms.org/images/og-docs-image.png'
content: '/docs/images/og-docs-image.png'
}
],
[
Expand Down Expand Up @@ -399,7 +418,7 @@ export default defineConfig({
};

if (pageData.frontmatter.featured_image) {
structuredData.image = `https://docs.apostrophecms.org${pageData.frontmatter.featured_image}`;
structuredData.image = `${hostname}${pageData.frontmatter.featured_image}`;
}

head.push(['script', { type: 'application/ld+json' }, JSON.stringify(structuredData)]);
Expand Down
8 changes: 4 additions & 4 deletions docs/cookbook/creating-webhooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ handlers(self) {
async sendWebhook(req, data) {
// data sent by the afterPublish event includes the document data
// and whether it is being published for the first time
// https://docs.apostrophecms.org/reference/server-events.html#afterpublish
// https://apostrophecms.com/docs/reference/server-events.html#afterpublish
if (!data.firstTime) {
return;
}
Expand All @@ -40,11 +40,11 @@ handlers(self) {

In this block of code, we are using the `handlers(self)` module configuration function. We could use any server event, but in this case, we are using the `afterPublication` event that is emitted by our custom article piece-type module. This server event delivers two parameters, `req` and `data`. The `data` parameter contains information about the document being published including the content and whether this is the first time it is being published. In this case, we are adding an early return if this isn't the first time the document is being published.

The next section of code is involved in setting up the HTTP `POST` request using the `post` method of the [`@apostrophecms/http` module](https://docs.apostrophecms.org/reference/modules/http.html#async-post-url-options) to send our data to the endpoint. Depending on the endpoint, the returned response might be as simple as a `200` success or a `400` failed response, or might contain additional data. You can wrap your `POST` in a try-catch block to catch any exceptions. You can then decide whether to throw an error or notify the user of a problem with `self.apos.notify(req, 'We were unable to send a notification to Slack.');`
The next section of code is involved in setting up the HTTP `POST` request using the `post` method of the [`@apostrophecms/http` module](/reference/modules/http.md#async-post-url-options) to send our data to the endpoint. Depending on the endpoint, the returned response might be as simple as a `200` success or a `400` failed response, or might contain additional data. You can wrap your `POST` in a try-catch block to catch any exceptions. You can then decide whether to throw an error or notify the user of a problem with `self.apos.notify(req, 'We were unable to send a notification to Slack.');`

## Incoming webhooks

Your project may require a webhook endpoint to receive incoming notices from services, like a payment portal or subscription manager. Much like Slack can add a message to a channel when it receives data from your site on the correct endpoint, your site can be set up to make changes to the database or perform other tasks when data is received at a specific endpoint. This can be accomplished by using the Apostrophe [`apiRoutes(self)` module configuration](https://docs.apostrophecms.org/reference/module-api/module-overview.html#apiroutes-self) function. This allows you to easily set up an endpoint for any HTTP request method.
Your project may require a webhook endpoint to receive incoming notices from services, like a payment portal or subscription manager. Much like Slack can add a message to a channel when it receives data from your site on the correct endpoint, your site can be set up to make changes to the database or perform other tasks when data is received at a specific endpoint. This can be accomplished by using the Apostrophe [`apiRoutes(self)` module configuration](/reference/module-api/module-overview.md#apiroutes-self) function. This allows you to easily set up an endpoint for any HTTP request method.

<AposCodeBlock>

Expand Down Expand Up @@ -88,7 +88,7 @@ apiRoutes(self) {

In this code example, the webhook is being implemented using the `apiRoutes(self)` module configuration function. We are exposing a `POST` route, the one that is most typically used by webhook providers, by passing an object with our function to the `post` property. The function is named for the route it is exposing. In this case, it starts with a forward slash (`/`), indicating that this is relative to the project site itself, e.g. `https://www.my-project.com/webhooks`.

Within the function, we first are checking for the presence of an authorization header. If it isn't found we throw an error with the string 'forbidden'. This is mapped to a `403` error and returns it to the webhook originator. There are a number of other error strings detailed in the reference documentation for [`apiRoutes`](https://docs.apostrophecms.org/reference/module-api/module-overview.html#returning-error-codes). Once authentication is complete you can pass the data off for sanitization and use.
Within the function, we first are checking for the presence of an authorization header. If it isn't found we throw an error with the string 'forbidden'. This is mapped to a `403` error and returns it to the webhook originator. There are a number of other error strings detailed in the reference documentation for [`apiRoutes`](/reference/module-api/module-overview.md#returning-error-codes). Once authentication is complete you can pass the data off for sanitization and use.

Finally, most providers require the return of some type of success message, otherwise, they will attempt to resend the webhook. If no information needs to be supplied you can simply return an empty object. Alternatively, you can return an object that contains information to include in the body of the response. The header will still indicate a response of `200/OK`.

Expand Down
4 changes: 2 additions & 2 deletions docs/cookbook/html-conversion.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Let's get started converting this template to an Apostrophe project!

## Creating a new project

If you don't already have the apostrophe CLI installed, follow the instructions [here](https://docs.apostrophecms.org/guide/setting-up.html#the-apostrophe-cli-tool). Next, create a new project from the command line. Make sure you are in the directory where you want to create your new project folder and run the following command:
If you don't already have the apostrophe CLI installed, follow the instructions [here](/guide/setting-up.md#the-apostrophe-cli-tool). Next, create a new project from the command line. Make sure you are in the directory where you want to create your new project folder and run the following command:

<AposCodeBlock>

Expand Down Expand Up @@ -899,7 +899,7 @@ The "Home" page of the template is essentially an `index.html` page that lists a
</template>
</AposCodeBlock>

Focusing on the `for` loop in the code. We are stepping through all of the articles returned in `data.pieces` and outputing the relevant data. Again, since we specified a `perPage` value of `5` in the options, this will return the five newest blog articles. This can be further configured within the `blog-page` module options, for example with the [`sort` option](https://docs.apostrophecms.org/reference/modules/piece-type.html#sort).
Focusing on the `for` loop in the code. We are stepping through all of the articles returned in `data.pieces` and outputing the relevant data. Again, since we specified a `perPage` value of `5` in the options, this will return the five newest blog articles. This can be further configured within the `blog-page` module options, for example with the [`sort` option](/reference/modules/piece-type.md#sort).

The "Pager" section is expanded to conditionally show newer and older blog articles, unlike the original template, which only shows older articles. Within the section, we are taking advantage of some additional data that is being delivered to the `index.html` page. Within the `data` payload are `data.currentPage` and `data.totalPages`. The `data.totalPages` is how many individual data sets are present for the particular piece type if divided into groups based on the `perPage` option (the default is `10`).

Expand Down
2 changes: 1 addition & 1 deletion docs/cookbook/ubuntu-hosting.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ The `root` and `try_files` statements let nginx serve static files directly, for
the best speed; if the URL isn't a static file, it is passed to Apostrophe. `expires 7d` allows the browser to cache the static files, for performance.
:::

1. You'll want to **add SSL for HTTPS connections**, too. For that, follow the LetsEncrypt [Certbot documentation](https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx.html). Certbot will make the necessary nginx configuration changes for you.
1. You'll want to **add SSL for HTTPS connections**, too. For that, follow the LetsEncrypt [Certbot documentation](https://certbot.eff.org/instructions?ws=nginx&os=snap). Certbot will make the necessary nginx configuration changes for you.

2. Now instruct `nginx` to restart:

Expand Down
6 changes: 3 additions & 3 deletions docs/cookbook/using-docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Docker can be installed on Mac, Windows, and Linux machines with either a CLI in

### Apostrophe project setup

For this tutorial, we will be using the [a3-demo](https://github.com/apostrophecms/a3-demo) template. However, you can also use an existing project or create a new one by following our getting started [tutorial](https://docs.apostrophecms.org/guide/setting-up.html). If using the a3-demo, follow the link and click on the "Use this template" button to fork the template into your own repo. Next, clone the repo to your local machine and open it in your favorite code editor.
For this tutorial, we will be using the [a3-demo](https://github.com/apostrophecms/a3-demo) template. However, you can also use an existing project or create a new one by following our getting started [tutorial](/guide/setting-up.md). If using the a3-demo, follow the link and click on the "Use this template" button to fork the template into your own repo. Next, clone the repo to your local machine and open it in your favorite code editor.

### Creating the dockerfile

Expand Down Expand Up @@ -234,7 +234,7 @@ While in this example, our project is still being hosted locally, any of these c
Right now, our Dockerized container is limited to a single server. For simple, low-traffic sites this could be fine. However, if we want to scale our site over several servers and add a load balancer like Nginix, we need to add support for cloud storage and a cloud database. Fortunately, Apostrophe makes this relatively easy.

## Using AWS S3 services
If you aren't hosting your project on a single server, you will need to have a different uploaded asset storage method. Typically this is a service like Amazon Web Services S3 or another similar service. Apostrophe is set up to easily use S3 services by adding environment variables. You can read more in the [documentation](https://docs.apostrophecms.org/reference/modules/uploadfs.html#s3-storage-options). We can take advantage of this in Docker by expanding our `docker-compose.yml` and `.env` files.
If you aren't hosting your project on a single server, you will need to have a different uploaded asset storage method. Typically this is a service like Amazon Web Services S3 or another similar service. Apostrophe is set up to easily use S3 services by adding environment variables. You can read more in the [documentation](/reference/modules/uploadfs.md#s3-storage-options). We can take advantage of this in Docker by expanding our `docker-compose.yml` and `.env` files.

### Changing the `docker-compose.yaml` file
In order to pass the environment variables into our project container we just need to add them inside the `environment:` key. If we are using S3 services at Amazon, we need to add four variables: `APOS_S3_REGION`, `APOS_S3_BUCKET`, `APOS_S3_KEY`, and `APOS_S3_SECRET`. For other S3-type storage solutions, such as [filebase](https://filebase.com/), you will also want to set the `APOS_S3_ENDPOINT` variable. For AWS, your `environment:` section should now look like this:
Expand Down Expand Up @@ -328,7 +328,7 @@ docker compose up
Great, so we have a working Apostrophe Docker image. How do we get it on the web? There are many options. Here are a few.

* [Automated builds from GitHub](https://docs.docker.com/docker-hub/github/)
* Install [Dokku](http://dokku.viewdocs.io/dokku/) on the server then use [Dockerfile deployment](http://dokku.viewdocs.io/dokku/deployment/methods/dockerfiles/)
* Install [Dokku](https://dokku.com/docs/getting-started/installation/) on the server then use [Dockerfile deployment](https://dokku.com/docs/getting-started/install/docker/)
* Use `docker save` and `docker load` to [deploy without a private registry](https://realguess.net/2015/02/04/docker-save-load-and-deploy/)
* Build the image directly on the server
* Many more (use a web search!)
Loading