Resource Creation

Pagelove provides two modes for creating new resources using standard HTTP semantics: direct creation via PUT to a known name, and templated creation via POST to a template resource.

When to reach for it

Use PUT when the client knows the final resource name and can supply the full representation. Use POST to a template when the final name or content must be determined by server-side logic.

Mode comparison

Aspect PUT POST + Template
Final resource name Known by client Determined by template (<base>)
Server-side logic None Full templating system
Authorization checks 1 (PUT) 2 (POST to template, PUT to final location)
Client receives Standard PUT response 301 redirect to new resource
Typical use Uploading files, programmatic creation Blog posts, CMS entries, user-generated content

Direct creation (PUT)

The client sends an HTTP PUT request to the desired resource path:

PUT /new-blog-post.html

The request body contains the full representation (HTML, image, etc.). The server verifies that the actor is authorized to PUT at the provided path using AuthorizationRule declarations.

Standard HTTP semantics apply (ETag, conditional requests, content negotiation).

Templated creation (POST)

Templated creation follows a multi-step pipeline:

1. POST to template

The client sends a POST to a template resource:

POST /templates/new-post.html

The request body, query parameters, and other request metadata are available to the template execution context.

2. Template authorization

The server verifies POST authorization on the template resource using AuthorizationRule. If this check fails, the request is rejected before any templating occurs.

3. Template processing

The template is processed using the Pagelove templating system. It can incorporate request body parameters, query parameters, headers, and actor identity. The output is a complete HTML document.

4. Final location via <base>

The generated document must contain an HTML <base> element with an href attribute:

<base href="/posts/hello-world.html">

Pagelove interprets this value as the canonical storage location of the new resource. This aligns with the standard semantics of <base>, which defines the base URL for resolving relative URLs.

5. Final location authorization

The server verifies that the actor is authorized to PUT at the <base> href. This is a separate check from the initial POST authorization. If it fails, no resource is written.

6. Persistence and redirect

The generated document is written to the content store at the path specified by base.href. The server responds with:

301 Moved Permanently
Location: 

Error cases

Condition Result
POST to the template is not authorized Rejected before templating runs, per AuthorizationRule.
Templated output has no <base> element, an empty href, or no href attribute at all 422 Unprocessable Entity — "Template must include a <base href> element specifying the target resource path".
The actor is not authorized to PUT at the resolved <base href> Rejected; no resource is written.
The request body cannot be fully read (the connection is interrupted mid-upload) 400 Bad Request; no resource is written. A partially-received body is never composed and stored, so a dropped connection returns an error you can retry rather than silently publishing a truncated document.

Examples

Templated creation via POST

Store a template resource that uses the request body to build the new document and determines its location via <base>:

{% example "setup-template", "body" %}

POST form data to the template. The server creates the resource and responds with a redirect:

POST /sspi-rc-templates/new-entry.html
Content-Type: application/x-www-form-urlencoded

slug=hello-world&title=Hello+World&content=First+post
HTTP/1.1 301
Location: /sspi-rc-entries/hello-world.html

See also