Skip to content

Commit

Permalink
Simplify relation and linking between pages (#377)
Browse files Browse the repository at this point in the history
  • Loading branch information
ia3andy authored Jan 17, 2025
1 parent 6143d2c commit ee97f35
Show file tree
Hide file tree
Showing 13 changed files with 118 additions and 29 deletions.
15 changes: 12 additions & 3 deletions blog/content/docs/advanced.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -318,14 +318,14 @@ The pages links are automatically converted to urls by Roq, they are available i
<a href="{site.url}">Back to main page</a>
----

or
or to get the next page url in a document:

[source,html]
----
<a href="{page.nextPage.url}">{page.nextPage.title}</a>
<a href="{page.next.url}">{page.next.title}</a>
----

or
or when iterating on documents:

[source,html]
----
Expand All @@ -334,6 +334,15 @@ or
{/for}
----

or also to manually retrieve a page url with `site.page(sourcePath)`:

[source,html]
----
<a href="{site.page('foo.html').url}">{site.page('foo.html').title}</a>
----



TIP: By default, url will be rendered as relative from the site root. You can also get the full absolute url (i.e. from `http(s)://`) by using `absolute` on any url (e.g. `{site.url.absolute}`).

=== Manual linking
Expand Down
40 changes: 33 additions & 7 deletions blog/content/docs/basics.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -149,13 +149,29 @@ You can use Qute to access site and pages data. For this use the `site` and `pag
| `site.image`
| `RoqUrl`
| The site image URL if present
| The cover image URL of the page with disk check
| `http://example.com/static/images/site.png`
| `site.url(Object path, Object... others)`
| `site.image(String relativePath)`
| `RoqUrl`
| The image from the public images directory with disk check
| `site.image('foo.jpg') => http://example.com/images/foo.jpg`
| `site.file(String relativePath)`
| `RoqUrl`
| The file from the public directory with disk check
| `site.file('foo.pdf') => http://example.com/foo.pdf`
| `site.url(String path, String... others)`
| `RoqUrl`
| Shortcut for site.url.resolve(path)
| `site.url.resolve("/about") => http://example.com/my-roq-site/about`
| `site.url("/about") => http://example.com/my-roq-site/about`
| `site.page(String sourcePath)`
| `Page`
| Get a page or document page by source path (e.g. pages/first-page.html)
| `site.page('foo.html').url.absolute => http://example.com/the-foo-page`
|===
====

Expand Down Expand Up @@ -203,12 +219,22 @@ You can use Qute to access site and pages data. For this use the `site` and `pag
| The description of the page (shortcut from FM)
| `This is the about us page.`
| `page.image()`
| `page.image`
| `RoqUrl`
| The cover image URL of the page (with disk check)
| The cover image URL of the page with disk check
| `http://example.com/static/images/about.png`
| `page.date()`
| `page.image(String relativePath)`
| `RoqUrl`
| The image from the attached files (for index pages) or from the public image directory with disk check (for other pages)
| `page.image('foo.jpg') => http://example.com/foo-page/foo.jpg`
| `site.file(String relativePath)`
| `RoqUrl`
| The file from the attached files with disk check
| `page.file('foo.pdf') => http://example.com/foo-page/foo.pdf`
| `page.date`
| `ZonedDateTime`
| The publication date of the page
| `2023-10-01T12:00:00Z`
Expand Down Expand Up @@ -431,7 +457,7 @@ The resulting link for a page can be different from its directory name, attached

Let's imagine for a minute that the page link is `https://my-site.org/awesome-page/`, then the slide will be served on `https://my-site.org/awesome-page/slide.pdf`.

You can use `{page.file("slide.pdf")}` to resolve the file url *and check that the file exists*. This is useful from another page or if you want the absolute url (i.e. `{page.file("slide.pdf").absolute}`):
You can use `{page.file("slide.pdf")}` to resolve the file url *and check that the file exists*. This is also useful in other cases, for example from another page (e.g. `{site.page("my-page/index.md").file("slide.pdf")}`) or if you want the absolute url (e.g. `{page.file("slide.pdf").absolute}`):

TIP: If you want to iterate over page files, they can be listed using `{page.files}`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ void publishTagPages(
Map.of(":tag", e::getKey));
final RoqUrl url = rootUrl.rootUrl().resolve(link);

PageInfo info = item.raw().info().changeId(tagCollection);
PageInfo info = item.raw().info().changeId(tagCollection + "." + item.raw().info().sourceFileExtension());

// Dealing with pagination is as simple as those two lines:
if (data.containsKey(PAGINATE_KEY)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import io.quarkiverse.roq.frontmatter.runtime.model.Paginator;
import io.quarkiverse.roq.frontmatter.runtime.model.RootUrl;
import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl;
import io.quarkiverse.roq.util.PathUtils;
import io.quarkus.deployment.annotations.BuildProducer;
import io.quarkus.deployment.annotations.BuildStep;
import io.quarkus.runtime.configuration.ConfigurationException;
Expand Down Expand Up @@ -92,7 +93,8 @@ public void paginatePublish(RoqSiteConfig config,
}
PageInfo info = pagination.info();
if (i > 1) {
info = info.changeId(paginatedUrl.path());
info = info.changeId(
PathUtils.removeExtension(info.sourceFilePath()) + "_p" + i + "." + info.sourceFileExtension());
}
paginatedPages.add(new PageToPublish(paginatedUrl, info, data));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,7 @@ private static Consumer<Path> addBuildItem(
String quteTemplatePath = ROQ_GENERATED_QUTE_PREFIX + removeExtension(normalizedPath)
+ resolveOutputExtension(markups, normalizedPath);
boolean published = type.isPage();
String id = type.isPage() ? normalizedPath : removeExtension(normalizedPath);
String id = type.isPage() ? sourcePath : removeExtension(sourcePath);
final boolean isHtml = isPageTargetHtml(file);
var isIndex = isHtml && "index".equals(PathUtils.removeExtension(PathUtils.fileName(sourcePath)));
var isSiteIndex = isHtml && id.startsWith("index.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class TemplateLinkTest {
@Test
void testLink() {
JsonObject frontMatter = new JsonObject().put("title", "My First Blog Post");
final PageInfo pageInfo = createPageInfo("_posts/my-first-blog-post.md", "_posts/my-first-blog-post.md", true, true);
final PageInfo pageInfo = createPageInfo("posts/my-first-blog-post.md", "posts/my-first-blog-post.md", true, true);

String generatedLink = pageLink("/", ":year/:month/:day/:slug", new PageLinkData(pageInfo, null, frontMatter));
assertEquals("2024/08/27/my-first-blog-post/", generatedLink);
Expand All @@ -25,7 +25,7 @@ void testLink() {
@Test
void testLinkExt() {
JsonObject frontMatter = new JsonObject().put("title", "My First Blog Post");
final PageInfo pageInfo = createPageInfo("posts/my-first-blog-post.md", "_posts/my-first-blog-post.md", true, true);
final PageInfo pageInfo = createPageInfo("posts/my-first-blog-post.md", "posts/my-first-blog-post.md", true, true);

String generatedLink = pageLink("/", ":year/:month/:day/:slug:ext!", new PageLinkData(pageInfo, null, frontMatter));
assertEquals("2024/08/27/my-first-blog-post.html", generatedLink);
Expand All @@ -46,7 +46,7 @@ void testLinkJson() {
@Test
void testPaginateLink() {
JsonObject frontMatter = new JsonObject().put("title", "My First Blog Post");
final PageInfo pageInfo = createPageInfo("posts/my-first-blog-post.html", "_posts/my-first-blog-post.md", true, true);
final PageInfo pageInfo = createPageInfo("posts/my-first-blog-post.html", "posts/my-first-blog-post.md", true, true);

String generatedLink = paginateLink("/", null, new PaginateLinkData(pageInfo, "posts", "3", frontMatter));
assertEquals("posts/page3/", generatedLink);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,27 @@ public DocumentPage nextPage() {
return collection().nextPage(this);
}

/**
* Resolve the next document page in the collection or null if none
*/
public DocumentPage next() {
return nextPage();
}

/**
* Resolve the previous document page in the collection or null if none
*/
public DocumentPage previous() {
return previousPage();
}

/**
* Resolve the previous document page in the collection or null if none
*/
public DocumentPage prev() {
return previousPage();
}

/**
* Resolve the previous document page in the collection or null if none
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public interface Page {
PageInfo info();

/**
* The page unique id, it is either the source file name (e.g. _posts/my-post.md or a generated id for dynamic pages).
* The page unique identifier, it is either the source file relative path (e.g. posts/my-post.md or a generated source path
* for dynamic pages).
*/
default String id() {
return info().id();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
@Vetoed
public record PageInfo(
/**
* The page unique id, it is either the source file name (e.g. _posts/my-favorite-beer.md or a generated id for dynamic
* pages).
* The page unique identifier, it is either the source file relative path (e.g. posts/my-post.md or a generated source
* path for dynamic pages).
*/
String id,

Expand All @@ -35,7 +35,7 @@ public record PageInfo(
String rawContent,

/**
* The path of the source file (e.g _posts/my-favorite-beer.md)
* The path of the source file (e.g posts/my-favorite-beer.md)
*/
String sourceFilePath,

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,23 +146,36 @@ public RoqUrl url(Object path, Object path1, Object path2) {
}

/**
* Find a page by id
* Find a page or document page by source path
*
* @param id the page id (e.g. pages/first-page.html)
* @param sourcePath the page source path (e.g. pages/first-page.html) or the generated source path for generated pages (e.g
* /index_p2.html).
* @return the page or null
*/
public NormalPage page(String id) {
return pagesById.get().get(id);
public Page page(String sourcePath) {
return pagesById.get().containsKey(sourcePath) ? pagesById.get().get(sourcePath) : documentsById.get().get(sourcePath);
}

/**
* Find a document by id
* Find a normal page (documents not included) by source path
*
* @param id the document page id (e.g. _posts/first-post)
* @param sourcePath the page source path (e.g. pages/first-page.html) or the generated source path for generated pages (e.g
* /index_p2.html).
* @return the page or null
*/
public NormalPage normalPage(String sourcePath) {
return pagesById.get().get(sourcePath);
}

/**
* Find a document by sourcePath
*
* @param sourcePath the document source path (e.g. pages/first-page.html) or the generated source path for generated
* documents.
* @return the document page or null
*/
public DocumentPage document(String id) {
return documentsById.get().get(id);
public DocumentPage document(String sourcePath) {
return documentsById.get().get(sourcePath);
}

public RoqUrl url() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@

Here are the links: {page.file('hello.pdf')} and {page.file('./hello.pdf')}

and an images: {site.image('hello.png')} and {page.image('hello-page.png')} and {page.image('./hello-page.png')};
and an images: {site.image('hello.png')} and {page.image('hello-page.png')} and {page.image('./hello-page.png')}

page by path: {site.page('élo [email protected]').url}
document by path: {site.document('posts/markdown-post-k8s.md').url}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{site.page('élo you.html').url}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,19 @@ public void testMdPost() {
.body(containsString("Legacy: /static/assets/images/legacy.png"));
}

@Test
public void testPageDir() {
RestAssured.when().get("/posts/2010-08-05-hello-world").then().statusCode(200).log().ifValidationFails()
.body("html.head.title", equalTo("posts/2010-08-05-hello-world/index.md - Hello, world! I'm Roq"))
.body(containsString("<h1 class=\"page-title\">posts/2010-08-05-hello-world/index.md"))
.body(containsString(
"Here are the links: /posts/2010-08-05-hello-world/hello.pdf and /posts/2010-08-05-hello-world/hello.pdf"))
.body(containsString(
"and an images: /images/hello.png and /posts/2010-08-05-hello-world/hello-page.png and /posts/2010-08-05-hello-world/hello-page.png"))
.body(containsString("page by path: /lo-you/"))
.body(containsString("document by path: /posts/k8s-post/"));
}

@Test
public void testCodestartPost() {
RestAssured.when().get("/posts/the-first-roq").then().statusCode(200).log().ifValidationFails()
Expand Down

0 comments on commit ee97f35

Please sign in to comment.