Add /sitemap endpoint for generating sitemap.xml
Summary: Ref T3045 Reviewers: #testers, kuba-orlik Reviewed By: #testers, kuba-orlik Subscribers: kuba-orlik, jenkins-user Maniphest Tasks: T3045 Differential Revision: https://hub.sealcode.org/D1616
This commit is contained in:
parent
30c6a2f881
commit
7864f5c3cf
@ -8,6 +8,7 @@ import { imageRouter, RESPONSIVE_IMAGES_URL_PATH } from "../image-router.js";
|
||||
import { customUrlView } from "./middlewares/customUrlView.js";
|
||||
import mountAutoRoutes from "./routes.js";
|
||||
import _locreq from "locreq";
|
||||
import sitemapPage from "../sitemap.xml.js";
|
||||
const locreq = _locreq(new URL("./", import.meta.url).pathname);
|
||||
|
||||
export const mainRouter = (app: TheApp, koa_app: Koa, router: Router): void => {
|
||||
@ -41,6 +42,11 @@ export const mainRouter = (app: TheApp, koa_app: Koa, router: Router): void => {
|
||||
ctx.body = { status: ctx.$app.status, started_at };
|
||||
});
|
||||
|
||||
router.get("/sitemap.xml", async (ctx) => {
|
||||
ctx.set("Content-Type", "application/xml");
|
||||
ctx.body = await sitemapPage.render(ctx);
|
||||
});
|
||||
|
||||
router.use(RESPONSIVE_IMAGES_URL_PATH, imageRouter.getRoutes());
|
||||
|
||||
mountAutoRoutes(router);
|
||||
|
||||
29
src/back/sitemap.xml.tsx
Normal file
29
src/back/sitemap.xml.tsx
Normal file
@ -0,0 +1,29 @@
|
||||
import type { Context } from "koa";
|
||||
import { Page } from "@sealcode/sealgen";
|
||||
|
||||
export const actionName = "Sitemap";
|
||||
|
||||
async function generateSitemap(ctx: Context) {
|
||||
const pages = await ctx.$app.collections.pages.list(ctx.$context).fetch();
|
||||
|
||||
let xml = `<?xml version="1.0" encoding="UTF-8"?>\n`;
|
||||
xml += `<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">\n`;
|
||||
|
||||
for (const page of pages.items) {
|
||||
xml += ` <url>\n <loc>${ctx.origin.replace(/\/$/, "")}${page.get("url")}</loc>\n </url>\n`;
|
||||
}
|
||||
|
||||
xml += `</urlset>\n`;
|
||||
return xml;
|
||||
}
|
||||
|
||||
export default new (class SitemapPage extends Page {
|
||||
async canAccess() {
|
||||
return { canAccess: true, message: "" };
|
||||
}
|
||||
|
||||
async render(ctx: Context) {
|
||||
ctx.set("Content-Type", "application/xml");
|
||||
return generateSitemap(ctx);
|
||||
}
|
||||
})();
|
||||
54
tests/sitemap.test.ts
Normal file
54
tests/sitemap.test.ts
Normal file
@ -0,0 +1,54 @@
|
||||
import * as assert from "node:assert";
|
||||
import { test, expect } from "./backend-fixture";
|
||||
|
||||
test("sitemap returns expected XML for empty DB", async ({ backend, request }) => {
|
||||
const response = await request.get(`${backend.url}/sitemap.xml`);
|
||||
assert.strictEqual(response.status(), 200);
|
||||
|
||||
const actual = await response.text();
|
||||
const expected = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>${backend.url}/</loc>
|
||||
</url>
|
||||
</urlset>
|
||||
`;
|
||||
assert.strictEqual(actual, expected);
|
||||
});
|
||||
|
||||
test("sitemap returns expected XML after creating a page via UI", async ({
|
||||
page,
|
||||
backend,
|
||||
request,
|
||||
}) => {
|
||||
await page.goto(backend.url);
|
||||
await page.getByRole("link", { name: "Go to Admin" }).click();
|
||||
await page.getByPlaceholder("text").fill("admin");
|
||||
await page.getByPlaceholder("text").press("Tab");
|
||||
await page.getByPlaceholder("password").fill("adminadmin");
|
||||
await page.getByRole("button", { name: "Wyślij" }).click();
|
||||
|
||||
await page.getByRole("link", { name: "Edit Pages" }).click();
|
||||
await page.getByRole("link", { name: "Create" }).click();
|
||||
await page.getByLabel("url").fill("/my-page/");
|
||||
await page.getByLabel("title").fill("My Page");
|
||||
await page.getByLabel("heading").fill("My Heading");
|
||||
await page.getByLabel("description").fill("My Description");
|
||||
await page.getByRole("button", { name: "Wyślij" }).click();
|
||||
|
||||
const response = await request.get(`${backend.url}/sitemap.xml`);
|
||||
assert.strictEqual(response.status(), 200);
|
||||
|
||||
const actual = await response.text();
|
||||
const expected = `<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>${backend.url}/</loc>
|
||||
</url>
|
||||
<url>
|
||||
<loc>${backend.url}/my-page/</loc>
|
||||
</url>
|
||||
</urlset>
|
||||
`;
|
||||
assert.strictEqual(actual, expected);
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user