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
- Templating — server-side rendering used during templated creation
- Authorization Rules — control who can create resources
- Resource Binding — bind site-wide queries for use in templates