diff --git a/.gitignore b/.gitignore index a67054a6..38b7d339 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ node_modules docs/.vitepress/cache docs/.vitepress/dist docs/public/version.json +docs-planning diff --git a/docs/.vitepress/sidebarGuide.js b/docs/.vitepress/sidebarGuide.js index 701a8fba..4c8b6215 100644 --- a/docs/.vitepress/sidebarGuide.js +++ b/docs/.vitepress/sidebarGuide.js @@ -11,7 +11,7 @@ const sidebarGuide = [ link: 'guide/introduction.md' }, { - text: 'Why Apostrophe', + text: 'Why ApostropheCMS', link: 'guide/why-apostrophe.md' }, { @@ -51,11 +51,11 @@ const sidebarGuide = [ link: 'guide/migration/overview.md' }, { - text: 'Upgrade From Apostrophe 2', + text: 'Upgrade From ApostropheCMS 2', link: 'guide/migration/upgrading.md' }, { - text: 'Upgrade From Apostrophe 3', + text: 'Upgrade From ApostropheCMS 3', link: 'guide/migration/upgrading-3-to-4.md' }, { @@ -205,6 +205,10 @@ const sidebarGuide = [ text: 'JSX Templates', link: 'guide/jsx-templates.md' }, + { + text: 'Nunjucks Templates', + link: 'guide/nunjucks-templates.md' + }, { text: 'Custom Nunjucks Tags', link: 'reference/template-tags.md' diff --git a/docs/cookbook/deploying-to-heroku.md b/docs/cookbook/deploying-to-heroku.md index f9b4a448..a1dcb326 100644 --- a/docs/cookbook/deploying-to-heroku.md +++ b/docs/cookbook/deploying-to-heroku.md @@ -1,9 +1,9 @@ -# Deploying Apostrophe in the Cloud with Heroku +# Deploying ApostropheCMS in the Cloud with Heroku There are many cloud hosting services, but they all present the same challenges. For example, separate servers often don't share a single filesystem. The database usually needs its own scalable cloud hosting. And performing tasks like minifying assets is often best done in your development environment, minimizing what has to be done in production. -## Deploying Apostrophe to Heroku +## Deploying ApostropheCMS to Heroku [Heroku](http://heroku.com) is a great starting point for cloud hosting because it is simple to set up, but all of the cloud's challenges come into play. What we learn by deploying to Heroku can be applied equally to Amazon EC2, Microsoft Azure, and other cloud hosting services. @@ -12,10 +12,10 @@ To reduce costs for this how-to, we'll be using free services from Amazon Web Se ## Before you begin ### Create the project (or use your own) -First, build an Apostrophe site! See the [setting up page](../guide/development-setup.md) to get started with the installation of the CLI. We will create a project called `heroku-tut`. Alternatively, you can use an existing Apostrophe site by simply skipping this step. +First, build an Apostrophe site! See the [setting up page](../guide/development-setup.md) to get started. We will create a project called `heroku-tut`. Alternatively, you can use an existing Apostrophe site by simply skipping this step. ```bash -$ apos create heroku-tut +$ npm create apostrophe@latest heroku-tut ``` ### Commit to Git After creation, the project needs to be committed to a Git repository. If you don't already have Git installed on your system, you can learn about installation at the [official site](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). diff --git a/docs/cookbook/index.md b/docs/cookbook/index.md index a7262453..706271e7 100644 --- a/docs/cookbook/index.md +++ b/docs/cookbook/index.md @@ -1,10 +1,10 @@ --- -title: Code Cookbook +title: ApostropheCMS Code Cookbook prev: false next: false --- -# Apostrophe code cookbook +# ApostropheCMS code cookbook Welcome to the cookbook. These code recipes show how to execute specific tasks, from hosting setup to commonly used module configurations. For more general information about Apostrophe configuration and concepts see [the main documentation](../guide/introduction). diff --git a/docs/cookbook/using-docker.md b/docs/cookbook/using-docker.md index 54d37a0d..23f895b7 100644 --- a/docs/cookbook/using-docker.md +++ b/docs/cookbook/using-docker.md @@ -1,4 +1,4 @@ -# Hosting an Apostrophe project with Docker +# Hosting an ApostropheCMS project with Docker [Docker](https://www.docker.com/) is a containerization platform that lets developers build an image for their projects and then run it anywhere. This guide is for production, not development. If you want to use Docker as a development environment, you can explore using a persistent Docker volume for your project, but bear in mind that commands like npm install can be very slow in such a configuration. diff --git a/docs/cookbook/using-s3-storage.md b/docs/cookbook/using-s3-storage.md index 2d7658cd..c5fe1dc7 100644 --- a/docs/cookbook/using-s3-storage.md +++ b/docs/cookbook/using-s3-storage.md @@ -1,4 +1,4 @@ -# Using S3 services with Apostrophe +# Using S3 services with ApostropheCMS Deploying Apostrophe to production requires that you specify hosting for the code base, the MongoDB instance, and storage for any uploaded content. Many hosting services can provide all three, but it is also possible and sometimes desirable to split these between different services. This tutorial looks at file storage solutions using the S3 API. diff --git a/docs/cookbook/windows-development.md b/docs/cookbook/windows-development.md index e09d9c12..4c4631a6 100644 --- a/docs/cookbook/windows-development.md +++ b/docs/cookbook/windows-development.md @@ -1,7 +1,7 @@ --- next: - text: 'Code Organization - Modules' - link: '/guide/modules.html' + text: 'Creating a project' + link: '/guide/development-setup.html#creating-a-project' --- # Windows Development with WSL 2 (Optional) diff --git a/docs/guide/adding-custom-widget-placeholder-content.md b/docs/guide/adding-custom-widget-placeholder-content.md index 301ebf28..d85028b1 100644 --- a/docs/guide/adding-custom-widget-placeholder-content.md +++ b/docs/guide/adding-custom-widget-placeholder-content.md @@ -41,34 +41,38 @@ module.exports = { You can bypass the call to `determineBestAsetUrl()` for your images or videos stored in the `public` folder and instead pass the path to the asset using `placeholderUrl` in place of `placeholderImage`. This is discouraged because errors can be made in this path. It is better to let Apostrophe figure this out for you. ::: -### Altering the widget.html file +### Altering the widget template -The specific alteration of the `widget.html` template will depend on the type of placeholder content being delivered. Irrespective of file type, the template will have access to `data.widget.aposPlaceholder` and `data.manager.options.placeholderUrl` to populate the markup. +The specific alteration of the widget template will depend on the type of placeholder content being delivered. Irrespective of file type, the template will have access to the widget's `aposPlaceholder` property and the manager's `placeholderUrl` option to populate the markup — `data.widget.aposPlaceholder` and `data.manager.options.placeholderUrl` in Nunjucks, or the destructured `widget.aposPlaceholder` and `manager.options.placeholderUrl` in JSX, since `manager` arrives on the same data object as `widget`. -The first, `data.widget.aposPlaceholder`, allows for confirmation that the placeholder should be displayed. This will return `true` when the widget is first added and return `false` once the widget has been edited. +The first, `aposPlaceholder`, allows for confirmation that the placeholder should be displayed. This will return `true` when the widget is first added and return `false` once the widget has been edited. -The second, `data.manager.options.placeholderUrl`, will contain the path to the content placeholder asset. If you set the `placeholderImage`, this will either be the path computed by the call to `determineBestAssetUrl()`. Otherwise, it will be the URL passed directly through the `placeholderUrl` option. +The second, `placeholderUrl`, will contain the path to the content placeholder asset. If you set the `placeholderImage`, this will either be the path computed by the call to `determineBestAssetUrl()`. Otherwise, it will be the URL passed directly through the `placeholderUrl` option. This example demonstrates adding an image. -``` nunjucks -
-

Custom Widget

- {% if data.widget.aposPlaceholder and data.manager.options.placeholderUrl %} - {{ __t('nameSpace:imagePlaceholder') }} - {% else %} - - {% endif %} -
+```jsx +export default function({ widget, manager }, { __t }) { + return ( +
+

Custom Widget

+ {widget.aposPlaceholder && manager.options.placeholderUrl ? ( + {__t('nameSpace:imagePlaceholder')} + ) : ( + <>{/* markup displayed after the user edits the widget */} + )} +
+ ); +} ```
@@ -77,21 +81,25 @@ This example demonstrates adding a self-hosted video. -``` nunjucks -
- - {% if data.widget.aposPlaceholder and data.manager.options.placeholderUrl %} - - {% else %} - - {% endif %} -
+```jsx +export default function({ widget, manager }) { + return ( +
+ {/* For videos uploaded to the `public` folder */} + {widget.aposPlaceholder && manager.options.placeholderUrl ? ( + + ) : ( + <>{/* markup displayed after the user edits the widget */} + )} +
+ ); +} ```
@@ -100,7 +108,7 @@ This example demonstrates adding a self-hosted video. Your placeholder content should be added to the `public` folder of the custom widget. It should be named `placeholder.extension`, where the extension matches the extension passed into the `placeholderImage` option. In the first example above, the file should be `modules/custom-widget/public/placeholder.png`. ## Adding a placeholder with a custom name -In some cases, a widget might need to have more than a single piece of placeholder content, or you might want to give the placeholder content a different name than `placeholder.extension`. In this case, once again you need to modify the main module options, the Nunjuck template, and the contents of the public folder. +In some cases, a widget might need to have more than a single piece of placeholder content, or you might want to give the placeholder content a different name than `placeholder.extension`. In this case, once again you need to modify the main module options, the widget template, and the contents of the public folder. ### Altering the `index.js` file for custom placeholders @@ -110,9 +118,9 @@ For each self-hosted placeholder, the initialization function should call the `d If electing to add multiple placeholders to a single page, as soon as the user makes any edits, all placeholder content will be removed from the page because `aposPlaceholder` is only checked once to determine if the widget has been edited. -### Altering the Nunjucks template for custom placeholders +### Altering the widget template for custom placeholders -The template will still have access to `data.widget.aposPlaceholder` to determine if the widget has been edited and remove placeholder content. The URL for the placeholder can be accessed using `data.manager.options.Url`. For example, `data.manager.options.customOneUrl` or `data.manager.options.videoOneUrl`. This will be available for each `Image` and `Url` option in the module. +The template will still have access to the widget's `aposPlaceholder` property to determine if the widget has been edited and remove placeholder content — `data.widget.aposPlaceholder` in Nunjucks, or the destructured `widget.aposPlaceholder` in JSX. The URL for the placeholder can be accessed using `Url` on the widget manager's options — `data.manager.options.Url` in Nunjucks, or the destructured `manager.options.Url` in JSX, since `manager` arrives on the same data object as `widget`. For example, `customOneUrl` or `videoOneUrl`. This will be available for each `Image` and `Url` option in the module. The same conditional block that was used for a single basic placeholder should be used for each custom placeholder added to the template. diff --git a/docs/guide/apostrophe-demo-overview.md b/docs/guide/apostrophe-demo-overview.md index 7082c569..7a2380f0 100644 --- a/docs/guide/apostrophe-demo-overview.md +++ b/docs/guide/apostrophe-demo-overview.md @@ -10,7 +10,7 @@ The sections below cover the patterns you encounter in the first hour of working This starter is a single unified application: ApostropheCMS handles content modeling, the admin editing UI, server-side rendering, and asset serving in one Node.js/Express process. There is no separate frontend server. When a request arrives, ApostropheCMS selects the matching template, populates it with content data, and returns the rendered HTML directly. -Templates can be written in Nunjucks (`.html`) or JSX (`.jsx`); both are fully supported and can coexist in the same project. If both exist for the same template, `.jsx` wins. +Templates can be written in [JSX](/guide/jsx-templates.md) (`.jsx`) or Nunjucks (`.html`). JSX is the recommended choice for new work; Nunjucks remains fully supported, and the two coexist in the same project. Apostrophe walks the module's view-folder override chain, preferring `.jsx` then `.njk` then `.html` **within each folder** — so a template in a nearer override folder wins regardless of its extension. See [`render()`](/reference/modules/module.md#async-render-req-template-data). ## Template Discovery @@ -18,56 +18,63 @@ Templates are discovered automatically by filename — there is no registry to u | Template | Path | |---|---| -| Widget | `modules/{module-name}/views/widget.html` or `.jsx` | -| Regular page | `modules/{module-name}/views/page.html` or `.jsx` | -| Piece index | `modules/{module-name}/views/index.html` or `.jsx` | -| Piece show | `modules/{module-name}/views/show.html` or `.jsx` | +| Widget | `modules/{module-name}/views/widget.jsx` or `.html` | +| Regular page | `modules/{module-name}/views/page.jsx` or `.html` | +| Piece index | `modules/{module-name}/views/index.jsx` or `.html` | +| Piece show | `modules/{module-name}/views/show.jsx` or `.html` | > **Note:** A `.jsx` template can extend or include a `.html` layout using `` or `