Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/.vitepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,10 @@ const sidebarPlugins = [
text: "Note",
link: "/plugins/post-types/note",
},
{
text: "Page",
link: "/plugins/post-types/page",
},
{
text: "Photo",
link: "/plugins/post-types/photo",
Expand Down
1 change: 1 addition & 0 deletions docs/plugins/post-types/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ A [post type](../../concepts#post-type) provides an interface for creating and e
- [Audio](audio.md) `@indiekit/post-type-audio`
- [Event](event.md) `@indiekit/post-type-event`
- [Jam](jam.md) `@indiekit/post-type-jam`
- [Page](page.md) `@indiekit/post-type-page`
- [Repost](repost.md) `@indiekit/post-type-repost`
- [RSVP](rsvp.md) `@indiekit/post-type-rsvp`
- [Video](video.md) `@indiekit/post-type-video`
1 change: 1 addition & 0 deletions docs/plugins/post-types/page.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!--@include: ../../../packages/post-type-page/README.md-->
1 change: 1 addition & 0 deletions helpers/frontend/views/frontend-components.njk
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,7 @@
<li>{{- icon("next") -}} next</li>
<li>{{- icon("note") -}} note</li>
<li>{{- icon("offline") -}} offline</li>
<li>{{- icon("page") -}} page</li>
<li>{{- icon("photo") -}} photo</li>
<li>{{- icon("previous") -}} previous</li>
<li>{{- icon("public") -}} public</li>
Expand Down
1 change: 1 addition & 0 deletions indiekit.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const config = {
"@indiekit/post-type-audio",
"@indiekit/post-type-event",
"@indiekit/post-type-jam",
"@indiekit/post-type-page",
"@indiekit/post-type-repost",
"@indiekit/post-type-rsvp",
"@indiekit/post-type-video",
Expand Down
12 changes: 12 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { strict as assert } from "node:assert";
import { after, describe, it } from "node:test";

import { mockAgent } from "@indiekit-test/mock-agent";
import { testServer } from "@indiekit-test/server";
import { testToken } from "@indiekit-test/token";
import supertest from "supertest";

await mockAgent("endpoint-micropub");
const server = await testServer({
plugins: ["@indiekit/post-type-page", "@indiekit/preset-eleventy"],
usePostTypes: false,
});
const request = supertest.agent(server);

describe("endpoint-micropub POST /micropub", () => {
it("Creates page at root URL", async () => {
const result = await request
.post("/micropub")
.auth(testToken(), { type: "bearer" })
.set("accept", "application/json")
.send("h=page")
.send("name=About")
.send("content=All+about+me.");

assert.equal(result.status, 202);
assert.equal(result.headers.location, "https://website.example/about");
});

after(() => server.close());
});
1 change: 1 addition & 0 deletions packages/frontend/lib/globals/icon.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export const icon = (name, title) => {
note: "M12 8h24c2 0 4 2 4 4v24c0 2-2 4-4 4H12c-2 0-4-2-4-4V12c0-2 2-4 4-4zm24-4H12c-4 0-8 4-8 8v24c0 5 4 8 8 8h24c5 0 8-3 8-8V12c0-4-3-8-8-8zM12 14h24v4H12v-4zm0 8h24v4H12v-4zm0 8h18v4H12v-4z",
offline:
"M24 7a32 32 0 1 1-15.8 4.2l3.7 3.7a24.7 24.7 0 0 0-8.4 6.6L0 18v8.6a27 27 0 1 0 48 0V18l-3.5 3.5a27 27 0 0 0-25.1-9.1l-4.2-4.2A32 32 0 0 1 24 7Zm0 51a17 17 0 0 0 15.5-10h5.4A22 22 0 0 1 3 48h5.4A17 17 0 0 0 24 58Zm0-26a5 5 0 1 1 0 10 5 5 0 0 1 0-10Zm16-6-3.5 3.5-1.2-1.2-9.2-9.2a22 22 0 0 1 14 6.9Zm-22.9-6 4.1 4.1a17 17 0 0 0-9.7 5.3L8 26a22 22 0 0 1 9-6ZM2 5l3-3 41 41-3 3L2 5Z",
page: "M12 4h18l3 1 10 10 1 3v18q0 8-8 8H12q-7 0-8-8V12q1-7 8-8m18 4H12q-3 1-4 4v24q1 4 4 4h24q4 0 4-4V18H30zm-18 6h14v4H12zm0 8h24v4H12Zm0 8h24v4H12Z",
photo:
"M36 4H12c-4 0-8 4-8 8v24c0 5 4 8 8 8h24c5 0 8-3 8-8V12c0-4-3-8-8-8zM12 8h24c2 0 4 2 4 4v24c0 2-2 4-4 4H12c-2 0-4-2-4-4V12c0-2 2-4 4-4zm24 24l-9-14-7 11-3-5-5 8h24z",
previous:
Expand Down
29 changes: 29 additions & 0 deletions packages/post-type-page/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# @indiekit/post-type-page

Page post type for Indiekit. A page is an undated post at the root of your website, such as `/about`, `/now` or `/uses`.

## Installation

`npm install @indiekit/post-type-page`

## Usage

Add `@indiekit/post-type-page` to your list of plug-ins, specifying options as required:

```json
{
"plugins": ["@indiekit/post-type-page"],
"@indiekit/post-type-page": {
"name": "Page"
}
}
```

Micropub clients create a page by sending `h=page`. Presets write a page to the root of your content, where your static site generator serves it at `/{slug}`.

## Options

| Option | Type | Description |
| :------- | :------- | :-------------------------------- |
| `name` | `string` | Post type name. |
| `fields` | `Array` | Fields to show in post interface. |
4 changes: 4 additions & 0 deletions packages/post-type-page/assets/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
31 changes: 31 additions & 0 deletions packages/post-type-page/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const defaults = {
name: "Page",
fields: {
name: { required: true },
content: { required: true },
summary: {},
category: {},
"post-status": {},
visibility: {},
},
};

export default class PagePostType {
name = "Page post type";

constructor(options = {}) {
this.options = { ...defaults, ...options };
}

get config() {
return {
name: this.options.name,
h: "page",
fields: this.options.fields,
};
}

init(Indiekit) {
Indiekit.addPostType("page", this);
}
}
38 changes: 38 additions & 0 deletions packages/post-type-page/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@indiekit/post-type-page",
"version": "1.0.0-beta.28",
"description": "Page post type for Indiekit",
"keywords": [
"indiekit",
"indiekit-plugin",
"indieweb",
"post-type",
"page"
],
"homepage": "https://getindiekit.com",
"author": {
"name": "Paul Robert Lloyd",
"url": "https://paulrobertlloyd.com"
},
"license": "MIT",
"engines": {
"node": ">=24.17"
},
"type": "module",
"main": "index.js",
"files": [
"assets",
"index.js"
],
"bugs": {
"url": "https://github.com/getindiekit/indiekit/issues"
},
"repository": {
"type": "git",
"url": "https://github.com/getindiekit/indiekit.git",
"directory": "packages/post-type-page"
},
"publishConfig": {
"access": "public"
}
}
6 changes: 6 additions & 0 deletions packages/post-type-photo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@
"name": "Paul Robert Lloyd",
"url": "https://paulrobertlloyd.com"
},
"contributors": [
{
"name": "Ricardo Mendes",
"url": "https://rmendes.net/"
}
],
"license": "MIT",
"engines": {
"node": ">=24.17"
Expand Down
15 changes: 15 additions & 0 deletions packages/preset-eleventy/lib/post-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ import plur from "plur";
*/
export const getPostTypes = (postTypes) => {
for (const type of postTypes.keys()) {
// A page has no date and lives at the root, where Eleventy serves it
if (type === "page") {
postTypes.set(type, {
...postTypes.get(type),
post: {
path: "{slug}.md",
url: "{slug}",
},
media: {
path: "media/pages/{filename}",
},
});
continue;
}

const collection = plur(type);

postTypes.set(type, {
Expand Down
11 changes: 11 additions & 0 deletions packages/preset-eleventy/test/unit/post-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const postTypes = new Map([
["article", { name: "Journal post" }],
["note", { name: "Micro post" }],
["puppy", { name: "Puppy post" }],
["page", { name: "Page" }],
]);

describe("preset-eleventy/lib/post-types", () => {
Expand Down Expand Up @@ -43,5 +44,15 @@ describe("preset-eleventy/lib/post-types", () => {
path: "media/puppies/{yyyy}/{MM}/{dd}/{filename}",
},
});
assert.deepEqual(result.get("page"), {
name: "Page",
post: {
path: "{slug}.md",
url: "{slug}",
},
media: {
path: "media/pages/{filename}",
},
});
});
});
16 changes: 16 additions & 0 deletions packages/preset-hugo/lib/post-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,22 @@ import plur from "plur";
*/
export const getPostTypes = (postTypes) => {
for (const type of postTypes.keys()) {
// A page has no date and lives at the root of the content directory
if (type === "page") {
postTypes.set(type, {
...postTypes.get(type),
post: {
path: "content/{slug}.md",
url: "{slug}",
},
media: {
path: "static/pages/{filename}",
url: "pages/{filename}",
},
});
continue;
}

const section = plur(type);

/**
Expand Down
12 changes: 12 additions & 0 deletions packages/preset-hugo/test/unit/post-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const postTypes = new Map([
["article", { name: "Journal post" }],
["note", { name: "Micro post" }],
["puppy", { name: "Puppy post" }],
["page", { name: "Page" }],
]);

describe("preset-hugo/lib/post-types", () => {
Expand Down Expand Up @@ -46,5 +47,16 @@ describe("preset-hugo/lib/post-types", () => {
url: "puppies/{filename}",
},
});
assert.deepEqual(result.get("page"), {
name: "Page",
post: {
path: "content/{slug}.md",
url: "{slug}",
},
media: {
path: "static/pages/{filename}",
url: "pages/{filename}",
},
});
});
});
15 changes: 14 additions & 1 deletion packages/preset-jekyll/lib/post-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,20 @@ export const getPostTypes = (postTypes) => {
for (const type of postTypes.keys()) {
const collection = plur(type);

if (type === "article") {
if (type === "page") {
// A page has no date; an index file in its own directory is served at
// its URL without a permalink setting
updates.set("page", {
...postTypes.get("page"),
post: {
path: "{slug}/index.md",
url: "{slug}",
},
media: {
path: "media/pages/{filename}",
},
});
} else if (type === "article") {
updates.set("article", {
...postTypes.get("article"),
post: {
Expand Down
11 changes: 11 additions & 0 deletions packages/preset-jekyll/test/unit/post-types.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const postTypes = new Map([
["article", { name: "Journal post" }],
["note", { name: "Micro post" }],
["puppy", { name: "Puppy post" }],
["page", { name: "Page" }],
]);

describe("preset-jekyll/lib/post-types", () => {
Expand Down Expand Up @@ -43,5 +44,15 @@ describe("preset-jekyll/lib/post-types", () => {
path: "media/puppies/{yyyy}/{MM}/{dd}/{filename}",
},
});
assert.deepEqual(result.get("page"), {
name: "Page",
post: {
path: "{slug}/index.md",
url: "{slug}",
},
media: {
path: "media/pages/{filename}",
},
});
});
});
Loading