diff --git a/.gitignore b/.gitignore
index 82863e71d..0a81ddefa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,6 +14,3 @@ pyvenv.cfg
docs/volto
docs/plone.restapi
docs/plone.api
-
-# editor files
-.vscode
diff --git a/docs/classic-ui/index.md b/docs/classic-ui/index.md
index 8fd0f5a9c..25f8019c7 100644
--- a/docs/classic-ui/index.md
+++ b/docs/classic-ui/index.md
@@ -55,6 +55,7 @@ images
layers
module-federation
mockup
+page-templates
portlets
recipes
static-resources
diff --git a/docs/classic-ui/page-templates.md b/docs/classic-ui/page-templates.md
new file mode 100644
index 000000000..2feef36c4
--- /dev/null
+++ b/docs/classic-ui/page-templates.md
@@ -0,0 +1,342 @@
+---
+myst:
+ html_meta:
+ "description": "Page templates in Plone Classic UI"
+ "property=og:description": "Page templates in Plone Classic UI"
+ "property=og:title": "Page templates in Plone Classic UI"
+ "keywords": "Plone 6, Classic UI, page, templates, Twitter Bootstrap 5"
+---
+
+(classic-ui-page-templates-index-label)=
+
+# Page templates
+
+This chapter provides an tutorial of page templates in Classic UI.
+
+
+## Background
+
+When you visit the Plone backend with a web browser, you will view the Classic UI.
+These pages are generated with classic Plone browser views and page templates.
+
+Browser views are documented in depth in {doc}`views`.
+
+Plone Classic UI uses {term}`Zope Page Template`s (ZPT).
+These templates use well established and time-tested standards, {term}`Template Attribute Language` (TAL), {term}`Template Attribute Language Expression Syntax` (TALES), and {term}`Macro Expansion Template Attribute Language` (METAL).
+
+From a Python programmer's point of view, page templates are a tool to display a Python object on the web, instead of what that object's `__repr__()` method would return.
+These template files always have a file extension of `.pt`.
+
+A normal full Plone HTML page consists of the following.
+
+- the _master template_ defining the overall layout of the page
+- METAL _slots_ defined by the master template, and filled by the object being published
+- _viewlets_ and _viewlet managers_
+- _tiles_
+
+Page templates most frequently describe an HTML document.
+They can also render XML, which is useful for RSS feeds or XML-based APIs.
+
+Templates can render any media type you find useful, including Markdown, LaTeX, or plain text.
+You could, if you wanted, create a page template that rendered a media type of `application/json`, but there are better ways to do that directly from a browser view.
+The point here is that you are not limited to templates that only create HTML.
+
+
+## Override existing templates
+
+Your first journey in page templates could be to override a Plone backend core template or a template from an add-on.
+The recommended approach is to use [`z3c.jbot`](https://pypi.org/project/z3c.jbot/), and to put your customized templates onto the filesystem and under a version control system.
+
+
+### `z3c.jbot`
+
+`z3c.jbot` can override page templates for views, viewlets, old style page templates and portlets.
+In fact, it can override any `.pt` file in the Plone source tree.
+
+To override a particular file, first determine its canonical filename.
+It's defined as the path relative to the package within which the file is located.
+
+```{tip}
+See Customizing Existing Templates – Mastering Plone 5 development training, {ref}`training:plone5-zpt2-finding-label`.
+```
+
+```{todo}
+@stevepiercy spun up a clean Plone site via buildout.
+The paths that @flipcmf originally mentioned do not exist in the `eggs` directory.
+@stevepiercy found the source `search.pt` file, but has no clue where to put it in the project file system.
+The information in the next few paragraphs must be verified by someone who knows what they're doing.
+```
+
+As an example, to override the default search page in Plone Classic UI, first find the existing template.
+In a fresh plone install, it's at {file}`src/Products.CMFPlone/Products/CMFPlone/browser/templates/search.pt`.
+You will name the file by replacing the directory separators (`/`) with dots (`.`).
+Thus the override file will be called `Products.CMFPlone.browser.templates.search.pt`.
+
+Create a new directory inside your local Plone install for template overrides `mysite/template-overrides`.
+Copy the Plone `search.pt` into that directory, and rename it to `Products.CMFPlone.browser.templates.search.pt`
+
+```text
+├─ myproject
+│ ├─ src
+│ │ └─ Products.CMFPlone
+│ │ └─ Products
+│ │ └─ CMFPlone
+│ │ └─ browser
+│ │ └─ templates
+│ │ └─ search.pt ← override this
+│ └─ mysite
+│ ├─ configure.zcml
+│ └─ template-overrides
+│ └─ Products.CMFPlone.browser.templates.search.pt ← with this
+```
+
+In your {file}`configure.zcml`, register the `template-overrides` directory with `z3c.jbot`.
+
+```xml
+
+
+
+```
+
+Now edit `Products.CMFPlone.browser.templates.search.pt`, and see your changes on the Plone search page.
+
+
+### Override with ZCML
+
+Although not best practice, you can also override templates by creating an {file}`override.zcml` and add your custom registration.
+For the search page, use the ZCML entry for the search view in `Products/CMFPlone/browser/configure.zcml` and copy it into your own {file}`overrides.zcml`, but change the `template` attribute to point to your custom template.
+You must also change the `class` attribute to become an absolute dotted path to the original class path.
+
+```xml
+
+```
+
+### Layer with ZCML
+
+A better and much more flexible way to override templates, especially when developing add-ons, is to use a browser layer in your {file}`configure.zcml`.
+This is _highly_ preferred to using an {file}`overrides.zcml` file, but involves using a `BrowserLayer` interface.
+
+```xml
+
+```
+
+
+### Edit browser views
+
+Sometimes when you look up a browser view's ZCML, it does not have a `template` attribute.
+In this case, the template is frequently hard-coded into the Python browser view.
+One example of this is in the control panel pages, where the templates are not added to {file}`configure.zcml`.
+`@@actions-controlpanel` is found in `Products/CMFPlone/controlpanel/browser/actions.py`.
+
+```python
+from Products.Five import BrowserView
+from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
+
+class ActionListControlPanel(BrowserView):
+ """Control panel for the portal actions."""
+
+ template = ViewPageTemplateFile("actions.pt")
+```
+
+These are harder to override.
+Best practice is to copy the Python file ({file}`actions.py` in this case) to your customizations folder, and override the entire `browser:page` as shown above, pointing to your own {file}`actions.py` and modifying that Python code to find your new template `.pt` file.
+
+
+## Create your own templates
+
+If you create your own content type object, you probably want to display it on a web browser.
+Without a template, a default view will come up using Plone's built-in main template and default view for a content type.
+
+
+### Stand-alone templates
+
+```{warning}
+Although templates can be stand alone templates that render a Plone object directly, this is not best practice.
+A combination of a view and page template is the correct implementation.
+```
+
+The simplest possible template is an HTML document.
+
+```html
+
+
+hello custom template
+
+
+```
+
+Register it in ZCML.
+
+```xml
+
+```
+
+if you now go to any content item on your plone site, including the site itself, and add `custom_template` to the end of the url, the above html will display.
+
+This isn't very useful, but does show how Plone basically works.
+
+### Browser view templates
+
+```{todo}
+Todo
+```
+
+
+## Advanced Concepts
+
+```{todo}
+Todo
+```
+
+
+### Call templates in Python
+
+```{todo}
+Todo
+```
+
+
+### Pass data to templates
+
+```{todo}
+Todo
+```
+
+
+## Language reference
+
+```{todo}
+Todo
+```
+
+
+### Chameleon
+
+[Chameleon](https://chameleon.readthedocs.io/en/latest/) is an HTML/XML template engine for Python.
+It's designed to generate the document output of a web application, typically HTML markup or XML.
+
+The language used is _page templates_, originally a Zope invention.
+
+```{note}
+The template language specifications and API for the page templates engine are based on Zope Page Templates (see in particular `zope.pagetemplate`).
+However, the Chameleon compiler and page templates engine is an entirely new code base, packaged as a stand alone distribution.
+It does not require a Zope software environment.
+```
+
+The template engine compiles templates into Python byte code, and is optimized for speed.
+For a complex template language, the performance is very good.
+
+The page templates language is used within your document structure as special element attributes and text markup.
+Using a set of simple language constructs, you control the document flow, element repetition, text replacement, and translation.
+The language is known as {term}`Template Attribute Language` or TAL.
+The following snippet is a basic example.
+
+```xml
+
+
+ Hello, ${'world'}!
+
+
+
+ ${row.capitalize()} ${col}
+ |
+
+
+
+
+```
+
+The `${...}` notation is shorthand for text insertion.
+The Python expression inside the braces is evaluated, and the result included in the output.
+By default, the string is escaped before insertion.
+To avoid this, use the `structure` keyword:
+
+```xml
+
+```
+
+Note that if the expression result is an object that implements an `__html__()` method, this method will be called and the result treated as "structure".
+An example of such an object is the `Markup` class that's included as a utility.
+
+```python
+from chameleon.utils import Markup
+username = Markup("%s" % username)
+```
+
+The macro language—known as the {term}`Macro Expansion Template Attribute Language` (METAL)—provides a means of filling in portions of a generic template.
+
+The following two snippets work together.
+First the macro template.
+
+```xml
+
+
+ Example — ${document.title}
+
+
+ ${document.title}
+
+
+
+
+
+```
+
+Next the template that loads and uses the macro, filling in the `content` slot.
+
+```xml
+
+ ${structure: document.body}
+
+```
+
+In the example, the expression type `load` is used to retrieve a template from the file system using a path relative to the calling template.
+
+The METAL system works with TAL such that you can, for instance, fill in a slot that appears in a `tal:repeat` loop, or refer to defined variables using `tal:define`.
+
+The third language subset is the translation system, known as the internationalization language or {term}`i18n`.
+
+```xml
+
+
+ ...
+
+
+ You have ${round(amount, 2)} dollars in your account.
+
+
+...
+
+
+```
+
+Each translation message is marked up using `i18n:translate`, and values can be mapped using `i18n:name`.
+Attributes are marked for translation using `i18n:attributes`.
+The template engine generates `gettext ` translation strings from the markup.
+
+```text
+ "You have ${amount} dollars in your account."
+```
+
+If you use a web framework, such as `Pyramid `, the translation system is set up automatically and will negotiate on a _target language_ based on the HTTP request or other parameter.
+If not, then you need to configure this manually.
diff --git a/docs/glossary.md b/docs/glossary.md
index 4e161d317..f082d875a 100644
--- a/docs/glossary.md
+++ b/docs/glossary.md
@@ -136,9 +136,20 @@ ZMI
The ZMI is a direct interface into the backend software stack of Plone.
While it can still serve as a valuable tool for Plone specialists to fix problems or accomplish certain tasks, it is not recommended as a regular tool for Plone maintenance.
+Template Attribute Language
+TAL
+ The [Template Attribute Language](https://pagetemplates.readthedocs.io/en/latest/tal.html) (TAL) standard is an attribute language used to create dynamic templates.
+ It allows elements of a document to be replaced, repeated, or omitted.
+
+Template Attribute Language Expression Syntax
TALES
- TAL Expression Syntax (TALES) expression, which by default expects a path.
- Python and string expressions are also allowed.
+ The [Template Attribute Language Expression Syntax](https://pagetemplates.readthedocs.io/en/latest/tales.html) (TALES) standard describes expressions that supply {term}`TAL` and {term}`METAL` with data.
+ Python and string expressions are allowed.
+
+Macro Expansion Template Attribute Language
+METAL
+ The [Macro Expansion Template Attribute Language](https://pagetemplates.readthedocs.io/en/latest/metal.html) (METAL) standard is a facility for HTML/XML macro preprocessing.
+ It can be used in conjunction with or independently of {term}`TAL` and {term}`TALES`.
XML
The Extensible Markup Language.
@@ -519,6 +530,7 @@ ZODB
Zope
[Zope](https://zope.readthedocs.io/en/latest/) is a Python-based application server for building secure and highly scalable web applications.
+Zope Page Template
ZPT
Zope Page Template is a template language for Python.