Skip to content
Get started
Documentation menu

Entity types and taxonomies

This page lists everything about content in the admin: the list and its filters, the edit form, versions, content types, taxonomies and people. To create and publish something step by step, follow Edit and publish content.

Overview

Hatamoto stores every piece of content as an entity: a page, a blog post, a person or any other item. Each entity belongs to an entity type (shown to editors as a content type), whose schema decides its fields and its public address. A taxonomy groups entities, such as categories or tags, and each group in it is a term.

ScreenAddressOwnerEditor
Entity list, edit form, versions/admin/entitiesyesyes
People/admin/peopleyesyes
Media library/admin/settings/mediayesyes
Entity types/admin/settings/typesyesno
Taxonomies/admin/settings/taxonomiesyesno

The entity list

/admin/entities is where you land after signing in. A secondary sidebar lists All entities and one entry per entity type with its entry count. Owners also get Manage entity types. Choosing a type (?type=<slug>) shows that type with its plural name as the title, one New button for that type and no Type column. An unknown slug falls back to All.

From All entities, the Create menu lists every type except reusable blocks and layout parts, which live under Theme. Choosing a page or a post type creates an "Untitled" draft and opens its editor; a writer's newest untouched draft of that type is reused, so double clicks do not pile up empty drafts. Any other type opens the new-entity form.

Every filter lives in the address, so a view can be bookmarked:

ParameterMeaning
qSearch titles and URLs
typeAn entity type slug
statuspublished, draft, scheduled or archived
underA parent entity: shows everything below it. The Parent filter appears when some entities have children.
authorAn author (person)
termA taxonomy term, including its descendants
from, toUpdated-date range
sort, dirSort column (name, status or updated; the default is updated, newest first) and direction
pagePage number

Row and bulk actions

ActionShown whenEffect
EditalwaysOpens the editor for the type
Settingsthe type uses the page, section or blog editorOpens the entity form (/admin/entities/{id}) for name, slug and search details
View on sitepublished and the entity has a public addressOpens the public page
UnpublishpublishedMoves it back to draft
Publishdraft or archivedPublishes it
DeletealwaysConfirmation page, then deletes the entity and its versions

Bulk actions are Publish, Move to draft, Archive and Delete. The checked ids are posted to /admin/entities/bulk. Delete always asks first: without JavaScript you get a confirmation page (the form posts again with confirmed=1), with JavaScript the browser's confirm dialog opens.

The edit form

/admin/entities/{id} shows the entity form. Types that use a visual editor open it from /admin/entities/{id}/edit instead: pages (and any entity with page sections) open in the page builder, and post types open in the blog editor. The admin picks the right screen for the type. See the Editor reference.

The form is one POST and contains:

FieldNotes
Name, SlugThe slug is the last part of the public address.
StatusDraft, Published, Scheduled or Archived.
Publish atUsed when the status is Scheduled. Typed in the site time zone (Settings > General). The background worker publishes the entity when it is due.
ParentShown only when the type's address pattern uses {path} or {parent} (a page tree). A search box.
AuthorA person. Or add a new author creates one.
TermsCategories, tags and any custom taxonomy. Owners can add a new term here; editors can only pick existing ones.
Search and socialSEO title, SEO description, canonical address, social image and a switch that asks search engines not to list the page. Stored on the entity as meta_title, meta_description, canonical_url, og_image and no_index, the keys the public site reads, and not repeated among the type's own fields.
The type's own fieldsGenerated from the type's JSON Schema: text, long text, numbers, switches, images, lists and so on.

Buttons for adding, moving and removing repeated rows re-render the form without saving. The form's subtitle shows the type and the current version number. Image fields and the social image use the media picker (/admin/media/picker), which opens as a dialog when JavaScript is on. The page, builder and blog editors also refuse a stale save; see the Editor reference.

Versions

Every save creates a version.

AddressWhat it does
/admin/entities/{id}/versionsLists the versions
/admin/entities/{id}/versions/{version}Shows one version
/admin/entities/{id}/versions/compareShows the difference between two versions
/admin/entities/{id}/versions/{version}/restoreAsks for confirmation, then restores that state as a new version

Restoring never deletes history. A nightly job merges identical consecutive versions and prunes old ones, keeping the most recent 20 per entity and dropping automatic autosave versions before explicit ones.

Deleting and archiving

Deleting an entity (/admin/entities/{id}/delete) goes through a confirmation page and removes its version history too. Archive an entity instead to take it off the public site and keep it.

Entity types

Owners manage types under Settings > Entity models > Entity types (/admin/settings/types). A type has a name, a slug, a JSON Schema for its fields and settings for its public addresses.

The field editor builds the schema from rows. You can drag rows to reorder them (a drag only moves the row), group fields under headings and mark fields required. Anything the editor cannot express is kept as a custom row and never lost. Because Postgres does not keep key order in jsonb, the chosen order is stored in a root x-hm-order list, and an optional x-hm-group heading on a field groups it in the form.

SettingMeaning
url_patternThe public address pattern, for example /blog/{slug} or /docs/{path}. A live preview is at /admin/settings/types/preview-pattern. See URL patterns.
archive_path, archive_title, archive_descriptionThe listing page for the type
archive_crumb_labelThe section label in an entry's breadcrumb (falls back to the archive title, then the type name; the BreadcrumbList data uses it)
Sitemap group and JSON-LD typeHow the entries appear in the sitemap and in structured data
EditorForm, or Post editor to edit entries like blog posts. The types post, article, blog_post and blog always use the post editor.

Built-in types are read-only, except person. You can add fields to person and change its settings, but its core fields (job title, short bio, bio, photo, public, public email, website, LinkedIn, X, GitHub, expertise, on team) are locked, and the type cannot be deleted. The server enforces this for the REST API too.

Changing an address pattern keeps old links working. If you change a type's pattern (for example from /author/{slug} to /team/{slug}), Hatamoto writes a 301 redirect from each published entity's old path to the new one. A redirect that already exists at an old path is left alone, a move that would loop is skipped, and an entity that is not public gets none. See Redirect rules.

Taxonomies

Settings > Entity models > Taxonomies (/admin/settings/taxonomies, owners) manages categories, tags and any custom kinds. Each kind is a tab, and its terms are a tree you can nest. Open a term at /admin/settings/taxonomies/terms/{id} to rename it, change its parent, merge it into another term or delete it.

  • A merge moves every entity to the target term and sends the old archive address to the new one with a redirect.
  • Renaming a term or giving it another parent also redirects the archive paths of the term and its children.
  • Editors can assign existing terms from the entity form but cannot create terms there. Owners can.

People

People live at /admin/people, reached from the Entities list. The list shows every person entity with search, a team filter (?team=yes or ?team=no) and sorting. Add person opens a dialog, or /admin/people/new without JavaScript. A person is edited in the ordinary entity form, so fields you add to the person type appear there. A person never opens in the page builder.

FieldMeaning
Name, photo, job title, short bio, linksThe profile
PublicThe person gets a profile page, by default at /author/{slug}, and appears in the sitemap. A person who is not public has neither.
On teamMarks the person as part of the team

In the blog editor's author picker, typing a new name creates a person who is not public and has no login.

Your own profile

/admin/profile edits the person linked to your login: name, photo, job title, short bio, LinkedIn and the Public profile switch. You can also change your password there (at least 12 characters) and sign out on all devices. Until your person has a name and a photo you are sent to /admin/profile/complete after signing in.

Possible duplicates

The Possible duplicates (N) button opens /admin/people/duplicates. Each group has a Merge form (owners and editors) that posts to /admin/people/merge. A merge:

  • credits every post of the dropped person to the kept person, then deletes the dropped person;
  • moves the dropped person's login to the kept person when the kept person has none; two people who both have a login cannot be merged;
  • keeps the kept person's Public and On team choices;
  • fills empty profile fields of the kept person from the dropped one, except when the kept person is public and the dropped one was hidden: then nothing is copied, so a hidden person's details never become public;
  • writes a 301 redirect from the dropped person's profile page to the kept one when both were public.

Upgrading from authors

Older sites had plain authors instead of people. The upgrade migrations create one person for every author, make a person public only if the author had published posts, point posts at their person and link each user to the person with the same name. Nothing is deleted. For what a rollback sees, see Upgrading a self-hosted install.