Repository navigation
Give each content type a preview URL that the preview token fills in - #3130
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #3099
A new core settings area,
preview, holds an absolutehttporhttpsURL template for each content type. It is set per site with instance defaults, for examplehttps://www.example.com/{locale}/articles/{slug}?preview={token}.POST .../preview-tokennow also answersurlandpublishedUrl.urlis the template filled with the draft's values and the new token.publishedUrlis the same template, without the token's parameter, filled from the published row of the locale that gave the draft. Both are null when the type has no template. Saving a template that is not an absolute http(s) URL, or that names a type or field the schema does not have, is refused. Spec 4.7, 4.10 and 4.13, the admin draft (4.12 and AQ15), the host configuration page and the OpenAPI document describe what was built.Dependencies
None.
Decisions
publishedUrl, not a{status}placeholder (AQ15, now settled in the admin draft). The published page takes no token, and the admin cannot fill a template itself because it does not read the area. So a{status}placeholder would still need a second answer.{locale}is the site's code (en, never theENa request may send) of the locale whose row gave the draft. That is the token's locale, or, for a token without a locale, the first locale of the request's chain in which the entry has a row, which is how a read by id is served.publishedUrlis filled from that locale's published row only, read with no fallback, so it is null when that locale was never published. An entry with only English rows, read in French, gets its English pages.{token}is required, once, as the whole value of one query parameter (name={token}). Because of that, the published URL can drop the parameter cleanly, and the token never sits in the path or the host. A front end whose preview goes through a separate route would need a second template. That is left for later, and adding it breaks nothing.httporhttps. The host and port have no placeholder and no user info. The path does not start with//, which a front end that re-emits the path as a relative redirect would read as another host. Each%in the template must start a complete escape (two hex digits), so%{slug}and.%{slug}are refused and no value can complete an escape. A template holds only URL characters (no spaces, no backslash) and is at most 2,048 characters. Each value is escaped withUri.EscapeDataString.{id},{locale}(localized types only),{token}, and a field of the type that holds one value: a core text, slug, select, email, url, integer, decimal, boolean, date or dateTime field that is not hidden and not multiple. Plugin field types, relations, rich text, components, blocks and JSON are refused.{token}always means the token, even if the type has a field namedtoken..or...ISettingsCheckruns inSettingsServiceon write and on import, including a dry run, after the class's own attributes.PreviewSettingsCheckchecks the templates against the schema. Codes:FCMS3031for a template that is not a valid URL or puts{token}in the wrong place, andFCMS3032for an unknown type, field or placeholder. Both are 422 on the pathtemplates.{type}, and both are the next free codes in the preview-token block.PreviewSettingsis internal to core. It is listed byGET /settingswithplugin: null, and reading or writing it needssettings.preview.manage. Minting reads the area throughISettings<T>, so an editor who may mint gets the URL.PublicAPI, migration, role seeding or log event id changes.Acceptance
article, thepreview-tokenanswer holds the URL with the entry's values and the token, escapedurl: nullhttporhttpsURL, or that names a field the type does not have, is refusedTests
PreviewUrlTemplateTests(new, unit): escaping, no value can change the origin or add a segment, the template's own escapes are kept, the published URL drops the token's parameter, scalar formats, null for missing, empty, dot-only or non-scalar values, every refused form (FCMS3031, including%{slug},.%{slug},%zzand a path starting with//), every refused placeholder (FCMS3032), and the area check for unknown types.PreviewUrlTests(new, integration on SQLite):ENfilled asen, a French read served by English rows giving the English pages, and a French draft whosepublishedUrlstays null until French is published;url: nullwith no template and for a type that has none, and a site template that replaces the defaults;previewlisted inGET /settings;TransferTests.ASettingsDocumentThatTheChecksOfItsAreaRefuseIsReportedByADryRun(data): a dry-run import of a badpreviewdocument reports the item asFCMS3031and writes nothing.OpenApiDocumentTests.ThePreviewTokenRouteHasItsBodiescovers the two new properties.dotnet build -c Release -warnaserror, the SDK, core and architecture tests, the new and changed classes,PreviewTokenTests,PreviewTokenTargetTests, the settings, site and transfer endpoint tests, the dataSettingsTestsandTransferTestson SQLite,PluginContributionTests, and markdownlint.