├── .all-contributorsrc ├── .github ├── CODEOWNERS ├── dependabot.yml ├── project.yml └── workflows │ ├── build-pr-preview.yml │ ├── build.yml │ ├── deploy-blog.yml │ ├── pre-release.yml │ ├── preview-pr-teardown.yml │ ├── preview-pr.yml │ ├── quarkus-snapshot.yml │ ├── release-perform.yml │ └── release-prepare.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── action.yml ├── blog ├── .gitignore ├── config │ └── application.properties ├── content │ ├── 404.html │ ├── about.md │ ├── docs │ │ ├── advanced.adoc │ │ ├── basics.adoc │ │ ├── getting-started │ │ │ ├── index.adoc │ │ │ └── roq-how-it-works.png │ │ ├── plugins.adoc │ │ └── publishing.adoc │ ├── events.html │ ├── index.html │ ├── posts │ │ ├── 2024-08-29-welcome-to-roq.1.md │ │ ├── 2024-09-16-nice-url-experience.md │ │ ├── 2024-09-19-drafts-and-future.md │ │ ├── 2024-09-20-hightlight-js.md │ │ ├── 2024-09-20-pagination.md │ │ ├── 2024-09-23-seo.md │ │ ├── 2024-10-08-tagging.md │ │ ├── 2024-10-09-aliases.md │ │ ├── 2024-10-10-rss-feed.md │ │ ├── 2024-10-22-asciidoc.adoc │ │ ├── 2024-10-31-roq-with-blogs │ │ │ ├── generator-runtime-discussion.png │ │ │ └── index.md │ │ ├── 2024-11-14-qrcode.md │ │ ├── 2024-12-06-series │ │ │ ├── index.adoc │ │ │ └── series.foo.png │ │ ├── 2024-12-10-happy-users.md │ │ ├── 2024-12-26-page-files │ │ │ ├── dina-badamshina-j7vbBmTHmjY-unsplash.jpg │ │ │ ├── index.md │ │ │ └── sample.pdf │ │ ├── 2025-01-08-sitemap.md │ │ ├── 2025-01-28-roq-and-roll-test │ │ │ ├── c'est de la poussière d'étoile.jpg │ │ │ └── index.md │ │ ├── 2025-02-27-feature-comparison │ │ │ └── index.md │ │ ├── 2025-03-24-updating-roq │ │ │ └── index.md │ │ └── 2025-04-04-lunr │ │ │ ├── index.adoc │ │ │ └── search.png │ ├── roqers.md │ ├── rss.xml │ ├── search-index.json │ └── sitemap.xml ├── data │ ├── authors.yml │ ├── events.yml │ └── menu.yml ├── pom.xml ├── public │ ├── googlefb811abf43ab0eb2.html │ └── images │ │ ├── iamroq.png │ │ ├── ico.png │ │ ├── roq-icon.png │ │ ├── roq-icon.svg │ │ ├── site-icon.svg │ │ └── tagging.png ├── src │ ├── main │ │ ├── asciidoc-templates │ │ │ └── document.html.slim │ │ ├── java │ │ │ └── Events.java │ │ └── resources │ │ │ ├── messages │ │ │ └── roq_theme_en.properties │ │ │ └── web │ │ │ └── app │ │ │ ├── app.scss │ │ │ ├── asciidoc-vars.scss │ │ │ ├── asciidoctor-layout.scss │ │ │ ├── asciidoctor.scss │ │ │ └── main.js │ └── test │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── roq │ │ └── it │ │ ├── RoqBlogSlugifiedFilesTest.java │ │ └── RoqBlogTest.java └── templates │ ├── doc │ ├── quarkus-roq-data.adoc │ ├── quarkus-roq-data_quarkus.roq.adoc │ ├── quarkus-roq-frontmatter.adoc │ ├── quarkus-roq-frontmatter_site.adoc │ ├── quarkus-roq-generator.adoc │ ├── quarkus-roq-generator_quarkus.roq.adoc │ ├── quarkus-roq-plugin-asciidoc-jruby.adoc │ ├── quarkus-roq-plugin-asciidoc-jruby_quarkus.qute.adoc │ ├── quarkus-roq-plugin-asciidoctorj.adoc │ ├── quarkus-roq-plugin-asciidoctorj_quarkus.qute.adoc │ ├── quarkus-roq.adoc │ └── quarkus-roq_quarkus.roq.adoc │ ├── layouts │ ├── doc.html │ └── roq-default │ │ ├── default.html │ │ ├── main.html │ │ └── post.html │ └── partials │ ├── doc │ ├── directory-structure.adoc │ ├── doc-attributes.adoc │ ├── edit-contrib.adoc │ └── start-roq.adoc │ ├── getting-started-frontmatter.adoc │ ├── github-pages.adoc │ └── roq-default │ └── sidebar-copyright.html ├── docs ├── antora.yml ├── modules │ └── ROOT │ │ ├── assets │ │ └── images │ │ │ ├── roq-dirs.png │ │ │ ├── roq-how-it-works.png │ │ │ └── roq.svg │ │ ├── examples │ │ └── .keepme │ │ ├── nav.adoc │ │ └── pages │ │ ├── _includes │ │ ├── attributes.adoc │ │ ├── quarkus-roq-data.adoc │ │ ├── quarkus-roq-data_quarkus.roq.adoc │ │ ├── quarkus-roq-frontmatter.adoc │ │ ├── quarkus-roq-frontmatter_quarkus.adoc │ │ ├── quarkus-roq-frontmatter_quarkus.roq.adoc │ │ ├── quarkus-roq-frontmatter_roq.site.adoc │ │ ├── quarkus-roq-frontmatter_site.adoc │ │ ├── quarkus-roq-generator.adoc │ │ ├── quarkus-roq-generator_quarkus.roq.adoc │ │ ├── quarkus-roq-plugin-asciidoc-jruby.adoc │ │ ├── quarkus-roq-plugin-asciidoc-jruby_quarkus.asciidoctorj.adoc │ │ ├── quarkus-roq-plugin-asciidoctorj.adoc │ │ ├── quarkus-roq-plugin-asciidoctorj_quarkus.qute.adoc │ │ ├── quarkus-roq-plugin-tagging.adoc │ │ ├── quarkus-roq-plugin-tagging_quarkus.roq.adoc │ │ ├── quarkus-roq.adoc │ │ └── quarkus-roq_quarkus.roq.adoc │ │ ├── index.adoc │ │ ├── quarkus-roq-data.adoc │ │ ├── quarkus-roq-frontmatter.adoc │ │ └── quarkus-roq-generator.adoc ├── pom.xml └── templates │ └── includes │ └── attributes.adoc ├── jbang-catalog.json ├── logo ├── .gitignore ├── out │ ├── crafted-by-roq-transparent-reversed.svg │ ├── crafted-by-roq-transparent.svg │ ├── iamroq-transparent.svg │ ├── ico.png │ ├── roq-icon-100.png │ ├── roq-icon-circle.svg │ ├── roq-icon-transparent-reversed.svg │ ├── roq-icon-transparent.svg │ ├── roq-icon.png │ ├── roq-icon.svg │ ├── roq-logo-reversed.png │ └── you-roq.svg ├── roq-icon.afdesign └── roq.afdesign ├── pom.xml ├── roq-common ├── deployment │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── roq │ │ └── deployment │ │ ├── RoqJacksonProcessor.java │ │ ├── RoqProjectProcessor.java │ │ ├── config │ │ ├── RoqConfig.java │ │ └── RoqJacksonConfig.java │ │ └── items │ │ ├── RoqJacksonBuildItem.java │ │ └── RoqProjectBuildItem.java ├── pom.xml └── runtime │ ├── pom.xml │ └── src │ └── main │ └── java │ └── io │ └── quarkiverse │ └── roq │ └── util │ └── PathUtils.java ├── roq-data ├── deployment │ ├── pom.xml │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── roq │ │ │ │ └── data │ │ │ │ └── deployment │ │ │ │ ├── DataConverter.java │ │ │ │ ├── RoqDataBeanProcessor.java │ │ │ │ ├── RoqDataConfig.java │ │ │ │ ├── RoqDataConverterProcessor.java │ │ │ │ ├── RoqDataReaderProcessor.java │ │ │ │ ├── converters │ │ │ │ ├── DataConverterFinder.java │ │ │ │ ├── JsonConverter.java │ │ │ │ └── YamlConverter.java │ │ │ │ ├── exception │ │ │ │ ├── DataConflictException.java │ │ │ │ ├── DataConversionException.java │ │ │ │ ├── DataListBindingException.java │ │ │ │ ├── DataMappingMismatchException.java │ │ │ │ ├── DataMappingRequiredFileException.java │ │ │ │ ├── DataReadingException.java │ │ │ │ └── DataScanningException.java │ │ │ │ └── items │ │ │ │ ├── DataMappingBuildItem.java │ │ │ │ ├── RoqDataBeanBuildItem.java │ │ │ │ ├── RoqDataBuildItem.java │ │ │ │ └── RoqDataJsonBuildItem.java │ │ └── test │ │ │ ├── java │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── roq │ │ │ │ └── data │ │ │ │ └── test │ │ │ │ ├── DataMappingRequiredDataFileTest.java │ │ │ │ ├── RoqDataBindingEnforceBeanDataFileSideTest.java │ │ │ │ ├── RoqDataBindingEnforceBeanDataMappingSideTest.java │ │ │ │ ├── RoqDataBindingTest.java │ │ │ │ ├── RoqDataDevModeTest.java │ │ │ │ ├── RoqDataInjectableBeanLookingCustomLocationTest.java │ │ │ │ ├── RoqDataInjectableBeanLookingDefaultLocationTest.java │ │ │ │ └── util │ │ │ │ ├── Bar.java │ │ │ │ ├── Foo.java │ │ │ │ ├── Foos.java │ │ │ │ ├── Item.java │ │ │ │ └── ItemRecord.java │ │ │ ├── resources │ │ │ ├── foo.json │ │ │ └── fromResource.json │ │ │ └── roq │ │ │ └── data │ │ │ ├── bar.yaml │ │ │ ├── baz.yml │ │ │ ├── foo.json │ │ │ ├── foos.yaml │ │ │ └── list.yaml │ └── test-data │ │ ├── bar.yaml │ │ ├── baz.yml │ │ └── foo.json ├── pom.xml └── runtime │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── io │ │ └── quarkiverse │ │ └── roq │ │ └── data │ │ └── runtime │ │ ├── RoqDataRecorder.java │ │ └── annotations │ │ └── DataMapping.java │ └── resources │ └── META-INF │ └── quarkus-extension.yaml ├── roq-frontmatter ├── deployment │ ├── pom.xml │ └── src │ │ ├── main │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── frontmatter │ │ │ └── deployment │ │ │ ├── Paginate.java │ │ │ ├── RoqFrontMatterOutputBuildItem.java │ │ │ ├── RoqFrontMatterProcessor.java │ │ │ ├── RoqFrontMatterRootUrlBuildItem.java │ │ │ ├── TemplateLink.java │ │ │ ├── data │ │ │ ├── RoqFrontMatterDataModificationBuildItem.java │ │ │ ├── RoqFrontMatterDataProcessor.java │ │ │ ├── RoqFrontMatterDocumentTemplateBuildItem.java │ │ │ ├── RoqFrontMatterPaginateTemplateBuildItem.java │ │ │ └── RoqFrontMatterTemplateBuildItem.java │ │ │ ├── exception │ │ │ ├── RoqFrontMatterReadingException.java │ │ │ ├── RoqLayoutNotFoundException.java │ │ │ ├── RoqPathConflictException.java │ │ │ ├── RoqPluginException.java │ │ │ ├── RoqSiteIndexNotFoundException.java │ │ │ ├── RoqSiteScanningException.java │ │ │ ├── RoqTemplateLinkException.java │ │ │ └── RoqThemeConfigurationException.java │ │ │ ├── publish │ │ │ ├── RoqFrontMatterPublishDerivedCollectionBuildItem.java │ │ │ ├── RoqFrontMatterPublishDocumentPageBuildItem.java │ │ │ ├── RoqFrontMatterPublishPageBuildItem.java │ │ │ └── RoqFrontMatterPublishProcessor.java │ │ │ ├── record │ │ │ ├── RoqFrontMatterCollectionBuildItem.java │ │ │ ├── RoqFrontMatterInitProcessor.java │ │ │ ├── RoqFrontMatterNormalPageBuildItem.java │ │ │ ├── RoqFrontMatterPageBuildItem.java │ │ │ └── RoqFrontMatterSiteIndexBuildItem.java │ │ │ └── scan │ │ │ ├── RoqFrontMatterQuteMarkupBuildItem.java │ │ │ ├── RoqFrontMatterRawTemplateBuildItem.java │ │ │ ├── RoqFrontMatterScanProcessor.java │ │ │ └── RoqFrontMatterStaticFileBuildItem.java │ │ └── test │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── frontmatter │ │ │ └── deployment │ │ │ ├── RoqFrontMatterApiModificationTest.java │ │ │ ├── RoqFrontMatterSimpleTest.java │ │ │ ├── RoqFrontMatterTest.java │ │ │ ├── TemplateLinkTest.java │ │ │ └── scan │ │ │ └── ParsePublishDateTest.java │ │ └── resources │ │ ├── application.properties │ │ ├── simple-site │ │ ├── content │ │ │ ├── index.html │ │ │ ├── pages │ │ │ │ └── some-page.html │ │ │ └── posts │ │ │ │ ├── 2020-10-24-old-post.html │ │ │ │ ├── 2023-10-10-some-post.html │ │ │ │ └── 2024-10-9-new-post.html │ │ ├── public │ │ │ └── images │ │ │ │ └── iamroq.png │ │ └── templates │ │ │ ├── layouts │ │ │ ├── default.html │ │ │ ├── page.html │ │ │ └── post.html │ │ │ └── partials │ │ │ └── header.html │ │ └── site │ │ ├── content │ │ ├── beers.json │ │ ├── index.html │ │ ├── pages │ │ │ ├── cool-page.html │ │ │ └── dir-page │ │ │ │ ├── beer.doc │ │ │ │ └── index.html │ │ └── posts │ │ │ ├── 2020-10-24-old-post.html │ │ │ ├── 2024-03-10-dir-post │ │ │ ├── beer.svg │ │ │ └── index.html │ │ │ └── awesome-post.html │ │ ├── data │ │ └── foo.yml │ │ ├── public │ │ └── images │ │ │ └── iamroq.png │ │ └── templates │ │ ├── layouts │ │ ├── default.html │ │ ├── page.html │ │ └── post.html │ │ └── partials │ │ ├── foo │ │ └── bar.html │ │ ├── header.html │ │ └── view.html ├── pom.xml └── runtime │ ├── pom.xml │ └── src │ └── main │ ├── java │ └── io │ │ └── quarkiverse │ │ └── roq │ │ └── frontmatter │ │ └── runtime │ │ ├── RoqFrontMatterMessages.java │ │ ├── RoqFrontMatterRecorder.java │ │ ├── RoqRouteHandler.java │ │ ├── RoqTemplateExtension.java │ │ ├── RoqTemplateGlobal.java │ │ ├── config │ │ ├── ConfiguredCollection.java │ │ └── RoqSiteConfig.java │ │ ├── exception │ │ └── RoqStaticFileException.java │ │ └── model │ │ ├── DocumentPage.java │ │ ├── NormalPage.java │ │ ├── Page.java │ │ ├── PageFiles.java │ │ ├── PageInfo.java │ │ ├── Paginator.java │ │ ├── RootUrl.java │ │ ├── RoqCollection.java │ │ ├── RoqCollections.java │ │ ├── RoqUrl.java │ │ └── Site.java │ └── resources │ ├── META-INF │ └── quarkus-extension.yaml │ ├── application.properties │ └── templates │ ├── fm │ ├── favicon.html │ ├── pagination.html │ └── rss.html │ └── tags │ ├── ga4.html │ ├── rss.html │ ├── seo.html │ ├── seoAuthor.html │ ├── seoDescription.html │ ├── seoFacebook.html │ ├── seoGenerator.html │ ├── seoImage.html │ ├── seoLocale.html │ ├── seoPaginator.html │ ├── seoTitle.html │ ├── seoTwitter.html │ ├── seoType.html │ ├── seoUrl.html │ └── seoVerifications.html ├── roq-generator ├── deployment │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── generator │ │ │ └── deployment │ │ │ ├── BuildSelectionBuildItem.java │ │ │ └── RoqGeneratorProcessor.java │ │ └── resources │ │ └── dev-ui │ │ └── qwc-roq-generator.js ├── integration-tests │ ├── pom.xml │ └── src │ │ ├── main │ │ ├── java │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── roq │ │ │ │ └── it │ │ │ │ └── RoqResource.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── resources │ │ │ │ └── assets │ │ │ │ └── vector.svg │ │ │ ├── application.properties │ │ │ ├── templates │ │ │ └── pub │ │ │ │ └── some-page.html │ │ │ └── web │ │ │ ├── index.html │ │ │ └── static │ │ │ ├── logo.svg │ │ │ ├── logo.svg.svg │ │ │ └── élo$ bar.txt │ │ └── test │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── roq │ │ └── it │ │ ├── RoqGenerationQueryTest.java │ │ ├── RoqGenerationReplaceTest.java │ │ └── RoqGenerationTest.java ├── pom.xml ├── runtime │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── generator │ │ │ └── runtime │ │ │ ├── ConfiguredPathsProvider.java │ │ │ ├── PageSource.java │ │ │ ├── PathReplaceConfig.java │ │ │ ├── RoqGenerator.java │ │ │ ├── RoqGeneratorConfig.java │ │ │ ├── RoqGeneratorRecorder.java │ │ │ ├── RoqSelection.java │ │ │ ├── SelectedPath.java │ │ │ ├── StaticFile.java │ │ │ └── devui │ │ │ └── RoqGeneratorJsonRPCService.java │ │ └── resources │ │ └── META-INF │ │ └── quarkus-extension.yaml └── spi │ ├── pom.xml │ └── src │ └── main │ └── java │ └── io │ └── quarkiverse │ └── roq │ └── generator │ └── deployment │ └── items │ └── SelectedPathBuildItem.java ├── roq-plugin ├── aliases │ ├── deployment │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── aliases │ │ │ └── deployment │ │ │ ├── RoqPluginAliasesProcessor.java │ │ │ └── items │ │ │ └── RoqFrontMatterAliasesBuildItem.java │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── aliases │ │ │ └── runtime │ │ │ └── RoqFrontMatterAliasesRecorder.java │ │ └── resources │ │ └── META-INF │ │ └── quarkus-extension.yaml ├── asciidoc-jruby │ ├── deployment │ │ ├── .asciidoctor │ │ │ └── diagram │ │ │ │ └── wunderbar.svg.cache │ │ ├── pom.xml │ │ ├── src │ │ │ ├── main │ │ │ │ └── java │ │ │ │ │ └── io │ │ │ │ │ └── quarkiverse │ │ │ │ │ └── roq │ │ │ │ │ └── plugin │ │ │ │ │ └── asciidoctorj │ │ │ │ │ └── deployment │ │ │ │ │ └── RoqPluginAsciidoctorJProcessor.java │ │ │ └── test │ │ │ │ └── java │ │ │ │ └── io │ │ │ │ └── quarkiverse │ │ │ │ └── roq │ │ │ │ └── plugin │ │ │ │ └── asciidoctorj │ │ │ │ └── test │ │ │ │ ├── QuarkusAsciidoctorJTest.java │ │ │ │ ├── QuteAsciidoctorJDiagramTest.java │ │ │ │ ├── QuteAsciidoctorJSectionHelperTest.java │ │ │ │ ├── QuteAsciidoctorJSectionWithInnerSectionTest.java │ │ │ │ └── QuteWebAsciidoctorJExtensionsTest.java │ │ └── wunderbar.svg │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── asciidoctorj │ │ │ └── runtime │ │ │ ├── AsciidoctorJConfig.java │ │ │ ├── AsciidoctorJConverter.java │ │ │ └── AsciidoctorJSectionHelperFactory.java │ │ └── resources │ │ └── META-INF │ │ └── quarkus-extension.yaml ├── asciidoc │ ├── deployment │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── asciidoc │ │ │ └── deployment │ │ │ └── RoqPluginAsciidocProcessor.java │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ └── resources │ │ └── META-INF │ │ └── quarkus-extension.yaml ├── lunr │ ├── deployment │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── lunr │ │ │ └── deployment │ │ │ └── RoqPluginLunrProcessor.java │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── sitemap │ │ │ └── runtime │ │ │ └── runtime │ │ │ └── RoqPluginLunrTemplateExtension.java │ │ ├── resources │ │ ├── META-INF │ │ │ └── quarkus-extension.yaml │ │ └── templates │ │ │ ├── fm │ │ │ └── search-index.json │ │ │ └── tags │ │ │ ├── search-button.html │ │ │ ├── search-overlay.html │ │ │ └── search-script.html │ │ └── web │ │ ├── search.js │ │ └── search.scss ├── markdown │ ├── deployment │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── asciidoc │ │ │ └── deployment │ │ │ └── RoqPluginMarkdownProcessor.java │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ └── resources │ │ └── META-INF │ │ └── quarkus-extension.yaml ├── pom.xml ├── qrcode │ ├── deployment │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── qrcode │ │ │ └── deployment │ │ │ └── RoqPluginQrCodeProcessor.java │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── qrcode │ │ │ └── runtime │ │ │ ├── Futures.java │ │ │ ├── QRCodeRenderer.java │ │ │ ├── QuteBarCode.java │ │ │ ├── RoqQrCode.java │ │ │ └── TypeUtil.java │ │ └── resources │ │ └── META-INF │ │ ├── beans.xml │ │ └── quarkus-extension.yaml ├── series │ ├── deployment │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── series │ │ │ └── deployment │ │ │ └── RoqPluginSeriesProcessor.java │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── series │ │ │ └── runtime │ │ │ ├── Series.java │ │ │ ├── SeriesMessage.java │ │ │ └── SeriesRecorder.java │ │ └── resources │ │ ├── META-INF │ │ ├── beans.xml │ │ └── quarkus-extension.yaml │ │ ├── messages │ │ └── series_fr.properties │ │ └── templates │ │ └── partials │ │ └── roq-series.html ├── sitemap │ ├── deployment │ │ ├── pom.xml │ │ └── src │ │ │ └── main │ │ │ └── java │ │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── sitemap │ │ │ └── deployment │ │ │ └── RoqPluginSitemapProcessor.java │ ├── pom.xml │ └── runtime │ │ ├── pom.xml │ │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── plugin │ │ │ └── sitemap │ │ │ └── runtime │ │ │ └── RoqPluginSitemapTemplateExtension.java │ │ └── resources │ │ ├── META-INF │ │ └── quarkus-extension.yaml │ │ └── templates │ │ └── fm │ │ └── sitemap.xml └── tagging │ ├── deployment │ ├── pom.xml │ └── src │ │ └── main │ │ └── java │ │ └── io │ │ └── quarkiverse │ │ └── roq │ │ └── plugin │ │ └── tagging │ │ └── deployment │ │ ├── RoqPluginTaggingProcessor.java │ │ └── RoqTaggingConfig.java │ ├── pom.xml │ └── runtime │ ├── pom.xml │ └── src │ └── main │ └── resources │ └── META-INF │ └── quarkus-extension.yaml ├── roq-testing ├── pom.xml └── src │ └── main │ ├── java │ └── io │ │ └── quarkiverse │ │ └── roq │ │ └── testing │ │ ├── RoqAndRoll.java │ │ ├── RoqGeneratorTestCallback.java │ │ └── RoqServer.java │ └── resources │ └── META-INF │ └── services │ ├── io.quarkus.test.junit.callback.QuarkusTestAfterAllCallback │ ├── io.quarkus.test.junit.callback.QuarkusTestAfterConstructCallback │ └── io.quarkus.test.junit.callback.QuarkusTestBeforeTestExecutionCallback ├── roq-theme ├── LICENSE ├── README.md ├── default │ ├── pom.xml │ └── src │ │ └── main │ │ ├── java │ │ └── io │ │ │ └── quarkiverse │ │ │ └── roq │ │ │ └── theme │ │ │ └── ThemeMessageBundle.java │ │ ├── resources │ │ ├── META-INF │ │ │ └── beans.xml │ │ ├── application.properties │ │ └── templates │ │ │ ├── partials │ │ │ └── roq-default │ │ │ │ ├── 404.html │ │ │ │ ├── head.html │ │ │ │ ├── pagination.html │ │ │ │ ├── sidebar-about.html │ │ │ │ ├── sidebar-contact.html │ │ │ │ ├── sidebar-copyright.html │ │ │ │ └── sidebar-menu.html │ │ │ ├── tags │ │ │ └── author-card.html │ │ │ └── theme-layouts │ │ │ └── roq-default │ │ │ ├── 404.html │ │ │ ├── default.html │ │ │ ├── index.html │ │ │ ├── main.html │ │ │ ├── page.html │ │ │ ├── post.html │ │ │ └── tag.html │ │ └── web │ │ ├── roq.js │ │ ├── roq.scss │ │ └── scss │ │ ├── _media.scss │ │ ├── _normalize.scss │ │ ├── _typo.scss │ │ ├── _variables.scss │ │ └── parts │ │ ├── _404-page.scss │ │ ├── _about-page.scss │ │ ├── _home-page.scss │ │ ├── _post-page.scss │ │ ├── _series.scss │ │ └── _tag.scss └── pom.xml ├── roq.java └── roq ├── deployment ├── pom.xml └── src │ └── main │ └── resources │ └── dummy.txt ├── integration-tests ├── pom.xml └── src │ ├── main │ └── resources │ │ ├── application.properties │ │ ├── content │ │ ├── error-image-site.md │ │ ├── error-static-file.md │ │ ├── ignore │ │ │ └── .foo │ │ ├── posts │ │ │ ├── 2010-08-05-hello-world │ │ │ │ ├── hello-page.png │ │ │ │ ├── hello.pdf │ │ │ │ └── index.md │ │ │ ├── error-file-dir │ │ │ │ └── index.md │ │ │ ├── error-file.md │ │ │ ├── error-image-dir │ │ │ │ └── index.md │ │ │ ├── error-image.md │ │ │ ├── escape-data.md │ │ │ ├── escaped-config.md │ │ │ └── markdown-post-k8s.md │ │ └── élo you$@.html │ │ ├── public │ │ ├── hello.txt │ │ ├── images │ │ │ ├── hello.foo.png │ │ │ └── hello.png │ │ └── static │ │ │ └── assets │ │ │ └── images │ │ │ └── legacy.png │ │ └── templates │ │ └── partials │ │ └── roq-default │ │ └── sidebar-copyright.html │ └── test │ └── java │ └── io │ └── quarkiverse │ └── roq │ ├── RoqCodestartTest.java │ ├── RoqNoSlugifyFilesTest.java │ ├── RoqTemplateExtensionTest.java │ └── RoqTest.java ├── pom.xml └── runtime ├── pom.xml └── src └── main ├── codestarts └── quarkus │ └── roq-codestart │ ├── base │ ├── .github │ │ └── workflows │ │ │ └── deploy.yml │ ├── content │ │ ├── 404.html │ │ ├── about.md │ │ ├── index.html │ │ └── posts │ │ │ └── 2024-10-13-the-first-roq │ │ │ ├── blog.avif │ │ │ └── index.md │ ├── data │ │ ├── authors.yml │ │ └── menu.yml │ └── public │ │ └── images │ │ ├── iamroq.png │ │ └── site-icon.svg │ └── codestart.yml └── resources └── META-INF └── quarkus-extension.yaml /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Lines starting with '#' are comments. 2 | # Each line is a file pattern followed by one or more owners. 3 | 4 | # More details are here: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners 5 | 6 | # The '*' pattern is global owners. 7 | 8 | # Order is important. The last matching pattern has the most precedence. 9 | # The folders are ordered as follows: 10 | 11 | # In each subsection folders are ordered first by depth, then alphabetically. 12 | # This should make it easy to add new rules without breaking existing ones. 13 | 14 | * @quarkiverse/quarkiverse-roq 15 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "maven" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/project.yml: -------------------------------------------------------------------------------- 1 | release: 2 | current-version: 1.6.0 3 | next-version: "999-SNAPSHOT" 4 | -------------------------------------------------------------------------------- /.github/workflows/build-pr-preview.yml: -------------------------------------------------------------------------------- 1 | name: Build PR Preview 2 | 3 | on: 4 | pull_request: 5 | paths-ignore: 6 | - '.gitignore' 7 | - 'CODEOWNERS' 8 | - 'LICENSE' 9 | - '*.md' 10 | - '*.txt' 11 | - '.all-contributorsrc' 12 | jobs: 13 | build-website: 14 | name: Build Website 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v4 18 | - name: Set up JDK 21 19 | uses: actions/setup-java@v4 20 | with: 21 | distribution: temurin 22 | java-version: 21 23 | cache: 'maven' 24 | 25 | - name: Build Roq 26 | run: mvn -B clean install --file pom.xml -DskipTests -Dno-format 27 | 28 | - name: Store PR id 29 | run: | 30 | echo ${{ github.event.number }} > ./docs/target/generated-docs/pr-id.txt 31 | 32 | - name: Publishing docs 33 | uses: actions/upload-artifact@v4 34 | with: 35 | name: docs 36 | path: ./docs/target/generated-docs 37 | retention-days: 3 38 | 39 | - name: Build blog 40 | uses: ./ 41 | with: 42 | setup-java: 'false' 43 | github-pages: 'false' 44 | site-directory: 'blog' 45 | site-future: 'true' 46 | maven-executable: 'mvn' 47 | 48 | - name: Publishing blog 49 | uses: actions/upload-artifact@v4 50 | with: 51 | name: blog 52 | path: ./blog/target/roq 53 | retention-days: 3 54 | -------------------------------------------------------------------------------- /.github/workflows/pre-release.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Pre Release 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - '.github/project.yml' 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | pre-release: 14 | name: Pre-Release 15 | uses: quarkiverse/.github/.github/workflows/pre-release.yml@main 16 | secrets: inherit 17 | -------------------------------------------------------------------------------- /.github/workflows/preview-pr-teardown.yml: -------------------------------------------------------------------------------- 1 | name: Surge.sh Teardown 2 | 3 | on: 4 | pull_request_target: 5 | # when using teardown: 'true', add default event types + closed event type 6 | types: [closed] 7 | 8 | jobs: 9 | preview: 10 | runs-on: ubuntu-latest 11 | permissions: 12 | pull-requests: write # Required to update PR status comment 13 | steps: 14 | - name: Teardown Surge.sh preview (docs) 15 | id: teardown-docs 16 | run: npx surge teardown https://quarkiverse-roq-docs-${{ github.event.number }}-preview.surge.sh --token ${{ secrets.SURGE_TOKEN }} || true 17 | - name: Update PR status comment 18 | uses: quarkusio/action-helpers@main 19 | with: 20 | action: maintain-one-comment 21 | github-token: ${{ secrets.GITHUB_TOKEN }} 22 | pr-number: ${{ github.event.number }} 23 | body: | 24 | 🙈 The PR is closed and the preview is expired. 25 | body-marker: 26 | 27 | - name: Teardown Surge.sh preview (blog) 28 | id: teardown-blog 29 | run: npx surge teardown https://quarkiverse-roq-blog-${{ github.event.number }}-preview.surge.sh --token ${{ secrets.SURGE_TOKEN }} || true 30 | - name: Update PR status comment 31 | uses: quarkusio/action-helpers@main 32 | with: 33 | action: maintain-one-comment 34 | github-token: ${{ secrets.GITHUB_TOKEN }} 35 | pr-number: ${{ github.event.number }} 36 | body: | 37 | 🙈 The PR is closed and the preview is expired. 38 | body-marker: 39 | -------------------------------------------------------------------------------- /.github/workflows/release-perform.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Perform Release 2 | run-name: Perform ${{github.event.inputs.tag || github.ref_name}} Release 3 | on: 4 | push: 5 | tags-ignore: 6 | - 'v*' 7 | workflow_dispatch: 8 | inputs: 9 | tag: 10 | description: 'Tag to release' 11 | required: true 12 | 13 | permissions: 14 | attestations: write 15 | id-token: write 16 | contents: read 17 | 18 | concurrency: 19 | group: ${{ github.workflow }}-${{ github.ref }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | perform-release: 24 | name: Perform Release 25 | uses: quarkiverse/.github/.github/workflows/perform-release.yml@main 26 | secrets: inherit 27 | with: 28 | version: ${{github.event.inputs.tag || github.ref_name}} 29 | -------------------------------------------------------------------------------- /.github/workflows/release-prepare.yml: -------------------------------------------------------------------------------- 1 | name: Quarkiverse Prepare Release 2 | 3 | on: 4 | pull_request: 5 | types: [ closed ] 6 | paths: 7 | - '.github/project.yml' 8 | 9 | concurrency: 10 | group: ${{ github.workflow }}-${{ github.ref }} 11 | cancel-in-progress: true 12 | 13 | jobs: 14 | prepare-release: 15 | name: Prepare Release 16 | if: ${{ github.event.pull_request.merged == true}} 17 | uses: quarkiverse/.github/.github/workflows/prepare-release.yml@main 18 | secrets: inherit 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see https://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | 25 | # Eclipse 26 | .project 27 | .classpath 28 | .settings/ 29 | bin/ 30 | 31 | # IntelliJ 32 | .idea 33 | *.ipr 34 | *.iml 35 | *.iws 36 | 37 | # NetBeans 38 | nb-configuration.xml 39 | 40 | # Visual Studio Code 41 | .vscode 42 | .factorypath 43 | 44 | # OSX 45 | .DS_Store 46 | 47 | # Vim 48 | *.swp 49 | *.swo 50 | 51 | # patch 52 | *.orig 53 | *.rej 54 | 55 | # Gradle 56 | .gradle/ 57 | build/ 58 | 59 | # Maven 60 | target/ 61 | pom.xml.tag 62 | pom.xml.releaseBackup 63 | pom.xml.versionsBackup 64 | release.properties 65 | 66 | .quarkus 67 | 68 | node_modules/ -------------------------------------------------------------------------------- /blog/.gitignore: -------------------------------------------------------------------------------- 1 | data/*.json 2 | data/project-info.yml 3 | templates/partials/doc/configs/** -------------------------------------------------------------------------------- /blog/config/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.web-bundler.dependencies.auto-import=all 2 | #quarkus.log.category."io.quarkiverse.roq.frontmatter.deployment".level=DEBUG 3 | #quarkus.log.category."io.quarkiverse.roq.generator".level=DEBUG 4 | quarkus.default-locale=en 5 | quarkus.asciidoctorj.attributes.icons=font 6 | quarkus.asciidoctorj.attributes.source-highlighter=highlight.js 7 | site.slugify-files=false -------------------------------------------------------------------------------- /blog/content/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: :theme/404 3 | link: 404.html 4 | image: iamroq.png 5 | --- 6 | -------------------------------------------------------------------------------- /blog/content/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | description: | 4 | Roq is a powerful static site generator that combines the best features of tools like Jekyll and Hugo, but within the Java ecosystem. It offers a modern approach with Quarkus at its core, requiring zero configuration to get started —ideal for developers who want to jump right in, while still being flexible enough for advanced users to hook into Java for deeper customization. 5 | layout: :theme/page 6 | --- 7 | 8 | # About Roq 9 | 10 | Roq is a powerful static site generator that combines the best features of tools like Jekyll and Hugo, but within the Java ecosystem. It offers a modern approach with Quarkus at its core, requiring zero configuration to get started —ideal for developers who want to jump right in, while still being flexible enough for advanced users to hook into Java for deeper customization. 11 | 12 | **This tool is a testament to how extensible and powerful Quarkus is, offering a low-risk yet highly capable platform that will evolve as demand grows.** 13 | 14 | ## Origins 15 | 16 | I wrote a [blog post]({site.url('posts/roq-with-blogs')}) explaining how it all started. 17 | 18 | ## Credits 19 | 20 | `Those are generated as a JSON by all-contributors, then we leverage roq-data to print them... slick 🏄!` 21 | 22 | Thanks goes to these wonderful people: 23 | 24 |
25 | {#for contributor in cdi:contributors.contributors} 26 | {#author-card name=contributor.name avatar=contributor.avatar_url nickname=contributor.login profile=contributor.profile } 27 | {#if cdi:authors.get(contributor.login)} 28 | author 29 | {/if} 30 | {/author-card} 31 | {/for} 32 |
33 | -------------------------------------------------------------------------------- /blog/content/docs/getting-started/roq-how-it-works.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/content/docs/getting-started/roq-how-it-works.png -------------------------------------------------------------------------------- /blog/content/events.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Events 3 | description: Events related to Roq 4 | layout: :theme/page 5 | --- 6 | 7 |

Roq Events

8 | 9 | {#for event in cdi:events.list} 10 |
11 |
12 | 13 |

{event.title}

14 |

{event.description}

15 | {#if event.link}More info...{/if} 16 |
17 |
18 | {/for} 19 | -------------------------------------------------------------------------------- /blog/content/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello, world! I’m Roq — a fun little SSG (Static Site Generator) with a Java soul and Quarkus energy. 3 | description: A static site generator (SSG) that makes it fun and easy to build websites and blogs. It’s built with Java and Quarkus under the hood—but you don’t need to know them. 4 | name: I am ROQ 5 | simple-name: ROQ 6 | image: roq-icon.svg 7 | icon: ico.png 8 | social-twitter: quarkusio 9 | social-facebook: 10 | social-github: quarkiverse/quarkus-roq 11 | social-linkedin: quarkusio 12 | layout: :theme/index 13 | paginate: 14 | collection: posts 15 | size: 10 16 | --- 17 |

A blog under the Roq

18 | 19 | If you haven't yet, be sure to check out our getting started page! 20 | -------------------------------------------------------------------------------- /blog/content/posts/2024-09-19-drafts-and-future.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Easily manage Drafts and Future articles in Roq" 3 | date: 2024-09-19 10:45:00 +0200 4 | description: Roq SSG introduces a new feature that allows you to hide or show draft and future articles using simple Quarkus configurations. This update gives developers greater control over which content is visible, improving content management and workflow. 5 | image: https://plus.unsplash.com/premium_photo-1664197369206-597ffd51f65c?q=80&w=3540&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 6 | tags: frontmatter, guide 7 | author: ia3andy 8 | --- 9 | 10 | Roq just made content management easier with a cool new feature that lets you control drafts and future articles directly in your configuration. No more messing around with hard-to-track content—now you can manage everything through the Quarkus config: 11 | 12 | ```shell 13 | quarkus dev -site.drafts -site.future` 14 | ``` 15 | 16 | This is using frontmatter data in articles and pages `draft: true` and `date: 2024-09-19 10:45:00 +0200` to take the decision. 17 | 18 | By default, both options are set to `false`, meaning that drafts and future pages will stay hidden until you’re ready to reveal them. All you need to do is update these configs when you're ready to publish. 19 | 20 | This simple feature adds flexibility and control, making your publishing process more streamlined. Happy content managing! 21 | -------------------------------------------------------------------------------- /blog/content/posts/2024-09-23-seo.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Out of the box awesome SEO 3 | image: https://images.unsplash.com/photo-1562577309-2592ab84b1bc?q=80&w=3474&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 4 | description: Learn how to implement SEO in Roq in a blink of an eye. 5 | author: ia3andy 6 | tags: seo, frontmatter, guide, cool-stuff 7 | date: 2024-09-23 14:00:00 +0200 8 | --- 9 | 10 | Adding SEO is as easy as adding this tag to your `` section: 11 | 12 | ```html 13 | \{#seo page site /} 14 | ``` 15 | 16 | It will automatically use the Frontmatter data to fill the tags. Read the Roq documentation for more... 17 | 18 | Like this: 19 | 20 | ```html 21 | {#seo page site /} 22 | ``` 23 | -------------------------------------------------------------------------------- /blog/content/posts/2024-10-08-tagging.md: -------------------------------------------------------------------------------- 1 | --- 2 | layout: :theme/post 3 | title: The first Roq plugin is for tagging (with pagination) 4 | image: tagging.png 5 | description: We introduced the first Roq plugin, it is for collection tagging & with pagination support! 6 | author: ia3andy 7 | tags: plugin, frontmatter, guide, cool-stuff 8 | series: roq-plugins 9 | --- 10 | 11 | My mind is getting blown by how much Quarkus was made for Static Site Generation. I just implemented a new plugin to generate tag pages and that was soooo easy. 12 | 13 | To use it: 14 | 15 | ```xml 16 | 17 | io.quarkiverse.roq 18 | quarkus-roq-plugin-tagging 19 | ... 20 | 21 | ``` 22 | 23 | and adding a new `layouts/tag.html` page or any layout with `tagging: [name of collection]` as FM data. 24 | 25 | For more info [check out the doc](https://iamroq.com/docs/plugins/#plugin-tagging). 26 | -------------------------------------------------------------------------------- /blog/content/posts/2024-10-10-rss-feed.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: RSS Feed of your blog posts 3 | description: Automatically generate an RSS feed of your blog links. 4 | image: https://images.unsplash.com/photo-1520636902994-f596446c3728?q=80&w=3198&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 5 | tags: plugin,frontmatter,guide 6 | author: melloware 7 | aliases: [rss] 8 | --- 9 | 10 | Adding RSS is as easy as adding this tag to your `` section: 11 | 12 | ```html 13 | \{#rss site /} 14 | ``` 15 | 16 | Like this: 17 | 18 | ``` 19 | {#rss site /} 20 | 21 | ``` 22 | 23 | It will automatically utilize the Frontmatter data from all your blog posts to generate a valid Atom RSS feed link at `rss.xml`. Ensure you create an `rss.xml` file at the root of your site and include this single line of code: 24 | 25 | ```html 26 | \{#include fm/rss.html /} 27 | ``` 28 | 29 | The Atom Syndication Format is an XML language used for web feeds. A web feed (also called ‘news feed’ or ‘RSS feed’) is a data format used for providing users with frequently updated content. Content distributors syndicate a web feed, thereby allowing users to subscribe a channel to it. A typical scenario of web-feed use might involve the following: a content provider publishes a feed link on its site which end users can register with an aggregator program (also called a feed reader or a newsreader) running on their own machines. 30 | 31 | ```xml 32 | {#include fm/rss.html} 33 | ``` 34 | -------------------------------------------------------------------------------- /blog/content/posts/2024-10-22-asciidoc.adoc: -------------------------------------------------------------------------------- 1 | --- 2 | title: Write your blog posts in AsciiDoc 3 | description: Automatically generate html from AsciiDoc content 4 | img: https://images.unsplash.com/photo-1455390582262-044cdead277a?q=80&w=3198&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 5 | tags: plugin, frontmatter, guide 6 | author: jtama 7 | aliases: [asciidoc] 8 | series: roq-plugins 9 | --- 10 | 11 | Writing content is AsciiDoc format is an absolut no brainer. Roq provides a plugin to handle it transparently for you. 12 | 13 | To use it, you need to add the `quarkus-roq-plugin-asciidoc' to your project. 14 | 15 | [%collapsible] 16 | ==== 17 | You can do that using several ways : 18 | 19 | [qanda] 20 | Manually:: 21 | [source,xml] 22 | .pom.xml 23 | ---- 24 | 25 | io.quarkiverse.roq 26 | quarkus-roq-plugin-asciidoc 27 | $\{quarkus-roq.version\} 28 | 29 | ---- 30 | 31 | Using the Quarkus cli:: 32 | [source,shell] 33 | ---- 34 | quarkus extension add io.quarkiverse.roq:quarkus-roq-plugin-asciidoc 35 | ---- 36 | 37 | Using the Maven:: 38 | [source,shell] 39 | ---- 40 | ./mvnw quarkus:add-extension -Dextensions="io.quarkiverse.roq:quarkus-roq-plugin-asciidoc" 41 | ---- 42 | 43 | Using the Gradle:: 44 | [source,shell] 45 | ---- 46 | ./gradlew addExtension --extensions="io.quarkiverse.roq:quarkus-roq-plugin-asciidoc" 47 | ---- 48 | ==== 49 | 50 | Once done, you can start writing your blog posts in AsciiDoc format. -------------------------------------------------------------------------------- /blog/content/posts/2024-10-31-roq-with-blogs/generator-runtime-discussion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/content/posts/2024-10-31-roq-with-blogs/generator-runtime-discussion.png -------------------------------------------------------------------------------- /blog/content/posts/2024-11-14-qrcode.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Need a QR Code? 3 | image: https://images.unsplash.com/photo-1726255294277-57c46883bd94?q=80&w=3870&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 4 | description: Add a QR Code to your Roq website. 5 | author: ia3andy 6 | tags: guide,cool-stuff,plugin 7 | date: 2024-11-14 14:00:00 +0200 8 | series: roq-plugins 9 | --- 10 | 11 | Need to add a scannable QR Code to your website? Whether it's for a restaurant menu, event ticket, or any other use case where you want to make your content easily accessible via mobile devices, the Roq QR Code plugin has you covered. 12 | 13 | **Step 1:** Add the QRCode plugin in your dependencies file: 14 | 15 | ```xml 16 | 17 | io.quarkiverse.roq 18 | quarkus-roq-plugin-qrcode 19 | ... 20 | 21 | ``` 22 | 23 | **Step 2:** Add the QRCode tag to your template with all the parameters you need: 24 | 25 | ```html 26 | \{#qrcode value="https://luigis.com/menu/" alt="Luigi's Menu" foreground="#000066" background="#FFFFFF" width=300 height=300 /} 27 | ``` 28 | 29 | It will render a QR Code like this: 30 | 31 |
32 | {#qrcode value="https://luigis.com/menu/" alt="Luigi's Menu" foreground="#000066" background="#FFFFFF" width=300 height=300 /} 33 |
34 | -------------------------------------------------------------------------------- /blog/content/posts/2024-12-06-series/series.foo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/content/posts/2024-12-06-series/series.foo.png -------------------------------------------------------------------------------- /blog/content/posts/2024-12-26-page-files/dina-badamshina-j7vbBmTHmjY-unsplash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/content/posts/2024-12-26-page-files/dina-badamshina-j7vbBmTHmjY-unsplash.jpg -------------------------------------------------------------------------------- /blog/content/posts/2024-12-26-page-files/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Static attached files for posts and pages 3 | image: dina-badamshina-j7vbBmTHmjY-unsplash.jpg 4 | description: | 5 | This Christmas, I’m Roq-ing a cool new feature (inspired by Hugo 😅): it is possible to attach static files to posts and pages. They will be served relative to the page. 🎁🤩 6 | author: ia3andy 7 | tags: frontmatter, cool-stuff 8 | --- 9 | 10 | This Christmas, I’m Roq-ing a cool new feature (inspired by Hugo 😅): it is possible to attach static files to posts and pages. They will be served relative to the page. 🎁🤩 11 | 12 | I love it because it allows to put all the content related to one page or post in the same place. Bonus, images are displayed on previews since they are relative to the template. 13 | 14 | For example here is a sample pdf: [link](sample.pdf). 15 | 16 | 17 | **Fun fact:** [@parisjug](https://www.parisjug.org/) is already using this feature on their site (which is on Hugo 🤪)! 18 | 19 | The doc for this feature is [here](https://iamroq.com/docs/basics/#page-files). 20 | -------------------------------------------------------------------------------- /blog/content/posts/2024-12-26-page-files/sample.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/content/posts/2024-12-26-page-files/sample.pdf -------------------------------------------------------------------------------- /blog/content/posts/2025-01-08-sitemap.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Easily Generate a `sitemap.xml` for Your Site with Roq" 3 | description: "Learn how to quickly set up and customize a sitemap.xml for your site using the Roq plugin." 4 | tags: plugin,frontmatter,guide,cool-stuff 5 | image: https://images.unsplash.com/photo-1488628176578-4ffd5fdbc900?q=80&w=4142&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 6 | author: ia3andy 7 | --- 8 | 9 | Creating a `sitemap.xml` for your site has never been easier! With the Sitemap plugin, you can automatically generate a well-structured sitemap for search engines to crawl your pages efficiently. 10 | 11 | ## Installation 12 | 13 | To get started, install the plugin by running the following command: 14 | 15 | ```shell 16 | quarkus ext add quarkus-roq-plugin-sitemap 17 | ``` 18 | 19 | ## Setting Up the Sitemap 20 | 21 | Next, create a new sitemap file in the `content/sitemap.xml`: 22 | 23 | 24 | ```xml 25 | 26 | \{#include fm/sitemap.xml} 27 | ``` 28 | 29 | And that's it! Your sitemap is now ready. 30 | 31 | ## Excluding Pages from the Sitemap 32 | 33 | If there are pages you don't want included in the sitemap, simply set the `sitemap` property to `false` in the FM of those pages. For example: 34 | 35 | ```yaml 36 | --- 37 | title: "Hidden Page" 38 | sitemap: false 39 | --- 40 | ``` 41 | 42 | ## Accessing Your Sitemap 43 | 44 | Once your site is up and running, you can view your sitemap by navigating to: 45 | 46 | ``` 47 | http://localhost:8080/sitemap.xml 48 | ``` 49 | 50 | Congratulations! You’ve successfully set up a `sitemap.xml` for your site. 51 | -------------------------------------------------------------------------------- /blog/content/posts/2025-01-28-roq-and-roll-test/c'est de la poussière d'étoile.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/content/posts/2025-01-28-roq-and-roll-test/c'est de la poussière d'étoile.jpg -------------------------------------------------------------------------------- /blog/content/posts/2025-03-24-updating-roq/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "No pain updates with Roq" 3 | description: One of the most overlooked aspects when choosing a Static Site Generator (SSG) is how easy it is to keep your project up to date. Many developers have struggled with complex upgrade processes, dependency conflicts, and breaking changes when using traditional SSGs like Jekyll or Hugo. 4 | image: https://images.unsplash.com/photo-1585776245991-cf89dd7fc73a?q=80&w=3999&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 5 | tags: blogging 6 | --- 7 | 8 | One of the most overlooked aspects when choosing a Static Site Generator (SSG) is how easy it is to keep your project up to date. Many developers have struggled with complex upgrade processes, dependency conflicts, and breaking changes when using traditional SSGs like Jekyll or Hugo. 9 | 10 | With **Roq**, upgrading is refreshingly simple. 11 | 12 | ## Updating Roq: A One-Command Upgrade 13 | 14 | Roq is built on **Quarkus**, which provides a streamlined upgrade process via the Quarkus CLI. To update Roq to the latest version, all you need to do is run: 15 | 16 | ```sh 17 | quarkus update 18 | ``` 19 | -------------------------------------------------------------------------------- /blog/content/posts/2025-04-04-lunr/index.adoc: -------------------------------------------------------------------------------- 1 | --- 2 | title: 🔎 Your users deserve searching capabilities! 3 | description: No third party service needed 🚀 4 | img: https://images.unsplash.com/photo-1554696468-19f8c7a71ad5?q=80&w=1740&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D 5 | tags: plugin, frontmatter, guide 6 | author: jtama 7 | --- 8 | 9 | So your site is growing larger and larger and so it becomes harder and harder to find anything you wrote more than a few weeks ago. 10 | And that is frustrating. 11 | 12 | [.text-center] 13 | __**Words vanish, writing remains**__ 14 | 15 | Yes... But if it remains buried deep in a pile of posts, it won't be of any use to any one. 16 | 17 | It seems you need to add a search engine to your site. 18 | 19 | But... you choose static generation for a reason, right ? Economy of resources, matters to you. And so you don't want to add a full-blown search engine like ElasticSearch or Solr. 20 | 21 | And guess what ? We couldn't agree more **with you** 🤩. We think you are _perfectly_ right, and that people should listen to you more. At least that's what we do. 👂 22 | 23 | So we did a bit of research and found out exactly what you need : 24 | 25 | https://lunrjs.com/[Lunr.js], it's a small, full-text search engine written in JavaScript. It runs in the browser based on a static generated json index and don't need any other third party services ✨. 26 | 27 | **Tadddaaah! ** We wrote a Lunr.js plugin for Roq. 28 | 29 | image::search.png[Search] 30 | 31 | 👉 Full documentation is available link:/docs/plugins/#plugin-lunr[here], don't wait any longer, go check it out. 32 | -------------------------------------------------------------------------------- /blog/content/posts/2025-04-04-lunr/search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/content/posts/2025-04-04-lunr/search.png -------------------------------------------------------------------------------- /blog/content/roqers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: Roqers 3 | description: | 4 | Sites built with Roq! See what fellow Roqers have created—and share your own story. 5 | layout: :theme/page 6 | --- 7 | 8 | # 🎸 Roqers 9 | 10 | **You created a site with Roq? Please share the link with a small description in the comments and give us your experience.** 11 | 12 |
13 | 28 | -------------------------------------------------------------------------------- /blog/content/rss.xml: -------------------------------------------------------------------------------- 1 | {#include fm/rss.html} -------------------------------------------------------------------------------- /blog/content/search-index.json: -------------------------------------------------------------------------------- 1 | {#include fm/search-index.json} -------------------------------------------------------------------------------- /blog/content/sitemap.xml: -------------------------------------------------------------------------------- 1 | {#include fm/sitemap.xml} -------------------------------------------------------------------------------- /blog/data/authors.yml: -------------------------------------------------------------------------------- 1 | jtama: 2 | name: "Jérôme Tama" 3 | avatar: "https://github.com/jtama.png" 4 | job: Architect/Tech Lead 5 | profile: "https://x.com/jtama_" 6 | nickname: "jtama" 7 | bio: "Passionate about Java, Quarkus, containers, and documentation as code, I mainly develop, train, and sometimes contribute to OSS projects" 8 | ia3andy: 9 | name: "Andy Damevin" 10 | avatar: "https://github.com/ia3andy.png" 11 | job: Principal Software Engineer 12 | profile: "https://x.com/ia3andy" 13 | nickname: "ia3andy" 14 | bio: "I am happy to wake up every day and make the Java world a better place with Quarkus. I am mostly a backend developer but I am not that bad at doing web apps either in my spare time, in fact, you can be the judge of that since Roq is my baby :-)" 15 | mcruzdev: 16 | name: "Matheus Cruz" 17 | avatar: "https://github.com/mcruzdev.png" 18 | profile: "https://x.com/mcruzdev" 19 | job: Senior Software Engineer 20 | nickname: "mcruzdev" 21 | bio: "I am a passionate learner, open-source enthusiast, and Java developer with a drive for continuous improvement. When I’m not coding, you can find me on the Brazilian Jiu Jitsu mats, playing the guitar, or exploring new challenges. I believe in the power of community, collaboration, and creativity—both in and outside of tech." -------------------------------------------------------------------------------- /blog/data/events.yml: -------------------------------------------------------------------------------- 1 | - title: "Quarkus Insight - What is Quarkus Roq?" 2 | description: "Andy Damevin, Matheus Cruz and Melloware join us to discuss Quarkus Roq, which includes tooling for generating a static website with Quarkus." 3 | date: "2024-11-11" 4 | link: https://www.youtube.com/quarkusio/live 5 | - title: "Roq 1.0" 6 | description: "Roq 1.0 is out, it's time to Roq with blogs!" 7 | date: "2024-10-31" 8 | link: https://docs.quarkiverse.io/quarkus-roq/dev/index.html#generate 9 | - title: "Roq 1.0 Beta" 10 | description: "You can start building your site or blog with Roq. More features will come to cover all the needs you can expect from an awesome SSG!" 11 | date: "2024-10-20" 12 | -------------------------------------------------------------------------------- /blog/data/menu.yml: -------------------------------------------------------------------------------- 1 | nav: 2 | - title: "Blog" 3 | path: "/" 4 | icon: "fa-regular fa-newspaper" 5 | - title: "Events" 6 | path: "/events/" 7 | icon: "fa fa-calendar" 8 | - title: "About" 9 | path: "/about/" 10 | icon: "fa fa-thumbs-up" 11 | - title: "Roqers" 12 | path: "/roqers/" 13 | icon: "fa fa-guitar" 14 | doc: 15 | - title: "Getting Started" 16 | path: "/docs/getting-started/" 17 | icon: "fa fa-bolt" 18 | - title: "Roq the Basics" 19 | path: "/docs/basics/" 20 | icon: "fa fa-guitar" 21 | - title: "Publishing" 22 | path: "/docs/publishing/" 23 | icon: "fa fa-rocket" 24 | - title: "Plugins" 25 | path: "/docs/plugins/" 26 | icon: "fa-solid fa-hill-rockslide" 27 | - title: "Advanced stuff" 28 | path: "/docs/advanced/" 29 | icon: "fa-solid fa-truck-monster" 30 | 31 | -------------------------------------------------------------------------------- /blog/public/googlefb811abf43ab0eb2.html: -------------------------------------------------------------------------------- 1 | google-site-verification: googlefb811abf43ab0eb2.html -------------------------------------------------------------------------------- /blog/public/images/iamroq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/public/images/iamroq.png -------------------------------------------------------------------------------- /blog/public/images/ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/public/images/ico.png -------------------------------------------------------------------------------- /blog/public/images/roq-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/public/images/roq-icon.png -------------------------------------------------------------------------------- /blog/public/images/tagging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/blog/public/images/tagging.png -------------------------------------------------------------------------------- /blog/src/main/asciidoc-templates/document.html.slim: -------------------------------------------------------------------------------- 1 | - if document.attributes['toc'] 2 | - toc = converter.convert(document, 'toc') 3 | div.asciidoc 4 | aside.toc.sidebar 5 | div.toc-menu 6 | = toc 7 | article.doc.asciidoctor 8 | h1.page = document.doctitle 9 | aside.toc.embedded 10 | h3 Contents 11 | = toc 12 | = content 13 | - else 14 | div.asciidoc 15 | article.doc.asciidoctor 16 | h1.page = document.doctitle 17 | = content 18 | -------------------------------------------------------------------------------- /blog/src/main/java/Events.java: -------------------------------------------------------------------------------- 1 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 2 | import java.time.LocalDate; 3 | import java.util.List; 4 | 5 | @DataMapping(value = "events", parentArray = true) 6 | public record Events(List list) { 7 | 8 | public record Event(String title, String description, String date, String link) { 9 | 10 | public LocalDate parsedDate() { 11 | return LocalDate.parse(date); 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /blog/src/main/resources/messages/roq_theme_en.properties: -------------------------------------------------------------------------------- 1 | contact_title=Social -------------------------------------------------------------------------------- /blog/src/main/resources/web/app/main.js: -------------------------------------------------------------------------------- 1 | import hljs from 'highlight.js'; 2 | import 'highlight.js/scss/a11y-dark.scss'; 3 | 4 | hljs.highlightAll(); -------------------------------------------------------------------------------- /blog/templates/layouts/doc.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: :theme/main 3 | bodyClass: documentation 4 | --- 5 | 6 | {#insert /} -------------------------------------------------------------------------------- /blog/templates/layouts/roq-default/default.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: theme-layouts/roq-default/default 3 | --- 4 | 5 | {#insert /} 6 | 7 | {#head} 8 | {#search-script /} 9 | 10 | 11 | 12 | {/} 13 | 14 | -------------------------------------------------------------------------------- /blog/templates/layouts/roq-default/main.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: theme-layouts/roq-default/main 3 | --- 4 | 5 | {#search-overlay /} 6 | {#insert /} 7 | 8 | {#menu} 9 | {#search-button /} 10 | {#include partials/roq-default/sidebar-menu menu=cdi:menu.nav /} 11 | {#include partials/roq-default/sidebar-menu menu=cdi:menu.doc menuTitle="Doc" /} 12 | {/} 13 | 14 | {#footer} 15 | 24 | {/} -------------------------------------------------------------------------------- /blog/templates/layouts/roq-default/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: theme-layouts/roq-default/post 3 | --- 4 | 5 | {@io.quarkiverse.roq.frontmatter.runtime.model.DocumentPage page} 6 | 7 | {#include partials/roq-series /} 8 | 9 | {#insert /} 10 | 11 | {#article-end} 12 |
13 | 28 | {/} 29 | -------------------------------------------------------------------------------- /blog/templates/partials/doc/doc-attributes.adoc: -------------------------------------------------------------------------------- 1 | :toc: macro 2 | :toc-title: Contents 3 | :sectanchors: true 4 | :toclevels: 1 5 | :title: {page.title} -------------------------------------------------------------------------------- /blog/templates/partials/doc/edit-contrib.adoc: -------------------------------------------------------------------------------- 1 | NOTE: If you find any issue or missing info, be awesome and link:https://github.com/quarkiverse/quarkus-roq/edit/main/blog/content/docs/{name}.adoc[edit this document] to help others Roqers. 2 | -------------------------------------------------------------------------------- /blog/templates/partials/doc/start-roq.adoc: -------------------------------------------------------------------------------- 1 | 2 | 1. 👉 *Install* the https://quarkus.io/guides/cli-tooling[Quarkus CLI,window=_blank]. 3 | 2. 🚀 **Generate the starter app** using the CLI (you can change the name), or via https://code.quarkus.io/?a=roq-with-blog&e=io.quarkiverse.roq%3Aquarkus-roq[code.quarkus.io,window=_blank] 4 | + 5 | [source,shell] 6 | ---- 7 | quarkus create app roq-with-blog -x=io.quarkiverse.roq:quarkus-roq 8 | ---- 9 | 10 | 3. 🎮 *start dev-mode*: 11 | + 12 | [source,shell] 13 | ---- 14 | cd roq-with-blog 15 | quarkus dev 16 | ---- 17 | 18 | 4. 💻 Your site is available on *link:http://localhost:8080[localhost,window=_blank]* for dev 19 | 5. 🍾 Time to **link:{site.url('docs/basics/')}[Roq the basics]**! 20 | 6. ☀️ If you found some happiness with Roq, please support us: 21 | + 22 | ++++ 23 |
24 | Star 25 | ++++ 26 | -------------------------------------------------------------------------------- /blog/templates/partials/github-pages.adoc: -------------------------------------------------------------------------------- 1 | [[github-pages]] 2 | == Deploy to GitHub Pages 3 | 4 | Check if you already have the `.github/workflows/deploy.yml` file, if you don't create it: 5 | 6 | ..github/workflows/deploy.yml 7 | [source,yaml] 8 | ---- 9 | ## Deploy to GH-Pages for your Quarkus Roq blog. 10 | name: Roq Site Deploy 11 | 12 | on: 13 | push: 14 | branches: [ main ] # Switch to the branch which should be deployed to GitHub Pages 15 | workflow_dispatch: 16 | 17 | jobs: 18 | build: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - uses: actions/checkout@v4 22 | - name: Generate Roq Site 23 | uses: quarkiverse/quarkus-roq@v1 24 | with: 25 | github-token: ${{ secrets.GITHUB_TOKEN }} # Used to automatically get the GitHub Pages url 26 | deploy: 27 | environment: 28 | name: github-pages 29 | url: ${{ steps.deployment.outputs.page_url }} 30 | permissions: 31 | pages: write # to deploy to Pages 32 | id-token: write # to verify the deployment originates from an appropriate source 33 | runs-on: ubuntu-latest 34 | needs: build 35 | steps: 36 | - name: Deploy to GitHub Pages 37 | id: deployment 38 | uses: actions/deploy-pages@v4 39 | ---- 40 | 41 | Then to enable GitHub Pages: 42 | 43 | 1. *Open* your GitHub repository page 44 | 2. **Go to** Settings->Page 45 | 3. *Pick:* `Source: GitHub Actions`, that's enough (no save button) 46 | 47 | It's all good, restart your deploy workflow and enjoy! 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /blog/templates/partials/roq-default/sidebar-copyright.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: quarkus-roq 2 | title: Roq 3 | version: dev 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/roq-dirs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/docs/modules/ROOT/assets/images/roq-dirs.png -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/roq-how-it-works.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/docs/modules/ROOT/assets/images/roq-how-it-works.png -------------------------------------------------------------------------------- /docs/modules/ROOT/examples/.keepme: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/docs/modules/ROOT/examples/.keepme -------------------------------------------------------------------------------- /docs/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Static Site Generator] 2 | * xref:quarkus-roq-data.adoc[Data] 3 | * xref:quarkus-roq-frontmatter.adoc[FrontMatter] 4 | * xref:quarkus-roq-generator.adoc[Generator] -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/_includes/attributes.adoc: -------------------------------------------------------------------------------- 1 | :project-version: 1.6.0 2 | 3 | :examples-dir: ./../examples/ -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/_includes/quarkus-roq-plugin-tagging.adoc: -------------------------------------------------------------------------------- 1 | [.configuration-legend] 2 | icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime 3 | [.configuration-reference.searchable, cols="80,.^10,.^10"] 4 | |=== 5 | 6 | h|[.header-title]##Configuration property## 7 | h|Type 8 | h|Default 9 | 10 | a|icon:lock[title=Fixed at build time] [[quarkus-roq-plugin-tagging_quarkus-roq-tagging-lowercase]] [.property-path]##link:#quarkus-roq-plugin-tagging_quarkus-roq-tagging-lowercase[`quarkus.roq.tagging.lowercase`]## 11 | ifdef::add-copy-button-to-config-props[] 12 | config_property_copy_button:+++quarkus.roq.tagging.lowercase+++[] 13 | endif::add-copy-button-to-config-props[] 14 | 15 | 16 | [.description] 17 | -- 18 | When true, all selected tags are transformed to lowercase. 19 | 20 | 21 | ifdef::add-copy-button-to-env-var[] 22 | Environment variable: env_var_with_copy_button:+++QUARKUS_ROQ_TAGGING_LOWERCASE+++[] 23 | endif::add-copy-button-to-env-var[] 24 | ifndef::add-copy-button-to-env-var[] 25 | Environment variable: `+++QUARKUS_ROQ_TAGGING_LOWERCASE+++` 26 | endif::add-copy-button-to-env-var[] 27 | -- 28 | |boolean 29 | |`false` 30 | 31 | |=== 32 | 33 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/_includes/quarkus-roq-plugin-tagging_quarkus.roq.adoc: -------------------------------------------------------------------------------- 1 | [.configuration-legend] 2 | icon:lock[title=Fixed at build time] Configuration property fixed at build time - All other configuration properties are overridable at runtime 3 | [.configuration-reference.searchable, cols="80,.^10,.^10"] 4 | |=== 5 | 6 | h|[.header-title]##Configuration property## 7 | h|Type 8 | h|Default 9 | 10 | a|icon:lock[title=Fixed at build time] [[quarkus-roq-plugin-tagging_quarkus-roq-tagging-lowercase]] [.property-path]##link:#quarkus-roq-plugin-tagging_quarkus-roq-tagging-lowercase[`quarkus.roq.tagging.lowercase`]## 11 | ifdef::add-copy-button-to-config-props[] 12 | config_property_copy_button:+++quarkus.roq.tagging.lowercase+++[] 13 | endif::add-copy-button-to-config-props[] 14 | 15 | 16 | [.description] 17 | -- 18 | When true, all selected tags are transformed to lowercase. 19 | 20 | 21 | ifdef::add-copy-button-to-env-var[] 22 | Environment variable: env_var_with_copy_button:+++QUARKUS_ROQ_TAGGING_LOWERCASE+++[] 23 | endif::add-copy-button-to-env-var[] 24 | ifndef::add-copy-button-to-env-var[] 25 | Environment variable: `+++QUARKUS_ROQ_TAGGING_LOWERCASE+++` 26 | endif::add-copy-button-to-env-var[] 27 | -- 28 | |boolean 29 | |`false` 30 | 31 | |=== 32 | 33 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | include::./_includes/attributes.adoc[] 2 | 3 | = Quarkus Roq 4 | 5 | Roq allows to easily create a static website or blog using Quarkus super-powers. 6 | 7 | The documentation is available in the https://iamroq.com/docs/[Roq website]. 8 | 9 | Roq depends on a set of extensions which can also be used standalone: 10 | 11 | * xref:quarkus-roq-data.adoc[*Roq Data*]: Use json/yaml files content from your templates and articles with type safety. 12 | * xref:quarkus-roq-frontmatter.adoc[*Roq FrontMatter*]: Create a website from your Markdown/Asciidoc/Html pages using FrontMatter headers (url, layout, seo, data). 13 | * xref:quarkus-roq-generator.adoc[*Roq Generator*]: Command to run any Quarkus web application and extract it in a directory as purely static files (html and assets). 14 | 15 | [[extension-configuration-reference]] 16 | == Extension Configuration Reference 17 | 18 | include::_includes/quarkus-roq-frontmatter_site.adoc[leveloffset=+1, opts=optional] 19 | 20 | include::_includes/quarkus-roq.adoc[leveloffset=+1, opts=optional] 21 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/quarkus-roq-frontmatter.adoc: -------------------------------------------------------------------------------- 1 | include::./_includes/attributes.adoc[] 2 | 3 | = Quarkus Roq FrontMatter 4 | 5 | Quarkus Roq FrontMatter is a Quarkus extension that create a website from your Markdown/Asciidoc/Html pages using FrontMatter headers (url, layout, seo, data). 6 | 7 | The documentation is available in the https://iamroq.com/docs/[Roq website]. 8 | 9 | CAUTION: Roq FrontMatter is already included as part of the Roq Static Site Generator extension `io.quarkiverse.roq:quarkus-roq`, Follow <> section to use it standalone. 10 | 11 | [[standalone-installation]] 12 | == Standalone installation 13 | 14 | NOTE: It is included as part of the Roq Static Site Generator extension `io.quarkiverse.roq:quarkus-roq`. You can also use it standalone. 15 | 16 | If you want to use this extension standalone, you need to add the `io.quarkiverse.roq:quarkus-roq-frontmatter` extension first to your build file. 17 | 18 | For instance, with Maven, add the following dependency to your POM file: 19 | 20 | [source,xml,subs=attributes+] 21 | ---- 22 | 23 | io.quarkiverse.roq 24 | quarkus-roq-frontmatter 25 | {project-version} 26 | 27 | ---- 28 | 29 | [[extension-configuration-reference]] 30 | == Extension Configuration Reference 31 | 32 | include::_includes/quarkus-roq-frontmatter_quarkus.roq.adoc[leveloffset=+1, opts=optional] 33 | 34 | include::_includes/quarkus-roq-frontmatter_roq.site.adoc[leveloffset=+1, opts=optional] 35 | -------------------------------------------------------------------------------- /docs/templates/includes/attributes.adoc: -------------------------------------------------------------------------------- 1 | :project-version: ${release.current-version} 2 | 3 | :examples-dir: ./../examples/ -------------------------------------------------------------------------------- /jbang-catalog.json: -------------------------------------------------------------------------------- 1 | { 2 | "catalogs": {}, 3 | "aliases": { 4 | "roq": { 5 | "description": "Serve the generated static website locally", 6 | "script-ref": "roq.java" 7 | } 8 | }, 9 | "templates": {} 10 | } -------------------------------------------------------------------------------- /logo/.gitignore: -------------------------------------------------------------------------------- 1 | *.afdesign~lock~ -------------------------------------------------------------------------------- /logo/out/ico.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/logo/out/ico.png -------------------------------------------------------------------------------- /logo/out/roq-icon-100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/logo/out/roq-icon-100.png -------------------------------------------------------------------------------- /logo/out/roq-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/logo/out/roq-icon.png -------------------------------------------------------------------------------- /logo/out/roq-logo-reversed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/logo/out/roq-logo-reversed.png -------------------------------------------------------------------------------- /logo/roq-icon.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/logo/roq-icon.afdesign -------------------------------------------------------------------------------- /logo/roq.afdesign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/logo/roq.afdesign -------------------------------------------------------------------------------- /roq-common/deployment/src/main/java/io/quarkiverse/roq/deployment/config/RoqConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.deployment.config; 2 | 3 | import java.util.Optional; 4 | 5 | import io.quarkus.runtime.annotations.ConfigPhase; 6 | import io.quarkus.runtime.annotations.ConfigRoot; 7 | import io.smallrye.config.ConfigMapping; 8 | import io.smallrye.config.WithName; 9 | 10 | @ConfigMapping(prefix = "quarkus.roq") 11 | @ConfigRoot(phase = ConfigPhase.BUILD_TIME) 12 | public interface RoqConfig { 13 | 14 | String DEFAULT_DIR = ""; // {project-dir}/ 15 | String DEFAULT_RESOURCE_DIR = ""; // src/main/resources/ 16 | 17 | /** 18 | * Path to the Roq directory (relative to the project root). 19 | */ 20 | @WithName("dir") 21 | Optional dirOptional(); 22 | 23 | default String dir() { 24 | return dirOptional().orElse(DEFAULT_DIR); 25 | } 26 | 27 | /** 28 | * Path to the Roq directory in the resources. 29 | */ 30 | @WithName("resource-dir") 31 | Optional resourceDirOptional(); 32 | 33 | default String resourceDir() { 34 | return resourceDirOptional().orElse(DEFAULT_RESOURCE_DIR); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /roq-common/deployment/src/main/java/io/quarkiverse/roq/deployment/items/RoqJacksonBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.deployment.items; 2 | 3 | import com.fasterxml.jackson.databind.json.JsonMapper; 4 | import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; 5 | 6 | import io.quarkus.builder.item.SimpleBuildItem; 7 | 8 | public final class RoqJacksonBuildItem extends SimpleBuildItem { 9 | 10 | private final JsonMapper jsonMapper; 11 | private final YAMLMapper yamlMapper; 12 | 13 | public RoqJacksonBuildItem(JsonMapper jsonMapper, YAMLMapper yamlMapper) { 14 | this.jsonMapper = jsonMapper; 15 | this.yamlMapper = yamlMapper; 16 | } 17 | 18 | public JsonMapper getJsonMapper() { 19 | return jsonMapper; 20 | } 21 | 22 | public YAMLMapper getYamlMapper() { 23 | return yamlMapper; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /roq-common/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-common-parent 12 | pom 13 | Quarkus Roq - Common - Parent 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-common/runtime/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-common-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-common 12 | Quarkus Roq - Common 13 | 14 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/DataConverter.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | public interface DataConverter { 7 | 8 | Object convert(byte[] content) throws IOException; 9 | 10 | T convertToType(byte[] content, Class clazz) throws IOException; 11 | 12 | List convertToTypedList(byte[] content, Class clazz) throws IOException; 13 | } 14 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/RoqDataConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment; 2 | 3 | import java.util.Objects; 4 | 5 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 6 | import io.quarkus.runtime.annotations.ConfigPhase; 7 | import io.quarkus.runtime.annotations.ConfigRoot; 8 | import io.smallrye.config.ConfigMapping; 9 | import io.smallrye.config.WithDefault; 10 | 11 | @ConfigMapping(prefix = "quarkus.roq.data") 12 | @ConfigRoot(phase = ConfigPhase.BUILD_TIME) 13 | public interface RoqDataConfig { 14 | 15 | String DEFAULT_DIR = "data"; 16 | 17 | /** 18 | * The location of the Roq data files relative to the quarkus.roq.dir. 19 | */ 20 | @WithDefault(DEFAULT_DIR) 21 | String dir(); 22 | 23 | /** 24 | * Whether to enforce the use of a bean for each data file. 25 | *
26 | * With this option enabled, when a record is annotated with {@link DataMapping}, a bean will be created and populated 27 | * with the data from the file. 28 | */ 29 | @WithDefault("false") 30 | boolean enforceBean(); 31 | 32 | /** 33 | * Log data beans as info during build 34 | */ 35 | @WithDefault("true") 36 | boolean logDataBeans(); 37 | 38 | static boolean isEqual(RoqDataConfig q1, RoqDataConfig q2) { 39 | return Objects.equals(q1.dir(), q2.dir()) && Objects.equals(q1.enforceBean(), q2.enforceBean()); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/converters/DataConverterFinder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.converters; 2 | 3 | import java.util.Map; 4 | 5 | import com.fasterxml.jackson.databind.json.JsonMapper; 6 | import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; 7 | 8 | import io.quarkiverse.roq.data.deployment.DataConverter; 9 | 10 | public final class DataConverterFinder { 11 | 12 | private final Map converterByExtension; 13 | 14 | public DataConverterFinder(JsonMapper jsonMapper, YAMLMapper yamlMapper) { 15 | DataConverter jsonConverter = new JsonConverter(jsonMapper); 16 | DataConverter yamlConverter = new YamlConverter(yamlMapper); 17 | this.converterByExtension = Map.of( 18 | "yaml", yamlConverter, 19 | "yml", yamlConverter, 20 | "json", jsonConverter); 21 | } 22 | 23 | public DataConverter fromFileName(String fileName) { 24 | if (!fileName.contains(".")) { 25 | return null; 26 | } 27 | final String extension = fileName.substring(fileName.lastIndexOf(".") + 1); 28 | return converterByExtension.get(extension); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/converters/JsonConverter.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.converters; 2 | 3 | import java.io.IOException; 4 | import java.util.List; 5 | 6 | import com.fasterxml.jackson.databind.JavaType; 7 | import com.fasterxml.jackson.databind.json.JsonMapper; 8 | import com.fasterxml.jackson.databind.type.CollectionType; 9 | 10 | import io.quarkiverse.roq.data.deployment.DataConverter; 11 | import io.vertx.core.buffer.Buffer; 12 | import io.vertx.core.json.Json; 13 | 14 | public class JsonConverter implements DataConverter { 15 | 16 | private final JsonMapper mapper; 17 | 18 | public JsonConverter(JsonMapper mapper) { 19 | this.mapper = mapper; 20 | } 21 | 22 | @Override 23 | public Object convert(byte[] content) { 24 | return Json.decodeValue(Buffer.buffer(content)); 25 | } 26 | 27 | @Override 28 | public T convertToType(byte[] content, Class clazz) throws IOException { 29 | final JavaType javaType = mapper.getTypeFactory().constructType(clazz); 30 | return mapper.readValue(content, javaType); 31 | } 32 | 33 | @Override 34 | public List convertToTypedList(byte[] content, Class clazz) throws IOException { 35 | final CollectionType collectionType = mapper.getTypeFactory().constructCollectionType(List.class, clazz); 36 | return mapper.readValue(content, collectionType); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/exception/DataConflictException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.exception; 2 | 3 | public class DataConflictException extends RuntimeException { 4 | 5 | public DataConflictException(String message) { 6 | super(message); 7 | } 8 | 9 | public DataConflictException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/exception/DataConversionException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.exception; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | 6 | public class DataConversionException extends UncheckedIOException { 7 | 8 | public DataConversionException(String message, IOException cause) { 9 | super(message, cause); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/exception/DataListBindingException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.exception; 2 | 3 | public class DataListBindingException extends RuntimeException { 4 | 5 | public DataListBindingException(String message) { 6 | super(message); 7 | } 8 | 9 | public DataListBindingException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/exception/DataMappingMismatchException.java: -------------------------------------------------------------------------------- 1 | 2 | package io.quarkiverse.roq.data.deployment.exception; 3 | 4 | public class DataMappingMismatchException extends RuntimeException { 5 | 6 | public DataMappingMismatchException(String message) { 7 | super(message); 8 | } 9 | 10 | public DataMappingMismatchException(String message, Throwable cause) { 11 | super(message, cause); 12 | } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/exception/DataMappingRequiredFileException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.exception; 2 | 3 | public class DataMappingRequiredFileException extends RuntimeException { 4 | public DataMappingRequiredFileException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/exception/DataReadingException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.exception; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | 6 | public class DataReadingException extends UncheckedIOException { 7 | public DataReadingException(String message, IOException cause) { 8 | super(message, cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/exception/DataScanningException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.exception; 2 | 3 | import java.io.IOException; 4 | import java.io.UncheckedIOException; 5 | 6 | public class DataScanningException extends UncheckedIOException { 7 | public DataScanningException(String message, IOException cause) { 8 | super(message, cause); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /roq-data/deployment/src/main/java/io/quarkiverse/roq/data/deployment/items/RoqDataJsonBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.deployment.items; 2 | 3 | import java.util.Objects; 4 | 5 | import io.quarkus.builder.item.MultiBuildItem; 6 | 7 | /** 8 | * A build item representing a Roq data file. 9 | */ 10 | public final class RoqDataJsonBuildItem extends MultiBuildItem { 11 | 12 | /** 13 | * The name of the Roq data file. 14 | */ 15 | private final String name; 16 | 17 | /** 18 | * The content of the Roq data file as a JSON string. 19 | */ 20 | private final Object data; 21 | 22 | public RoqDataJsonBuildItem(String name, Object data) { 23 | this.name = name; 24 | this.data = data; 25 | } 26 | 27 | public String getName() { 28 | return name; 29 | } 30 | 31 | public Object getData() { 32 | return data; 33 | } 34 | 35 | @Override 36 | public boolean equals(Object object) { 37 | if (this == object) 38 | return true; 39 | if (object == null || getClass() != object.getClass()) 40 | return false; 41 | RoqDataJsonBuildItem that = (RoqDataJsonBuildItem) object; 42 | return Objects.equals(name, that.name) && Objects.equals(data, that.data); 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | return Objects.hash(name, data); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/DataMappingRequiredDataFileTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test; 2 | 3 | import org.assertj.core.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import org.junit.jupiter.api.extension.RegisterExtension; 6 | 7 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 8 | import io.quarkus.test.QuarkusUnitTest; 9 | 10 | public class DataMappingRequiredDataFileTest { 11 | 12 | @RegisterExtension 13 | static final QuarkusUnitTest unitTest = new QuarkusUnitTest() 14 | .withApplicationRoot((jar) -> jar 15 | .addClass(DataMappingRequiredDataFileTest.Person.class)) 16 | .assertException(throwable -> { 17 | Assertions.assertThat(throwable) 18 | .hasMessage("The @DataMapping#value(foo) is required, but there is no corresponding data file"); 19 | }); 20 | 21 | @DataMapping(value = "foo", required = true) 22 | public record Person(String name) { 23 | } 24 | 25 | @Test 26 | public void assertFail() { 27 | 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/RoqDataBindingEnforceBeanDataFileSideTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.jboss.shrinkwrap.api.asset.StringAsset; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | import org.junit.jupiter.api.extension.RegisterExtension; 9 | 10 | import io.quarkus.test.QuarkusUnitTest; 11 | 12 | public class RoqDataBindingEnforceBeanDataFileSideTest { 13 | 14 | @RegisterExtension 15 | static final QuarkusUnitTest quarkusUnitTest = new QuarkusUnitTest() 16 | .withApplicationRoot((jar) -> jar 17 | .add(new StringAsset("quarkus.roq.dir=src/test/roq\nquarkus.roq.data.enforce-bean=true"), 18 | "application.properties")) 19 | .assertException(e -> { 20 | assertThat(e).isInstanceOf(RuntimeException.class) 21 | .hasMessageContaining( 22 | "Some data mappings and data files do not match:") 23 | .hasMessageContaining("The data file 'bar' does not match with any @DataMapping class"); 24 | }); 25 | 26 | @Test 27 | void test() { 28 | Assertions.assertTrue(false); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/RoqDataBindingEnforceBeanDataMappingSideTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test; 2 | 3 | import static org.assertj.core.api.Assertions.assertThat; 4 | 5 | import org.jboss.shrinkwrap.api.asset.StringAsset; 6 | import org.junit.jupiter.api.Assertions; 7 | import org.junit.jupiter.api.Test; 8 | import org.junit.jupiter.api.extension.RegisterExtension; 9 | 10 | import io.quarkiverse.roq.data.deployment.exception.DataMappingMismatchException; 11 | import io.quarkiverse.roq.data.test.util.Bar; 12 | import io.quarkus.test.QuarkusUnitTest; 13 | 14 | public class RoqDataBindingEnforceBeanDataMappingSideTest { 15 | 16 | @RegisterExtension 17 | static final QuarkusUnitTest quarkusUnitTest = new QuarkusUnitTest() 18 | .withApplicationRoot((jar) -> jar 19 | .addClass(Bar.class) 20 | .add(new StringAsset("quarkus.roq.dir=src/test/site\nquarkus.roq.data.enforce-bean=true"), 21 | "application.properties")) 22 | .assertException(e -> { 23 | assertThat(e).isInstanceOf(DataMappingMismatchException.class) 24 | .hasMessageContaining( 25 | "Some data mappings and data files do not match:") 26 | .hasMessageContaining("The @DataMapping#value('why') does not match with any data file"); 27 | }); 28 | 29 | @Test 30 | void test() { 31 | Assertions.assertTrue(false); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/util/Bar.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test.util; 2 | 3 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 4 | 5 | @DataMapping("why") 6 | public record Bar(String style) { 7 | } 8 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/util/Foo.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test.util; 2 | 3 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 4 | 5 | @DataMapping("foo") 6 | public record Foo(String name) { 7 | @Override 8 | public String toString() { 9 | // Original is Foo[name=Super Heroes from Json] 10 | return this.name; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/util/Foos.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test.util; 2 | 3 | import java.util.List; 4 | 5 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 6 | 7 | @DataMapping(value = "foos", parentArray = true) 8 | public record Foos(List list) { 9 | } 10 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/util/Item.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test.util; 2 | 3 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 4 | 5 | @DataMapping("list") 6 | public class Item { 7 | 8 | private String name; 9 | 10 | public String getName() { 11 | return name; 12 | } 13 | 14 | public void setName(String name) { 15 | this.name = name; 16 | } 17 | 18 | @Override 19 | public String toString() { 20 | return name; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/java/io/quarkiverse/roq/data/test/util/ItemRecord.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.test.util; 2 | 3 | import io.quarkiverse.roq.data.runtime.annotations.DataMapping; 4 | 5 | @DataMapping("list") 6 | public record ItemRecord(String name) { 7 | } 8 | -------------------------------------------------------------------------------- /roq-data/deployment/src/test/resources/foo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Super Heroes from Json" 3 | } -------------------------------------------------------------------------------- /roq-data/deployment/src/test/resources/fromResource.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Hello from resource" 3 | } -------------------------------------------------------------------------------- /roq-data/deployment/src/test/roq/data/bar.yaml: -------------------------------------------------------------------------------- 1 | name: Super Heroes from Yaml -------------------------------------------------------------------------------- /roq-data/deployment/src/test/roq/data/baz.yml: -------------------------------------------------------------------------------- 1 | name: Super Heroes from Yml -------------------------------------------------------------------------------- /roq-data/deployment/src/test/roq/data/foo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Super Heroes from Json" 3 | } -------------------------------------------------------------------------------- /roq-data/deployment/src/test/roq/data/foos.yaml: -------------------------------------------------------------------------------- 1 | - name: Super Heroes 1 from Yaml 2 | - name: Super Heroes 2 from Yaml 3 | - name: Super Heroes 3 from Yaml -------------------------------------------------------------------------------- /roq-data/deployment/src/test/roq/data/list.yaml: -------------------------------------------------------------------------------- 1 | - name: Super Heroes 1 from Yaml 2 | - name: Super Heroes 2 from Yaml 3 | - name: Super Heroes 3 from Yaml -------------------------------------------------------------------------------- /roq-data/deployment/test-data/bar.yaml: -------------------------------------------------------------------------------- 1 | name: Super Heroes from Yaml custom -------------------------------------------------------------------------------- /roq-data/deployment/test-data/baz.yml: -------------------------------------------------------------------------------- 1 | name: Super Heroes from Yml custom -------------------------------------------------------------------------------- /roq-data/deployment/test-data/foo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Super Heroes from Json custom" 3 | } -------------------------------------------------------------------------------- /roq-data/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-data-parent 12 | pom 13 | Quarkus Roq - Data 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-data/runtime/src/main/java/io/quarkiverse/roq/data/runtime/RoqDataRecorder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.runtime; 2 | 3 | import io.quarkus.runtime.RuntimeValue; 4 | import io.quarkus.runtime.annotations.Recorder; 5 | 6 | @Recorder 7 | public class RoqDataRecorder { 8 | 9 | public RuntimeValue createRoqDataJson(Object data) { 10 | return new RuntimeValue<>(data); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /roq-data/runtime/src/main/java/io/quarkiverse/roq/data/runtime/annotations/DataMapping.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.data.runtime.annotations; 2 | 3 | import java.lang.annotation.Documented; 4 | import java.lang.annotation.ElementType; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * Annotation used to indicate that a class is a data mapping. 11 | */ 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ ElementType.TYPE }) 14 | @Documented 15 | public @interface DataMapping { 16 | 17 | /** 18 | * Indicates the name of the data file, excluding the file extension. 19 | * This name should match the data source file used for mapping purposes. 20 | * 21 | * @return the data file name without its extension 22 | */ 23 | String value(); 24 | 25 | /** 26 | * Indicates if the root element of the data file is structured as an array. 27 | * Set this to {@code true} if the root element is an array; otherwise, {@code false}. 28 | * 29 | * @return {@code true} if the root element is an array, {@code false} otherwise 30 | */ 31 | boolean parentArray() default false; 32 | 33 | /** 34 | * Defines whether the corresponding data file is required. 35 | * 36 | * @return {@code true} if the data file is mandatory, {@code false} if it's optional. 37 | */ 38 | boolean required() default false; 39 | } 40 | -------------------------------------------------------------------------------- /roq-data/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Data 2 | description: Use json/yaml files content from your templates and articles with type safety. 3 | metadata: 4 | keywords: 5 | - json 6 | - yaml 7 | - roq 8 | - ssg 9 | - data 10 | - static 11 | guide: https://docs.quarkiverse.io/quarkus-roq/dev/quarkus-roq-data.html 12 | categories: 13 | - "web" 14 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 15 | config: 16 | - "quarkus.roq" 17 | status: "preview" -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/Paginate.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment; 2 | 3 | public record Paginate(int size, String link, String collection) { 4 | public Paginate { 5 | if (size < 1) { 6 | throw new IllegalArgumentException("Paginate size cannot be lower than 1"); 7 | } 8 | if (link == null) { 9 | throw new IllegalArgumentException("Paginate link cannot be null"); 10 | } 11 | if (collection == null) { 12 | throw new IllegalArgumentException("Paginate collection cannot be null"); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterOutputBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment; 2 | 3 | import java.util.Map; 4 | import java.util.function.Supplier; 5 | 6 | import io.quarkiverse.roq.frontmatter.runtime.model.Page; 7 | import io.quarkus.builder.item.SimpleBuildItem; 8 | 9 | public final class RoqFrontMatterOutputBuildItem extends SimpleBuildItem { 10 | 11 | private final Map> allPagesByPath; 12 | 13 | public RoqFrontMatterOutputBuildItem(Map> allPagesByPath) { 14 | this.allPagesByPath = allPagesByPath; 15 | } 16 | 17 | public Map> allPagesByPath() { 18 | return allPagesByPath; 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/RoqFrontMatterRootUrlBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment; 2 | 3 | import io.quarkiverse.roq.frontmatter.runtime.model.RootUrl; 4 | import io.quarkus.builder.item.SimpleBuildItem; 5 | 6 | public final class RoqFrontMatterRootUrlBuildItem extends SimpleBuildItem { 7 | 8 | private final RootUrl rootUrl; 9 | 10 | public RoqFrontMatterRootUrlBuildItem(RootUrl rootUrl) { 11 | this.rootUrl = rootUrl; 12 | } 13 | 14 | public RootUrl rootUrl() { 15 | return rootUrl; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterPaginateTemplateBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.data; 2 | 3 | import io.quarkiverse.roq.frontmatter.runtime.config.ConfiguredCollection; 4 | import io.quarkiverse.roq.frontmatter.runtime.model.PageInfo; 5 | import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; 6 | import io.quarkus.builder.item.MultiBuildItem; 7 | import io.vertx.core.json.JsonObject; 8 | 9 | public final class RoqFrontMatterPaginateTemplateBuildItem extends MultiBuildItem { 10 | 11 | private final PageInfo info; 12 | private final ConfiguredCollection paginatedCollection; 13 | private final RoqUrl url; 14 | private final JsonObject data; 15 | 16 | public RoqFrontMatterPaginateTemplateBuildItem(RoqUrl url, PageInfo info, JsonObject data, 17 | ConfiguredCollection paginatedCollection) { 18 | this.info = info; 19 | this.paginatedCollection = paginatedCollection; 20 | this.url = url; 21 | this.data = data; 22 | } 23 | 24 | public ConfiguredCollection defaultPaginatedCollection() { 25 | return paginatedCollection; 26 | } 27 | 28 | public PageInfo info() { 29 | return info; 30 | } 31 | 32 | public RoqUrl url() { 33 | return url; 34 | } 35 | 36 | public JsonObject data() { 37 | return data; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/data/RoqFrontMatterTemplateBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.data; 2 | 3 | import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterRawTemplateBuildItem; 4 | import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; 5 | import io.quarkus.builder.item.MultiBuildItem; 6 | import io.vertx.core.json.JsonObject; 7 | 8 | /** 9 | * A build item representing a Roq FM file with the data already processed. 10 | * This is meant for reading purpose. 11 | */ 12 | public final class RoqFrontMatterTemplateBuildItem extends MultiBuildItem { 13 | private final RoqFrontMatterRawTemplateBuildItem raw; 14 | private final RoqUrl url; 15 | private final JsonObject data; 16 | 17 | RoqFrontMatterTemplateBuildItem(RoqFrontMatterRawTemplateBuildItem raw, RoqUrl url, JsonObject data) { 18 | this.raw = raw; 19 | this.url = url; 20 | this.data = data; 21 | } 22 | 23 | public boolean published() { 24 | return raw.published(); 25 | } 26 | 27 | public RoqFrontMatterRawTemplateBuildItem raw() { 28 | return raw; 29 | } 30 | 31 | public RoqUrl url() { 32 | return url; 33 | } 34 | 35 | public JsonObject data() { 36 | return data; 37 | } 38 | 39 | public boolean isPage() { 40 | return raw.isPage(); 41 | } 42 | 43 | public boolean isLayout() { 44 | return raw.isLayout(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqFrontMatterReadingException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqFrontMatterReadingException extends RuntimeException { 4 | 5 | public RoqFrontMatterReadingException(String message) { 6 | super(message); 7 | } 8 | 9 | public RoqFrontMatterReadingException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqLayoutNotFoundException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqLayoutNotFoundException extends RuntimeException { 4 | 5 | public RoqLayoutNotFoundException(String message) { 6 | super(message); 7 | } 8 | 9 | public RoqLayoutNotFoundException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqPathConflictException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqPathConflictException extends RuntimeException { 4 | 5 | public RoqPathConflictException(String message) { 6 | super(message); 7 | } 8 | 9 | public RoqPathConflictException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqPluginException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqPluginException extends RuntimeException { 4 | 5 | public RoqPluginException(String message) { 6 | super(message); 7 | } 8 | 9 | public RoqPluginException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqSiteIndexNotFoundException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqSiteIndexNotFoundException extends RuntimeException { 4 | 5 | public RoqSiteIndexNotFoundException(String message) { 6 | super(message); 7 | } 8 | 9 | public RoqSiteIndexNotFoundException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqSiteScanningException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqSiteScanningException extends RuntimeException { 4 | public RoqSiteScanningException(String message, Throwable cause) { 5 | super(message, cause); 6 | } 7 | 8 | public RoqSiteScanningException(String message) { 9 | super(message); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqTemplateLinkException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqTemplateLinkException extends RuntimeException { 4 | public RoqTemplateLinkException(String message) { 5 | super(message); 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/exception/RoqThemeConfigurationException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.exception; 2 | 3 | public class RoqThemeConfigurationException extends RuntimeException { 4 | 5 | public RoqThemeConfigurationException(String message) { 6 | super(message); 7 | } 8 | 9 | public RoqThemeConfigurationException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/publish/RoqFrontMatterPublishDerivedCollectionBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.publish; 2 | 3 | import java.util.List; 4 | 5 | import io.quarkiverse.roq.frontmatter.runtime.config.ConfiguredCollection; 6 | import io.quarkus.builder.item.MultiBuildItem; 7 | import io.vertx.core.json.JsonObject; 8 | 9 | public final class RoqFrontMatterPublishDerivedCollectionBuildItem extends MultiBuildItem { 10 | private final ConfiguredCollection collection; 11 | private final List documentIds; 12 | private final JsonObject data; 13 | 14 | public RoqFrontMatterPublishDerivedCollectionBuildItem(ConfiguredCollection collection, List documentIds, 15 | JsonObject data) { 16 | this.collection = collection; 17 | this.documentIds = documentIds; 18 | this.data = data; 19 | } 20 | 21 | public ConfiguredCollection collection() { 22 | return collection; 23 | } 24 | 25 | public List documentIds() { 26 | return documentIds; 27 | } 28 | 29 | public JsonObject data() { 30 | return data; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/publish/RoqFrontMatterPublishDocumentPageBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.publish; 2 | 3 | import io.quarkiverse.roq.frontmatter.runtime.config.ConfiguredCollection; 4 | import io.quarkiverse.roq.frontmatter.runtime.model.PageInfo; 5 | import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; 6 | import io.quarkus.builder.item.MultiBuildItem; 7 | import io.vertx.core.json.JsonObject; 8 | 9 | public final class RoqFrontMatterPublishDocumentPageBuildItem extends MultiBuildItem { 10 | private final RoqUrl url; 11 | private final PageInfo info; 12 | private final ConfiguredCollection collection; 13 | private final JsonObject data; 14 | 15 | public RoqFrontMatterPublishDocumentPageBuildItem(RoqUrl url, PageInfo info, ConfiguredCollection collection, 16 | JsonObject data) { 17 | this.url = url; 18 | this.info = info; 19 | this.collection = collection; 20 | this.data = data; 21 | } 22 | 23 | public ConfiguredCollection collection() { 24 | return collection; 25 | } 26 | 27 | public RoqUrl url() { 28 | return url; 29 | } 30 | 31 | public PageInfo info() { 32 | return info; 33 | } 34 | 35 | public JsonObject data() { 36 | return data; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/publish/RoqFrontMatterPublishPageBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.publish; 2 | 3 | import io.quarkiverse.roq.frontmatter.runtime.model.PageInfo; 4 | import io.quarkiverse.roq.frontmatter.runtime.model.Paginator; 5 | import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; 6 | import io.quarkus.builder.item.MultiBuildItem; 7 | import io.vertx.core.json.JsonObject; 8 | 9 | public final class RoqFrontMatterPublishPageBuildItem extends MultiBuildItem { 10 | private final RoqUrl url; 11 | private final PageInfo info; 12 | private final JsonObject data; 13 | private final Paginator paginator; 14 | 15 | public RoqFrontMatterPublishPageBuildItem(RoqUrl url, PageInfo info, JsonObject data, Paginator paginator) { 16 | this.url = url; 17 | this.info = info; 18 | this.data = data; 19 | this.paginator = paginator; 20 | } 21 | 22 | public RoqUrl url() { 23 | return url; 24 | } 25 | 26 | public PageInfo info() { 27 | return info; 28 | } 29 | 30 | public JsonObject data() { 31 | return data; 32 | } 33 | 34 | public Paginator paginator() { 35 | return paginator; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterCollectionBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.record; 2 | 3 | import java.util.List; 4 | import java.util.function.Supplier; 5 | 6 | import io.quarkiverse.roq.frontmatter.runtime.config.ConfiguredCollection; 7 | import io.quarkiverse.roq.frontmatter.runtime.model.DocumentPage; 8 | import io.quarkus.builder.item.MultiBuildItem; 9 | 10 | public final class RoqFrontMatterCollectionBuildItem extends MultiBuildItem { 11 | private final ConfiguredCollection collection; 12 | private final List> documents; 13 | 14 | public RoqFrontMatterCollectionBuildItem(ConfiguredCollection collection, List> documents) { 15 | this.collection = collection; 16 | this.documents = documents; 17 | } 18 | 19 | public ConfiguredCollection collection() { 20 | return collection; 21 | } 22 | 23 | public List> documents() { 24 | return documents; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterNormalPageBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.record; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import io.quarkiverse.roq.frontmatter.runtime.model.NormalPage; 6 | import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class RoqFrontMatterNormalPageBuildItem extends MultiBuildItem { 10 | private final String id; 11 | private final RoqUrl url; 12 | private final Supplier page; 13 | 14 | public RoqFrontMatterNormalPageBuildItem(String id, RoqUrl url, Supplier page) { 15 | this.id = id; 16 | this.url = url; 17 | this.page = page; 18 | } 19 | 20 | public String id() { 21 | return id; 22 | } 23 | 24 | public RoqUrl url() { 25 | return url; 26 | } 27 | 28 | public Supplier page() { 29 | return page; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterPageBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.record; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import io.quarkiverse.roq.frontmatter.runtime.model.Page; 6 | import io.quarkiverse.roq.frontmatter.runtime.model.RoqUrl; 7 | import io.quarkus.builder.item.MultiBuildItem; 8 | 9 | public final class RoqFrontMatterPageBuildItem extends MultiBuildItem { 10 | private final String id; 11 | private final RoqUrl url; 12 | private final boolean hidden; 13 | private final Supplier page; 14 | 15 | public RoqFrontMatterPageBuildItem(String id, RoqUrl url, boolean hidden, Supplier page) { 16 | this.id = id; 17 | this.url = url; 18 | this.hidden = hidden; 19 | this.page = page; 20 | } 21 | 22 | public RoqUrl url() { 23 | return url; 24 | } 25 | 26 | public boolean hidden() { 27 | return hidden; 28 | } 29 | 30 | public String id() { 31 | return id; 32 | } 33 | 34 | public Supplier page() { 35 | return page; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/record/RoqFrontMatterSiteIndexBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.record; 2 | 3 | import java.util.function.Supplier; 4 | 5 | import io.quarkiverse.roq.frontmatter.runtime.model.NormalPage; 6 | import io.quarkus.builder.item.SimpleBuildItem; 7 | 8 | public final class RoqFrontMatterSiteIndexBuildItem extends SimpleBuildItem { 9 | private final Supplier page; 10 | 11 | public RoqFrontMatterSiteIndexBuildItem(Supplier page) { 12 | this.page = page; 13 | } 14 | 15 | public Supplier page() { 16 | return page; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/main/java/io/quarkiverse/roq/frontmatter/deployment/scan/RoqFrontMatterStaticFileBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.deployment.scan; 2 | 3 | import java.nio.file.Path; 4 | 5 | import io.quarkus.builder.item.MultiBuildItem; 6 | 7 | public final class RoqFrontMatterStaticFileBuildItem extends MultiBuildItem { 8 | private final String link; 9 | private final Path filePath; 10 | 11 | public RoqFrontMatterStaticFileBuildItem(String link, Path filePath) { 12 | this.link = link; 13 | this.filePath = filePath; 14 | } 15 | 16 | public String link() { 17 | return link; 18 | } 19 | 20 | public Path filePath() { 21 | return filePath; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.roq.resource-dir=site 2 | quarkus.http.root-path=/foo/ 3 | 4 | site.url=https://mywebsite.com 5 | site.path-prefix=/bar/ 6 | site.time-zone=UTC 7 | 8 | quarkus.log.category."io.quarkiverse.roq.frontmatter".level=DEBUG 9 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/content/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Simple Site 3 | layout: default 4 | paginate: 5 | collection: posts 6 | size: 2 7 | --- 8 | 9 |
10 | {#for post in site.collections.posts.paginated(page.paginator)} 11 |

{post.title}

12 | {/for} 13 |
14 | 15 | {#include fm/pagination.html /} -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/content/pages/some-page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: Some page 4 | link: /page/some-page 5 | description: This is a simple page 6 | some-text: We can also use data 7 | --- 8 | 9 |

{page.title}

10 |

{page.data.some-text}

-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/content/posts/2020-10-24-old-post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Old Post 4 | --- 5 | 6 |

Old post with markdown

7 | 8 |

This is a very old post

-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/content/posts/2023-10-10-some-post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: Some Post 4 | --- 5 | 6 |

So me post

7 | 8 |

some content

9 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/content/posts/2024-10-9-new-post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: New Post 4 | --- 5 | 6 |

New post with html

7 | 8 |

This is a new post.

9 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/public/images/iamroq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq-frontmatter/deployment/src/test/resources/simple-site/public/images/iamroq.png -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/templates/layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {#include partials/header.html /} 5 | 6 | 7 | {#insert /} 8 | 9 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/templates/layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | {#insert /} 7 |
-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/templates/layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | link: /the-posts/:slug 4 | --- 5 |
6 | {#insert /} 7 | {page.date} 8 |
-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/simple-site/templates/partials/header.html: -------------------------------------------------------------------------------- 1 | {#seo page site/} -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello, world! I'm Roq 3 | description: > # this means to ignore newlines until "baseurl:" 4 | Write an awesome description for your new site here. You can edit this 5 | line in data/config.yml. It will appear in your document head meta (for 6 | Google search results) and in your feed.xml site description. 7 | layout: default 8 | paginate: posts 9 | --- 10 | 11 |
12 | {#for post in site.collections.posts.paginated(page.paginator)} 13 |

{post.id}

14 | {/for} 15 |
16 | 17 | previous: {page.paginator.previousIndex}, current: {page.paginator.currentIndex}, next: {page.paginator.nextIndex} -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/pages/cool-page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: My Cool Page 4 | link: /my-cool-page 5 | description: this is a very cool page 6 | foo: bar 7 | --- 8 | 9 |

Hello World

10 |

{page.data.foo}

-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/pages/dir-page/beer.doc: -------------------------------------------------------------------------------- 1 | Hello -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/pages/dir-page/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: My dir page 3 | link: :slug 4 | --- 5 |

Hello!

6 | 7 | beer -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/posts/2020-10-24-old-post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | slug: old-post 4 | --- 5 | 6 |

Old post with markdown

7 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/posts/2024-03-10-dir-post/beer.svg: -------------------------------------------------------------------------------- 1 | svg -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/posts/2024-03-10-dir-post/index.html: -------------------------------------------------------------------------------- 1 |

Hello!

2 | 3 |

{page.date()}

4 | beer -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/content/posts/awesome-post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: post 3 | title: My Cool Post 4 | slug: awesome-post-1 5 | description: this is a very awesome post 6 | foo: bar 7 | date: 2024-09-10 8 | --- 9 |

A cool blog post

10 |

{page.data.foo} {cdi:foo.var1}

-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/data/foo.yml: -------------------------------------------------------------------------------- 1 | var1: hello -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/public/images/iamroq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq-frontmatter/deployment/src/test/resources/site/public/images/iamroq.png -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/templates/layouts/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {#include partials/header.html /} 5 | 6 | 7 | {#insert /} 8 | {#include partials/view.html} 9 | 10 | -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/templates/layouts/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 | 5 |
6 | {#insert /} 7 |
-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/templates/layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: default 3 | --- 4 |
5 | {#insert /} 6 | {page.date} 7 |
-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/templates/partials/foo/bar.html: -------------------------------------------------------------------------------- 1 |

bar bar bar

-------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/templates/partials/header.html: -------------------------------------------------------------------------------- 1 | {page.title ?: site.title} 2 | 3 | 4 | 5 | 6 | {#if site.data.containsKey("analytics")} 7 | {#ga4 tag=site.data.getJsonObject('analytics').getString("ga4", "") /} 8 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/deployment/src/test/resources/site/templates/partials/view.html: -------------------------------------------------------------------------------- 1 |
2 |

{page.title ?: "My Website"}

3 | {#include partials/foo/bar.html} 4 |
-------------------------------------------------------------------------------- /roq-frontmatter/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-frontmatter-parent 12 | 999-SNAPSHOT 13 | pom 14 | Quarkus Roq - FrontMatter 15 | 16 | 17 | deployment 18 | runtime 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/RoqFrontMatterMessages.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.runtime; 2 | 3 | import io.quarkus.qute.i18n.Message; 4 | import io.quarkus.qute.i18n.MessageBundle; 5 | 6 | @MessageBundle(value = "fm", locale = "en") 7 | public interface RoqFrontMatterMessages { 8 | 9 | @Message("Page {index} of {total}") 10 | public String pageNumber(int index, int total); 11 | } 12 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/RoqTemplateGlobal.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.runtime; 2 | 3 | import java.time.LocalDateTime; 4 | import java.util.Locale; 5 | import java.util.Objects; 6 | 7 | import io.quarkus.qute.TemplateGlobal; 8 | 9 | @TemplateGlobal 10 | public class RoqTemplateGlobal { 11 | static LocalDateTime now = LocalDateTime.now(); 12 | static String roqVersion = Objects.toString(RoqTemplateGlobal.class.getPackage().getImplementationVersion(), "???"); 13 | static String locale = Locale.getDefault().toString(); 14 | } -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/config/ConfiguredCollection.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.runtime.config; 2 | 3 | public record ConfiguredCollection( 4 | String id, 5 | boolean derived, 6 | boolean hidden, 7 | boolean future, 8 | String layout) { 9 | } 10 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/exception/RoqStaticFileException.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.runtime.exception; 2 | 3 | public class RoqStaticFileException extends RuntimeException { 4 | 5 | public RoqStaticFileException(String message) { 6 | super(message); 7 | } 8 | 9 | public RoqStaticFileException(String message, Throwable cause) { 10 | super(message, cause); 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/model/NormalPage.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.runtime.model; 2 | 3 | import jakarta.enterprise.inject.Vetoed; 4 | 5 | import io.quarkus.qute.TemplateData; 6 | import io.vertx.core.json.JsonObject; 7 | 8 | /** 9 | * This represents a normal "standalone" page (not in a collection) 10 | * 11 | * @param url the url to this page 12 | * @param info the page info 13 | * @param data the FM data of this page 14 | * @param paginator the paginator if any 15 | */ 16 | @TemplateData 17 | @Vetoed 18 | public record NormalPage(RoqUrl url, PageInfo info, JsonObject data, Paginator paginator) implements Page { 19 | 20 | } 21 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/model/PageFiles.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.runtime.model; 2 | 3 | import static io.quarkiverse.roq.util.PathUtils.getExtension; 4 | import static io.quarkiverse.roq.util.PathUtils.removeExtension; 5 | 6 | import java.util.List; 7 | 8 | import io.quarkiverse.roq.util.PathUtils; 9 | 10 | public record PageFiles(List names, boolean slugified) { 11 | public boolean contains(Object o) { 12 | return names.contains(o); 13 | } 14 | 15 | public boolean isEmpty() { 16 | return names.isEmpty(); 17 | } 18 | 19 | public int size() { 20 | return names.size(); 21 | } 22 | 23 | public static String slugifyFile(String filePath) { 24 | final String extension = getExtension(filePath); 25 | String path = removeExtension(filePath); 26 | // We allow dots because some static files might have versions in their names 27 | // Anyway they have an extension 28 | return PathUtils.slugify(path, true, true) + "." + extension; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/java/io/quarkiverse/roq/frontmatter/runtime/model/RoqCollections.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.frontmatter.runtime.model; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import jakarta.enterprise.inject.Vetoed; 7 | 8 | import io.quarkus.qute.TemplateData; 9 | 10 | /** 11 | * This represents all collections by id 12 | * 13 | * @param collections the map of collections by id 14 | */ 15 | @TemplateData 16 | @Vetoed 17 | public record RoqCollections(Map collections) { 18 | public RoqCollection get(String name) { 19 | return collections.get(name); 20 | } 21 | 22 | public List list() { 23 | return List.copyOf(collections.values()); 24 | } 25 | 26 | /** 27 | * Resolve the collection for this document page 28 | */ 29 | public RoqCollection resolveCollection(DocumentPage page) { 30 | if (page.collectionId() == null) { 31 | return null; 32 | } 33 | return this.get(page.collectionId()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq FrontMatter 2 | description: Create a website from your Markdown/Asciidoc/Html pages using FrontMatter headers (url, layout, seo, data). 3 | metadata: 4 | keywords: 5 | - markdown 6 | - frontmatter 7 | - asciidoc 8 | - site 9 | - ssg 10 | - roq 11 | - content 12 | - qute 13 | guide: https://docs.quarkiverse.io/quarkus-roq/dev/quarkus-roq-frontmatter.html 14 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 15 | config: 16 | - "quarkus.roq" 17 | categories: 18 | - "web" 19 | status: "preview" -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.qute.suffixes=qute.html,qute.txt,html,xhtml,htm,txt,json,yaml,yml,xml -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/fm/favicon.html: -------------------------------------------------------------------------------- 1 | {#if site.imageExists('favicon.svg')} 2 | 3 | {/if} 4 | {#if site.imageExists('favicon.png')} 5 | 6 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/fm/pagination.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.NormalPage page} 2 | 3 | {#if page.paginator} 4 | 19 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/fm/rss.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.Site site} 2 | {@io.quarkiverse.roq.frontmatter.runtime.model.NormalPage page} 3 | {#let name=(collectionName ?: 'posts')} 4 | 5 | 6 | <![CDATA[ {site.title} ]]> 7 | 8 | {site.url.absolute} 9 | Quarkus Roq 10 | {#if site.collections.get(name)} 11 | {#if site.collections.get(name).size > 0}{site.collections.get(name).get(0).date}{/if} 12 | {#for post in site.collections.get(name)} 13 | 14 | <![CDATA[{post.title}]]> 15 | {post.url.absolute} 16 | {post.url.absolute} 17 | {post.date} 18 |

{post.description}



19 |
20 | {/for} 21 | {/if} 22 |
23 |
24 | 25 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/ga4.html: -------------------------------------------------------------------------------- 1 | {@java.lang.String tag} 2 | {#if tag} 3 | 4 | 11 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/rss.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.Site site} 2 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seo.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.Site site} 2 | {@io.quarkiverse.roq.frontmatter.runtime.model.Page page} 3 | 4 | {#seoTitle pageTitle=page.title siteTitle=site.title /} 5 | {#seoDescription pageDescription=page.description siteDescription=site.description /} 6 | {#seoAuthor pageAuthor=page.data.author?? siteAuthor=site.data.author?? /} 7 | {#seoUrl url=page.url /} 8 | {#seoType page /} 9 | {#seoImage page site /} 10 | {#seoVerifications webmasterVerifications=site.data.webmasterVerifications?? /} 11 | {#seoPaginator page site /} 12 | {#seoFacebook facebook=site.data.facebook?? /} 13 | {#seoTwitter twitter=site.data.twitter?? /} 14 | {#seoLocale pageLocale=page.data.lang?? siteLocale=site.data.lang?? defaultLocale=global:locale /} 15 | {#seoGenerator name="Quarkus Roq" version=global:roqVersion /} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoAuthor.html: -------------------------------------------------------------------------------- 1 | {#if pageAuthor || siteAuthor} 2 | 3 | 4 | 5 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoDescription.html: -------------------------------------------------------------------------------- 1 | {#if pageDescription || siteDescription} 2 | 3 | 4 | 5 | 6 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoFacebook.html: -------------------------------------------------------------------------------- 1 | {#if facebook} 2 | 3 | {#if facebook.admins} 4 | 5 | {/if} 6 | 7 | {#if facebook.publisher} 8 | 9 | {/if} 10 | 11 | {#if facebook.app_id} 12 | 13 | {/if} 14 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoGenerator.html: -------------------------------------------------------------------------------- 1 | {#if name} 2 | 3 | 4 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoImage.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.Site site} 2 | {@io.quarkiverse.roq.frontmatter.runtime.model.Page page} 3 | 4 | {#if page.image} 5 | 6 | 7 | 8 | 9 | {#else} 10 | 11 | 12 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoLocale.html: -------------------------------------------------------------------------------- 1 | {#if pageLocale || siteLocale} 2 | 3 | 4 | {#else} 5 | 6 | 7 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoPaginator.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.Site site} 2 | {#if page.paginator??} 3 | 4 | {#if page.paginator.previous} 5 | 6 | {/if} 7 | {#if page.paginator.next} 8 | 9 | {/if} 10 | {#else if page.collection??} 11 | 12 | {#if page.prevPage} 13 | 14 | {/if} 15 | {#if page.nextPage} 16 | 17 | {/if} 18 | {/if} 19 | -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoTitle.html: -------------------------------------------------------------------------------- 1 | {@java.lang.String pageTitle} 2 | {@java.lang.String siteTitle} 3 | 4 | {#if pageTitle || siteTitle} 5 | 6 | {#fragment title rendered=false}{#if pageTitle && pageTitle ne siteTitle}{pageTitle} - {siteTitle}{#else}{siteTitle}{/if}{/fragment} 7 | {#include $title /} 8 | 9 | 10 | {/if} 11 | {#if siteTitle} 12 | 13 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoTwitter.html: -------------------------------------------------------------------------------- 1 | {#if twitter} 2 | 3 | 4 | 5 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoType.html: -------------------------------------------------------------------------------- 1 | {#if it.date} 2 | 3 | 4 | 5 | {#else} 6 | 7 | 8 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoUrl.html: -------------------------------------------------------------------------------- 1 | {#if url} 2 | 3 | 4 | 5 | 6 | {/if} -------------------------------------------------------------------------------- /roq-frontmatter/runtime/src/main/resources/templates/tags/seoVerifications.html: -------------------------------------------------------------------------------- 1 | {#if webmasterVerifications} 2 | 3 | {#if webmasterVerifications.google} 4 | 5 | {/if} 6 | {#if webmasterVerifications.bing} 7 | 8 | {/if} 9 | {#if webmasterVerifications.alexa} 10 | 11 | {/if} 12 | {#if webmasterVerifications.yandex} 13 | 14 | {/if} 15 | {#if webmasterVerifications.baidu} 16 | 17 | {/if} 18 | {#if webmasterVerifications.facebook} 19 | 20 | {/if} 21 | {/if} -------------------------------------------------------------------------------- /roq-generator/deployment/src/main/java/io/quarkiverse/roq/generator/deployment/BuildSelectionBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.deployment; 2 | 3 | import java.util.Map; 4 | 5 | import io.quarkiverse.roq.generator.runtime.RoqSelection; 6 | import io.quarkiverse.roq.generator.runtime.StaticFile; 7 | import io.quarkus.builder.item.SimpleBuildItem; 8 | 9 | public final class BuildSelectionBuildItem extends SimpleBuildItem { 10 | private final Map staticFiles; 11 | private final RoqSelection selectedPaths; 12 | 13 | public BuildSelectionBuildItem(Map staticFiles, RoqSelection selectedPaths) { 14 | this.staticFiles = staticFiles; 15 | this.selectedPaths = selectedPaths; 16 | } 17 | 18 | public Map staticFiles() { 19 | return staticFiles; 20 | } 21 | 22 | public RoqSelection selectedPaths() { 23 | return selectedPaths; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /roq-generator/integration-tests/src/main/resources/META-INF/resources/assets/vector.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /roq-generator/integration-tests/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | quarkus.roq.generator.paths=/,/static/**,/assets/**,/some-page,/roq/c'est de la poussière d'étoile/ 2 | quarkus.roq.generator.custom-paths."/roq?name\=custom"=/foo.json 3 | quarkus.roq.generator.batch=true 4 | quarkus.log.category."io.quarkiverse.roq".level=DEBUG 5 | %replace.quarkus.roq.generator.path-replace.enabled=true 6 | %replace,query.quarkus.roq.generator.paths=/,/static/**,/assets/**,/some-page,/roq?name=foo2 -------------------------------------------------------------------------------- /roq-generator/integration-tests/src/main/resources/templates/pub/some-page.html: -------------------------------------------------------------------------------- 1 |

Hello

2 | -------------------------------------------------------------------------------- /roq-generator/integration-tests/src/main/resources/web/index.html: -------------------------------------------------------------------------------- 1 |

Hello

2 | -------------------------------------------------------------------------------- /roq-generator/integration-tests/src/main/resources/web/static/élo$ bar.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq-generator/integration-tests/src/main/resources/web/static/élo$ bar.txt -------------------------------------------------------------------------------- /roq-generator/integration-tests/src/test/java/io/quarkiverse/roq/it/RoqGenerationTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.it; 2 | 3 | import static java.nio.file.Files.exists; 4 | import static org.junit.jupiter.api.Assertions.assertTrue; 5 | 6 | import java.nio.file.Path; 7 | 8 | import org.junit.jupiter.api.Test; 9 | 10 | import io.quarkus.test.junit.main.Launch; 11 | import io.quarkus.test.junit.main.QuarkusMainTest; 12 | 13 | @QuarkusMainTest 14 | public class RoqGenerationTest { 15 | 16 | @Test 17 | @Launch 18 | public void testGenerate() { 19 | assertTrue(exists(Path.of("target/roq/index.html"))); 20 | assertTrue(exists(Path.of("target/roq/some-page"))); 21 | assertTrue(exists(Path.of("target/roq/foo.json"))); 22 | assertTrue(exists(Path.of("target/roq/assets/vector.svg"))); 23 | assertTrue(exists(Path.of("target/roq/static/logo.svg"))); 24 | assertTrue(exists(Path.of("target/roq/static/logo.svg.svg"))); 25 | assertTrue(exists(Path.of("target/roq/static/élo$ bar.txt"))); 26 | assertTrue(exists(Path.of("target/roq/roq/c'est de la poussière d'étoile/index.html"))); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /roq-generator/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-generator-parent 12 | pom 13 | Quarkus Roq - Generator 14 | 15 | 16 | spi 17 | runtime 18 | deployment 19 | 20 | 21 | 22 | 23 | it 24 | 25 | 26 | performRelease 27 | !true 28 | 29 | 30 | 31 | integration-tests 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/java/io/quarkiverse/roq/generator/runtime/ConfiguredPathsProvider.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.runtime; 2 | 3 | import java.util.Map; 4 | 5 | import jakarta.enterprise.inject.Produces; 6 | import jakarta.inject.Singleton; 7 | 8 | @Singleton 9 | public class ConfiguredPathsProvider { 10 | 11 | private static volatile String targetDir; 12 | 13 | private static volatile RoqSelection buildSelectedPaths; 14 | private static volatile Map staticFiles; 15 | 16 | public static void setStaticFiles(Map staticFiles) { 17 | ConfiguredPathsProvider.staticFiles = staticFiles; 18 | } 19 | 20 | public static Map staticFiles() { 21 | return staticFiles; 22 | } 23 | 24 | public static void setOutputTarget(String targetDir) { 25 | ConfiguredPathsProvider.targetDir = targetDir; 26 | } 27 | 28 | public static String targetDir() { 29 | return targetDir; 30 | } 31 | 32 | public static void setBuildSelectedPaths(RoqSelection selectedPaths) { 33 | buildSelectedPaths = selectedPaths; 34 | } 35 | 36 | @Produces 37 | @Singleton 38 | RoqSelection produce() { 39 | return buildSelectedPaths; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/java/io/quarkiverse/roq/generator/runtime/PageSource.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.runtime; 2 | 3 | public enum PageSource { 4 | /** 5 | * This page is configured through {@link RoqGeneratorConfig} 6 | */ 7 | CONFIG, 8 | 9 | /** 10 | * This page is configured through a build item 11 | */ 12 | BUILD_ITEM, 13 | 14 | /** 15 | * This page has been @Provided at runtime through a RoqSelection 16 | */ 17 | PROVIDED 18 | } 19 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/java/io/quarkiverse/roq/generator/runtime/PathReplaceConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.runtime; 2 | 3 | import io.smallrye.config.WithDefault; 4 | 5 | public interface PathReplaceConfig { 6 | 7 | String DEFAULT_ALLOWED_REGEX = "[^a-zA-Z0-9_\\\\/.\\-]"; 8 | String DEFAULT_REPLACE_WITH = "-"; 9 | 10 | /** 11 | * Enable path character replace 12 | */ 13 | @WithDefault("false") 14 | boolean enabled(); 15 | 16 | /** 17 | * The regex of allowed characters for file names (other characters will be replaced), for example: `[^a-zA-Z0-9_\\\\/.\\-]` 18 | *

19 | * By default, all characters are unchanged. 20 | */ 21 | @WithDefault(DEFAULT_ALLOWED_REGEX) 22 | String allowedRegex(); 23 | 24 | /** 25 | * The character to use to replace characters which doesn't match the 'allowed-regex' 26 | */ 27 | @WithDefault(DEFAULT_REPLACE_WITH) 28 | String replaceWith(); 29 | 30 | static PathReplaceConfig create(String allowedRegex, String replaceWith) { 31 | return new PathReplaceConfigImpl(true, allowedRegex, replaceWith); 32 | } 33 | 34 | static PathReplaceConfig replaceConfig() { 35 | return new PathReplaceConfigImpl(true, DEFAULT_ALLOWED_REGEX, DEFAULT_REPLACE_WITH); 36 | } 37 | 38 | static PathReplaceConfig createDefault() { 39 | return new PathReplaceConfigImpl(false, DEFAULT_ALLOWED_REGEX, DEFAULT_REPLACE_WITH); 40 | } 41 | 42 | record PathReplaceConfigImpl(boolean enabled, String allowedRegex, String replaceWith) implements PathReplaceConfig { 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/java/io/quarkiverse/roq/generator/runtime/RoqGeneratorRecorder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.runtime; 2 | 3 | import java.util.Map; 4 | 5 | import io.quarkus.runtime.annotations.Recorder; 6 | 7 | @Recorder 8 | public class RoqGeneratorRecorder { 9 | 10 | public void setStaticFiles(Map staticFiles) { 11 | ConfiguredPathsProvider.setStaticFiles(staticFiles); 12 | } 13 | 14 | public void setOutputTarget(String outputDirectory) { 15 | ConfiguredPathsProvider.setOutputTarget(outputDirectory); 16 | } 17 | 18 | public void setBuildSelectedPaths(RoqSelection selectedPaths) { 19 | ConfiguredPathsProvider.setBuildSelectedPaths(selectedPaths); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/java/io/quarkiverse/roq/generator/runtime/RoqSelection.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.runtime; 2 | 3 | import java.util.Comparator; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | public record RoqSelection(List paths) { 9 | 10 | public static List prepare(RoqGeneratorConfig config, List selection) { 11 | Set seenPaths = new HashSet<>(); 12 | return selection.stream().map(RoqSelection::paths).flatMap(List::stream) 13 | .filter(selectedPath -> seenPaths.add(selectedPath.path())) 14 | .map(s -> s.clean(config.pathReplace())) 15 | .sorted(Comparator.comparing(SelectedPath::outputPath)).toList(); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/java/io/quarkiverse/roq/generator/runtime/StaticFile.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.runtime; 2 | 3 | public record StaticFile(String path, FetchType type) { 4 | public enum FetchType { 5 | FILE, 6 | CLASSPATH, 7 | HTTP 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/java/io/quarkiverse/roq/generator/runtime/devui/RoqGeneratorJsonRPCService.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.runtime.devui; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import jakarta.enterprise.context.ApplicationScoped; 7 | import jakarta.inject.Inject; 8 | 9 | import io.quarkiverse.roq.generator.runtime.RoqGenerator; 10 | import io.quarkiverse.roq.generator.runtime.RoqGeneratorConfig; 11 | import io.quarkiverse.roq.generator.runtime.RoqSelection; 12 | import io.quarkiverse.roq.generator.runtime.SelectedPath; 13 | import io.quarkus.arc.All; 14 | import io.smallrye.common.annotation.Blocking; 15 | import io.smallrye.mutiny.Uni; 16 | 17 | @ApplicationScoped 18 | public class RoqGeneratorJsonRPCService { 19 | 20 | @All 21 | @Inject 22 | List selection; 23 | 24 | @Inject 25 | RoqGenerator generator; 26 | 27 | @Inject 28 | RoqGeneratorConfig config; 29 | 30 | @Blocking 31 | public List getSelection() { 32 | return RoqSelection.prepare(config, selection); 33 | } 34 | 35 | @Blocking 36 | public int getCount() { 37 | return getSelection().size(); 38 | } 39 | 40 | public Uni generate() { 41 | Map config = Map.of("quarkus.http.port", "8081"); 42 | return generator.generate().map(a -> generator.outputDir()); 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /roq-generator/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Generator 2 | description: Command to run any Quarkus web application and extract it in a directory as purely static files (html and assets). 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - ssg 13 | - roq 14 | - generator 15 | - web 16 | guide: https://docs.quarkiverse.io/quarkus-roq/dev/quarkus-roq-generator.html 17 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 18 | categories: 19 | - "web" 20 | config: 21 | - "quarkus.roq" 22 | status: "preview" -------------------------------------------------------------------------------- /roq-generator/spi/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | io.quarkiverse.roq 6 | quarkus-roq-generator-parent 7 | 999-SNAPSHOT 8 | 9 | quarkus-roq-generator-spi 10 | Quarkus Roq - Generator - SPI 11 | 12 | 13 | io.quarkus 14 | quarkus-core-deployment 15 | 16 | 17 | -------------------------------------------------------------------------------- /roq-generator/spi/src/main/java/io/quarkiverse/roq/generator/deployment/items/SelectedPathBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.generator.deployment.items; 2 | 3 | import io.quarkus.builder.item.MultiBuildItem; 4 | 5 | public final class SelectedPathBuildItem extends MultiBuildItem { 6 | 7 | /** 8 | * The path to fetch content from starting with / (without the root-path). 9 | */ 10 | private final String path; 11 | 12 | /** 13 | * The output path to generate. 14 | * If empty or null it will be auto-generated from the path 15 | */ 16 | private final String outputPath; 17 | 18 | public SelectedPathBuildItem(String path, String outputPath) { 19 | this.path = path; 20 | this.outputPath = outputPath == null ? "" : outputPath; 21 | } 22 | 23 | public String path() { 24 | return path; 25 | } 26 | 27 | public String outputPath() { 28 | return outputPath; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /roq-plugin/aliases/deployment/src/main/java/io/quarkiverse/roq/plugin/aliases/deployment/items/RoqFrontMatterAliasesBuildItem.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.aliases.deployment.items; 2 | 3 | import io.quarkus.builder.item.MultiBuildItem; 4 | 5 | public final class RoqFrontMatterAliasesBuildItem extends MultiBuildItem { 6 | 7 | /** 8 | * Represents an alias of a determined link. 9 | */ 10 | private final String alias; 11 | 12 | /** 13 | * The link where the {@code aliases} are pointing to. 14 | */ 15 | private final String target; 16 | 17 | public RoqFrontMatterAliasesBuildItem(String alias, String target) { 18 | this.alias = alias; 19 | this.target = target; 20 | } 21 | 22 | public String alias() { 23 | return alias; 24 | } 25 | 26 | public String target() { 27 | return target; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /roq-plugin/aliases/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-aliases-parent 12 | pom 13 | Quarkus Roq - Plugin - Aliases 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-plugin/aliases/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin - Aliases 2 | description: This plugin allows creating one or many aliases (redirections) for a page. 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - generator 13 | - web 14 | - roq 15 | - ssg 16 | - aliases 17 | - redirect 18 | - plugin 19 | guide: https://iamroq.com/docs/plugins/#plugin-aliases 20 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 21 | categories: 22 | - "web" 23 | config: 24 | - "quarkus.roq" 25 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/asciidoc-jruby/deployment/.asciidoctor/diagram/wunderbar.svg.cache: -------------------------------------------------------------------------------- 1 | {"checksum":"plantuml-md5-b9789764675c004c6f8dc2435a79cba2","options":{"size_limit":"4096"},"width":116,"height":105} -------------------------------------------------------------------------------- /roq-plugin/asciidoc-jruby/deployment/src/main/java/io/quarkiverse/roq/plugin/asciidoctorj/deployment/RoqPluginAsciidoctorJProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.asciidoctorj.deployment; 2 | 3 | import java.util.Set; 4 | 5 | import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterQuteMarkupBuildItem; 6 | import io.quarkiverse.roq.plugin.asciidoctorj.runtime.AsciidoctorJConverter; 7 | import io.quarkiverse.roq.plugin.asciidoctorj.runtime.AsciidoctorJSectionHelperFactory; 8 | import io.quarkus.arc.deployment.AdditionalBeanBuildItem; 9 | import io.quarkus.deployment.annotations.BuildProducer; 10 | import io.quarkus.deployment.annotations.BuildStep; 11 | import io.quarkus.deployment.builditem.FeatureBuildItem; 12 | 13 | public class RoqPluginAsciidoctorJProcessor { 14 | 15 | private static final String FEATURE = "roq-plugin-asciidoctorj"; 16 | 17 | @BuildStep 18 | FeatureBuildItem feature() { 19 | return new FeatureBuildItem(FEATURE); 20 | } 21 | 22 | @BuildStep 23 | RoqFrontMatterQuteMarkupBuildItem markup() { 24 | return new RoqFrontMatterQuteMarkupBuildItem(Set.of("adoc", "asciidoc"), 25 | new RoqFrontMatterQuteMarkupBuildItem.QuteMarkupSection("{#asciidoc}", "{/asciidoc}")); 26 | } 27 | 28 | @BuildStep 29 | void process(BuildProducer additionalBeans) { 30 | additionalBeans.produce(new AdditionalBeanBuildItem(AsciidoctorJSectionHelperFactory.class)); 31 | additionalBeans.produce(AdditionalBeanBuildItem.unremovableOf(AsciidoctorJConverter.class)); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /roq-plugin/asciidoc-jruby/deployment/src/test/java/io/quarkiverse/roq/plugin/asciidoctorj/test/QuteAsciidoctorJDiagramTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.asciidoctorj.test; 2 | 3 | import jakarta.inject.Inject; 4 | 5 | import org.assertj.core.api.SoftAssertions; 6 | import org.junit.jupiter.api.Test; 7 | import org.junit.jupiter.api.extension.RegisterExtension; 8 | 9 | import io.quarkus.qute.Engine; 10 | import io.quarkus.test.QuarkusUnitTest; 11 | 12 | public class QuteAsciidoctorJDiagramTest { 13 | 14 | @RegisterExtension 15 | static final QuarkusUnitTest quarkusApp = new QuarkusUnitTest(); 16 | 17 | @Inject 18 | Engine engine; 19 | 20 | @Test 21 | void shouldRenderDiagram() { 22 | 23 | String result = engine.parse(""" 24 |

Quarkus and Qute

25 | {#ascii} 26 | == Qute and Diagram 27 | 28 | Here is a diagram: 29 | 30 | [plantuml,target="wunderbar",format=svg] 31 | ---- 32 | @startuml 33 | Test -> Test2 34 | @enduml 35 | ---- 36 | 37 | {/ascii} 38 | """).render(); 39 | 40 | SoftAssertions.assertSoftly(softly -> { 41 | softly.assertThat(result).contains("

Quarkus and Qute

"); 42 | softly.assertThat(result).contains("

Qute and Diagram

"); 43 | softly.assertThat(result).containsPattern(" app.addAsResource(new StringAsset( 20 | """ 21 | {#ascii} 22 | = Qute and Roq 23 | 24 | Hello 25 | {/ascii} 26 | """), 27 | "templates/foo.txt")); 28 | 29 | @Inject 30 | Template foo; 31 | 32 | @Test 33 | void shouldConvertUsingAsciiTag() { 34 | String result = foo.render(); 35 | 36 | assertThat(result).containsIgnoringWhitespaces(""" 37 |

Qute and Roq

38 |
39 |

Hello

40 |
41 | """, result); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /roq-plugin/asciidoc-jruby/deployment/src/test/java/io/quarkiverse/roq/plugin/asciidoctorj/test/QuteWebAsciidoctorJExtensionsTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.asciidoctorj.test; 2 | 3 | import jakarta.inject.Inject; 4 | 5 | import org.assertj.core.api.Assertions; 6 | import org.jboss.shrinkwrap.api.asset.StringAsset; 7 | import org.junit.jupiter.api.Test; 8 | import org.junit.jupiter.api.extension.RegisterExtension; 9 | 10 | import io.quarkus.qute.Engine; 11 | import io.quarkus.test.QuarkusUnitTest; 12 | 13 | public class QuteWebAsciidoctorJExtensionsTest { 14 | 15 | @RegisterExtension 16 | static final QuarkusUnitTest quarkusApp = new QuarkusUnitTest() 17 | .withApplicationRoot( 18 | app -> app 19 | .addAsResource(new StringAsset("{data.asciidocify}"), "templates/foo.txt") 20 | .addAsResource(new StringAsset("{data.asciidocToHtml}"), "templates/bar.txt")); 21 | 22 | @Inject 23 | Engine engine; 24 | 25 | @Test 26 | void shouldUseAsciidocify() { 27 | String asciidoc = "= Qute and Roq"; 28 | Assertions.assertThat(engine.getTemplate("foo").data("data", asciidoc).render()).contains("

Qute and Roq

"); 29 | Assertions.assertThat(engine.getTemplate("bar").data("data", asciidoc).render()).contains("

Qute and Roq

"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /roq-plugin/asciidoc-jruby/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-asciidoc-jruby-parent 12 | pom 13 | Quarkus Roq - Plugin - AsciidoctorJ 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-plugin/asciidoc-jruby/runtime/src/main/java/io/quarkiverse/roq/plugin/asciidoctorj/runtime/AsciidoctorJConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.asciidoctorj.runtime; 2 | 3 | import java.util.Map; 4 | 5 | import io.quarkus.runtime.annotations.ConfigPhase; 6 | import io.quarkus.runtime.annotations.ConfigRoot; 7 | import io.smallrye.config.ConfigMapping; 8 | import io.smallrye.config.WithDefault; 9 | 10 | @ConfigMapping(prefix = "quarkus.asciidoctorj") 11 | @ConfigRoot(phase = ConfigPhase.BUILD_AND_RUN_TIME_FIXED) 12 | public interface AsciidoctorJConfig { 13 | 14 | /** 15 | * Set Asciidoctorj attributes 16 | */ 17 | Map attributes(); 18 | 19 | /** 20 | * Templates directory for Asciidoctorj 21 | */ 22 | @WithDefault("src/main/asciidoc-templates") 23 | String templatesDir(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /roq-plugin/asciidoc-jruby/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin - Asciidoc JRuby 2 | description: This plugin integrates AsciidoctorJ (the JRuby-based implementation of Asciidoctor) into Roq. While it has a slightly slower startup time and is not compatible with native builds, it offers the full range of Asciidoctor features for rich content processing. 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jruby 9 | - jekyll 10 | - hugo 11 | - lume 12 | - site 13 | - generator 14 | - web 15 | - roq 16 | - ssg 17 | - asciidoc 18 | - asciidoctor 19 | - plugin 20 | guide: https://iamroq.com/docs/plugins/#plugin-asciidoc 21 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 22 | categories: 23 | - "web" 24 | config: 25 | - "quarkus.roq" 26 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/asciidoc/deployment/src/main/java/io/quarkiverse/roq/plugin/asciidoc/deployment/RoqPluginAsciidocProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.asciidoc.deployment; 2 | 3 | import java.util.Set; 4 | 5 | import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterQuteMarkupBuildItem; 6 | import io.quarkus.deployment.annotations.BuildStep; 7 | import io.quarkus.deployment.builditem.FeatureBuildItem; 8 | 9 | public class RoqPluginAsciidocProcessor { 10 | 11 | private static final String FEATURE = "roq-plugin-asciidoc"; 12 | 13 | @BuildStep 14 | FeatureBuildItem feature() { 15 | return new FeatureBuildItem(FEATURE); 16 | } 17 | 18 | @BuildStep 19 | RoqFrontMatterQuteMarkupBuildItem markup() { 20 | return new RoqFrontMatterQuteMarkupBuildItem(Set.of("adoc", "asciidoc"), 21 | new RoqFrontMatterQuteMarkupBuildItem.QuteMarkupSection("{#asciidoc}", "{/asciidoc}")); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /roq-plugin/asciidoc/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-asciidoc-parent 12 | pom 13 | Quarkus Roq - Plugin - Asciidoc 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-plugin/asciidoc/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin - Asciidoc Java 2 | description: This plugin enables Asciidoc support in Roq with a fast startup time and full compatibility with native builds. However, it has limited features and does not support Asciidoc extensions (such as diagram). 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - generator 13 | - web 14 | - roq 15 | - ssg 16 | - asciidoc 17 | - plugin 18 | - asciidoctor 19 | guide: https://iamroq.com/docs/plugins/#plugin-asciidoc 20 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 21 | categories: 22 | - "web" 23 | config: 24 | - "quarkus.roq" 25 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/lunr/deployment/src/main/java/io/quarkiverse/roq/plugin/lunr/deployment/RoqPluginLunrProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.lunr.deployment; 2 | 3 | import io.quarkus.arc.deployment.AdditionalBeanBuildItem; 4 | import io.quarkus.deployment.annotations.BuildStep; 5 | import io.quarkus.deployment.builditem.FeatureBuildItem; 6 | 7 | public class RoqPluginLunrProcessor { 8 | private static final String FEATURE = "roq-plugin-lunr"; 9 | 10 | @BuildStep 11 | FeatureBuildItem feature() { 12 | return new FeatureBuildItem(FEATURE); 13 | } 14 | 15 | @BuildStep 16 | AdditionalBeanBuildItem process() { 17 | return new AdditionalBeanBuildItem( 18 | io.quarkiverse.roq.plugin.sitemap.runtime.runtime.RoqPluginLunrTemplateExtension.class); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /roq-plugin/lunr/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-lunr-parent 12 | pom 13 | Quarkus Roq - Plugin - Lunr 14 | 15 | deployment 16 | runtime 17 | 18 | 19 | -------------------------------------------------------------------------------- /roq-plugin/lunr/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin - Lunr 2 | description: This plugin adds lunr.js to your website -with prebuilt index- to provide searching capabilities 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - generator 13 | - web 14 | - roq 15 | - ssg 16 | - lunr 17 | - plugin 18 | guide: https://iamroq.com/docs/plugins/#plugin-lunr 19 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 20 | categories: 21 | - "web" 22 | config: 23 | - "quarkus.roq" 24 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/lunr/runtime/src/main/resources/templates/fm/search-index.json: -------------------------------------------------------------------------------- 1 | {site.searchIndex} -------------------------------------------------------------------------------- /roq-plugin/lunr/runtime/src/main/resources/templates/tags/search-button.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /roq-plugin/lunr/runtime/src/main/resources/templates/tags/search-overlay.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 12 |
13 |
14 | 15 |
16 |
17 |
-------------------------------------------------------------------------------- /roq-plugin/lunr/runtime/src/main/resources/templates/tags/search-script.html: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /roq-plugin/markdown/deployment/src/main/java/io/quarkiverse/roq/plugin/asciidoc/deployment/RoqPluginMarkdownProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.markdown.deployment; 2 | 3 | import java.util.Set; 4 | 5 | import io.quarkiverse.roq.frontmatter.deployment.scan.RoqFrontMatterQuteMarkupBuildItem; 6 | import io.quarkus.deployment.annotations.BuildStep; 7 | import io.quarkus.deployment.builditem.FeatureBuildItem; 8 | 9 | public class RoqPluginMarkdownProcessor { 10 | 11 | private static final String FEATURE = "roq-plugin-markdown"; 12 | 13 | @BuildStep 14 | FeatureBuildItem feature() { 15 | return new FeatureBuildItem(FEATURE); 16 | } 17 | 18 | @BuildStep 19 | RoqFrontMatterQuteMarkupBuildItem markup() { 20 | return new RoqFrontMatterQuteMarkupBuildItem(Set.of("md", "markdown"), 21 | new RoqFrontMatterQuteMarkupBuildItem.QuteMarkupSection("{#markdown}", "{/markdown}")); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /roq-plugin/markdown/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-markdown-parent 12 | pom 13 | Quarkus Roq - Plugin - Markdown 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-plugin/markdown/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin Markdown 2 | description: This plugin allows to use Markdown in ROQ 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - generator 13 | - web 14 | - roq 15 | - ssg 16 | - markdown 17 | - plugin 18 | guide: https://iamroq.com/docs/plugins/#plugin-markdown 19 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 20 | categories: 21 | - "web" 22 | config: 23 | - "quarkus.roq" 24 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-parent 12 | pom 13 | Quarkus Roq - Plugins 14 | 15 | 7.2.1.202505142326-r 16 | 17 | 18 | tagging 19 | aliases 20 | markdown 21 | asciidoc 22 | asciidoc-jruby 23 | qrcode 24 | series 25 | sitemap 26 | lunr 27 | 28 | 29 | -------------------------------------------------------------------------------- /roq-plugin/qrcode/deployment/src/main/java/io/quarkiverse/roq/plugin/qrcode/deployment/RoqPluginQrCodeProcessor.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.qrcode.deployment; 2 | 3 | import io.quarkiverse.roq.plugin.qrcode.runtime.QRCodeRenderer; 4 | import io.quarkus.arc.deployment.AdditionalBeanBuildItem; 5 | import io.quarkus.deployment.annotations.BuildStep; 6 | import io.quarkus.deployment.builditem.FeatureBuildItem; 7 | 8 | public class RoqPluginQrCodeProcessor { 9 | 10 | private static final String FEATURE = "roq-plugin-qrcode"; 11 | 12 | @BuildStep 13 | FeatureBuildItem feature() { 14 | return new FeatureBuildItem(FEATURE); 15 | } 16 | 17 | @BuildStep 18 | AdditionalBeanBuildItem process() { 19 | return new AdditionalBeanBuildItem(QRCodeRenderer.class); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /roq-plugin/qrcode/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-qrcode-parent 12 | pom 13 | Quarkus Roq - Plugin - QrCode 14 | 15 | 16 | 1.0.0 17 | 18 | 19 | deployment 20 | runtime 21 | 22 | 23 | -------------------------------------------------------------------------------- /roq-plugin/qrcode/runtime/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq-plugin/qrcode/runtime/src/main/resources/META-INF/beans.xml -------------------------------------------------------------------------------- /roq-plugin/qrcode/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin QrCode 2 | description: This plugin allows generate a QR Code in ROQ 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - generator 13 | - web 14 | - roq 15 | - ssg 16 | - qrcode 17 | - barcode 18 | - plugin 19 | guide: https://iamroq.com/docs/plugins/#plugin-qrcode 20 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 21 | categories: 22 | - "web" 23 | config: 24 | - "quarkus.roq" 25 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/series/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-series-parent 12 | pom 13 | Quarkus Roq - Plugin - Series 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-plugin/series/runtime/src/main/java/io/quarkiverse/roq/plugin/series/runtime/SeriesMessage.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.series.runtime; 2 | 3 | import io.quarkus.qute.i18n.Message; 4 | import io.quarkus.qute.i18n.MessageBundle; 5 | 6 | @MessageBundle(value = "series", defaultKey = Message.UNDERSCORED_ELEMENT_NAME, locale = "en") 7 | public interface SeriesMessage { 8 | 9 | @Message(defaultValue = "{title} ({count} Parts Series)") 10 | String header(String title, Integer count); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /roq-plugin/series/runtime/src/main/java/io/quarkiverse/roq/plugin/series/runtime/SeriesRecorder.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.series.runtime; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | import java.util.stream.Collectors; 6 | 7 | import io.quarkus.runtime.RuntimeValue; 8 | import io.quarkus.runtime.annotations.Recorder; 9 | 10 | @Recorder 11 | public class SeriesRecorder { 12 | public RuntimeValue generateSeries(Map> series) { 13 | return new RuntimeValue<>( 14 | new Series(series.entrySet().stream() 15 | .collect(Collectors.toMap(Map.Entry::getKey, 16 | entry -> new Series.SeriesEntry(entry.getKey(), entry.getValue()))))); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /roq-plugin/series/runtime/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq-plugin/series/runtime/src/main/resources/META-INF/beans.xml -------------------------------------------------------------------------------- /roq-plugin/series/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin Series 2 | description: This plugin allows you to join multiple posts in a series. 3 | metadata: 4 | keywords: 5 | - website 6 | - ssg 7 | - static 8 | - generate 9 | - jekyll 10 | - hugo 11 | - lume 12 | - site 13 | - generator 14 | - web 15 | - roq 16 | - plugin 17 | - series 18 | guide: https://iamroq.com/docs/plugins/#plugin-series 19 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 20 | categories: 21 | - "web" 22 | config: 23 | - "quarkus.roq" 24 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/series/runtime/src/main/resources/messages/series_fr.properties: -------------------------------------------------------------------------------- 1 | header={title} ({count} parties) 2 | -------------------------------------------------------------------------------- /roq-plugin/series/runtime/src/main/resources/templates/partials/roq-series.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.Page page} 2 | 3 | {#if cdi:series} 4 | {#let series=cdi:series.get(page)} 5 | {#if series} 6 |
7 |

{series:header(series.title, series.documents.size)}

8 | 23 |
24 | {/if} 25 | {/let} 26 | {/if} -------------------------------------------------------------------------------- /roq-plugin/sitemap/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-sitemap-parent 12 | pom 13 | Quarkus Roq - Plugin - Sitemap 14 | 15 | deployment 16 | runtime 17 | 18 | 19 | -------------------------------------------------------------------------------- /roq-plugin/sitemap/runtime/src/main/java/io/quarkiverse/roq/plugin/sitemap/runtime/RoqPluginSitemapTemplateExtension.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.sitemap.runtime; 2 | 3 | import java.time.ZonedDateTime; 4 | import java.time.format.DateTimeFormatter; 5 | 6 | import io.quarkiverse.roq.frontmatter.runtime.model.Page; 7 | import io.quarkus.arc.Unremovable; 8 | import io.quarkus.qute.TemplateExtension; 9 | 10 | @TemplateExtension 11 | @Unremovable 12 | public class RoqPluginSitemapTemplateExtension { 13 | 14 | public static final String LAST_MODIFIED_AT = "last-modified-at"; 15 | 16 | public static ZonedDateTime lastModifiedAt(Page page) { 17 | if (page.data().containsKey(LAST_MODIFIED_AT)) { 18 | return ZonedDateTime.parse(page.data().getString(LAST_MODIFIED_AT)); 19 | } 20 | return page.date(); 21 | } 22 | 23 | public static boolean sitemap(Page page) { 24 | return page.data().getBoolean("sitemap", true); 25 | } 26 | 27 | public static String iso(ZonedDateTime date) { 28 | return date.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /roq-plugin/sitemap/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin - Sitemap 2 | description: This plugin allows to create a sitemap.xml for your site 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - generator 13 | - web 14 | - roq 15 | - ssg 16 | - sitemap 17 | - plugin 18 | guide: https://iamroq.com/docs/plugins/#plugin-sitemap 19 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 20 | categories: 21 | - "web" 22 | config: 23 | - "quarkus.roq" 24 | status: "preview" -------------------------------------------------------------------------------- /roq-plugin/sitemap/runtime/src/main/resources/templates/fm/sitemap.xml: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.NormalPage page} 2 | 3 | {#if page.data.xsl??} 4 | 5 | {/if} 6 | 7 | 8 | {#for collection in site.collections.list} 9 | {#if !collection.hidden && !collection.derived} 10 | {#for doc in collection} 11 | {#if doc.sitemap} 12 | 13 | {doc.url.absolute} 14 | {doc.lastModifiedAt.iso} 15 | 16 | {/if} 17 | {/for} 18 | {/if} 19 | {/for} 20 | {#for page in site.pages} 21 | {#if page.info.isHtml && page.sitemap} 22 | 23 | {page.url.absolute} 24 | {page.lastModifiedAt.iso} 25 | 26 | {/if} 27 | {/for} 28 | -------------------------------------------------------------------------------- /roq-plugin/tagging/deployment/src/main/java/io/quarkiverse/roq/plugin/tagging/deployment/RoqTaggingConfig.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.plugin.tagging.deployment; 2 | 3 | import io.quarkus.runtime.annotations.ConfigPhase; 4 | import io.quarkus.runtime.annotations.ConfigRoot; 5 | import io.smallrye.config.ConfigMapping; 6 | import io.smallrye.config.WithDefault; 7 | 8 | @ConfigMapping(prefix = "quarkus.roq.tagging") 9 | @ConfigRoot(phase = ConfigPhase.BUILD_TIME) 10 | public interface RoqTaggingConfig { 11 | /** 12 | * When true, all selected tags are transformed to lowercase. 13 | */ 14 | @WithDefault("false") 15 | Boolean lowercase(); 16 | } 17 | -------------------------------------------------------------------------------- /roq-plugin/tagging/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-plugin-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-plugin-tagging-parent 12 | pom 13 | Quarkus Roq - Plugin - Tagging 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | -------------------------------------------------------------------------------- /roq-plugin/tagging/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq Plugin - Tagging 2 | description: This plugin allows to generate a dynamic (derived) collection based on a given collection tags. 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - lume 11 | - site 12 | - generator 13 | - web 14 | - roq 15 | - ssg 16 | - tagging 17 | - tag 18 | - plugin 19 | guide: https://iamroq.com/docs/plugins/#plugin-tagging 20 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 21 | categories: 22 | - "web" 23 | config: 24 | - "quarkus.roq" 25 | status: "preview" -------------------------------------------------------------------------------- /roq-testing/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-testing 12 | Quarkus Roq - Testing 13 | 14 | 15 | 16 | io.quarkus 17 | quarkus-junit5 18 | 19 | 20 | io.quarkiverse.roq 21 | quarkus-roq-generator 22 | ${project.version} 23 | 24 | 25 | io.rest-assured 26 | rest-assured 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /roq-testing/src/main/java/io/quarkiverse/roq/testing/RoqAndRoll.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.testing; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) // Annotation is retained at runtime for test setup. 9 | @Target(ElementType.TYPE) // Applied only at the class level. 10 | public @interface RoqAndRoll { 11 | 12 | int port() default 8082; 13 | 14 | } 15 | -------------------------------------------------------------------------------- /roq-testing/src/main/java/io/quarkiverse/roq/testing/RoqServer.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.testing; 2 | 3 | public record RoqServer(int port) { 4 | } 5 | -------------------------------------------------------------------------------- /roq-testing/src/main/resources/META-INF/services/io.quarkus.test.junit.callback.QuarkusTestAfterAllCallback: -------------------------------------------------------------------------------- 1 | io.quarkiverse.roq.testing.RoqGeneratorTestCallback -------------------------------------------------------------------------------- /roq-testing/src/main/resources/META-INF/services/io.quarkus.test.junit.callback.QuarkusTestAfterConstructCallback: -------------------------------------------------------------------------------- 1 | io.quarkiverse.roq.testing.RoqGeneratorTestCallback -------------------------------------------------------------------------------- /roq-testing/src/main/resources/META-INF/services/io.quarkus.test.junit.callback.QuarkusTestBeforeTestExecutionCallback: -------------------------------------------------------------------------------- 1 | io.quarkiverse.roq.testing.RoqGeneratorTestCallback -------------------------------------------------------------------------------- /roq-theme/README.md: -------------------------------------------------------------------------------- 1 | This theme was converted from https://github.com/artemsheludko/flexible-jekyll/ theme made by https://github.com/artemsheludko under GNU General Public License v3.0 2 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/java/io/quarkiverse/roq/theme/ThemeMessageBundle.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq.theme; 2 | 3 | import io.quarkus.qute.i18n.Message; 4 | import io.quarkus.qute.i18n.MessageBundle; 5 | 6 | @MessageBundle(value = "roq_theme", locale = "en") 7 | public interface ThemeMessageBundle { 8 | 9 | @Message(defaultValue = "Contact me") 10 | String contact_title(); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/META-INF/beans.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | site.theme=roq-default 2 | roq-default.uuid=${quarkus.uuid} -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/partials/roq-default/404.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.DocumentPage page} 2 | 3 |
4 |

Roq! Where's my page?

5 | {#if page.image} 6 | {page.title} 7 | {/} 8 |

Roq: If you are lost, find yourself here.

9 |
-------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/partials/roq-default/head.html: -------------------------------------------------------------------------------- 1 | {@java.lang.String tag} 2 | 3 | 4 | 5 | {#seo page site /} 6 | {#rss site /} 7 | 8 | 9 | 10 | 11 | {#if site.data.containsKey('icon')} 12 | {#let icon=site.data.getString('icon')} 13 | 14 | {/let} 15 | {#else if site.imageExists('site-icon.svg')} 16 | 17 | {/if} 18 | {#let color=site.data.getString('theme-color').or("#263959")} 19 | 20 | 21 | 22 | 23 | 24 | {#bundle /} 25 | 26 | {#if site.data.containsKey("analytics")} 27 | {#ga4 tag=site.data.getJsonObject('analytics').getString("ga4", "") /} 28 | {/if} -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/partials/roq-default/pagination.html: -------------------------------------------------------------------------------- 1 |
2 | {#include fm/pagination.html} 3 | {#newer}{/newer} 4 | {#older}{/older} 5 | {/include} 6 |
-------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/partials/roq-default/sidebar-about.html: -------------------------------------------------------------------------------- 1 |
2 | {#if site.image} 3 |
4 | {site.data.name} 5 |
6 | {/if} 7 |
{site.data.name}
8 | {#insert description}

{site.description}

{/} 9 |
-------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/partials/roq-default/sidebar-copyright.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/partials/roq-default/sidebar-menu.html: -------------------------------------------------------------------------------- 1 | {@io.quarkiverse.roq.frontmatter.runtime.model.Site site} 2 | {@java.util.List menu} 3 | {@java.lang.String menuTitle} 4 | 5 | 13 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/tags/author-card.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | {name}'s Avatar 4 |
5 |
6 |

{name}

7 | {#if nested-content??}{nested-content}{/if} 8 |
9 |
10 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/theme-layouts/roq-default/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Oops! Roq is saying 404 3 | layout: roq-default/default 4 | bodyClass: page-not-found 5 | link: 404.html 6 | sitemap: false 7 | search: false 8 | --- 9 | 10 | {#insert content} 11 | {#include partials/roq-default/404 /} 12 | {/insert} 13 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/theme-layouts/roq-default/default.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {#include partials/roq-default/head.html /} 5 | {#insert head /} 6 | 7 | 8 | 9 |
10 | {#insert /} 11 |
12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/theme-layouts/roq-default/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: roq-default/main 3 | --- 4 | 5 | 6 | {@io.quarkiverse.roq.frontmatter.runtime.model.NormalPage page} 7 | 8 |
9 | {#insert /} 10 |
11 | 12 | {#if site.collections.get('posts')} 13 | {#for post in site.collections.get('posts').paginated(page.paginator)} 14 |
15 | {#if post.image} 16 | 17 | {/if} 18 |
19 |

{post.title}

20 |

{post.description}

21 | 22 | 23 | {post.readTime} minute(s) read 24 | 25 |
26 |
27 | {/for} 28 | 29 | {#include partials/roq-default/pagination.html/} 30 | {/if} -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/theme-layouts/roq-default/main.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: roq-default/default 3 | --- 4 | 5 | {@io.quarkiverse.roq.frontmatter.runtime.model.Site site} 6 | 7 | 21 |
22 | {#insert /} 23 |
24 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/theme-layouts/roq-default/page.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: roq-default/main 3 | --- 4 | 5 | {#insert before-page/} 6 | 7 | {@io.quarkiverse.roq.frontmatter.runtime.model.DocumentPage page} 8 |
9 | {#insert /} 10 |
11 | 12 | {#insert after-page/} 13 | 14 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/resources/templates/theme-layouts/roq-default/tag.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: roq-default/main 3 | paginate: true 4 | tagging: posts 5 | --- 6 | 7 | {@io.quarkiverse.roq.frontmatter.runtime.model.NormalPage page} 8 | 9 | 10 |
11 |

{page.data.tag}

12 |
13 | 14 | {#for post in site.collections.get(page.data.tagCollection).paginated(page.paginator)} 15 |
16 | {#if post.image} 17 | 18 | {/if} 19 |
20 |

{post.title}

21 |

{post.description}

22 | 23 | 24 | {post.readTime} minute(s) read 25 | 26 |
27 |
28 | {/for} 29 | 30 | {#include partials/roq-default/pagination.html/} -------------------------------------------------------------------------------- /roq-theme/default/src/main/web/roq.js: -------------------------------------------------------------------------------- 1 | import '@fortawesome/fontawesome-free/scss/fontawesome.scss'; 2 | import '@fortawesome/fontawesome-free/scss/regular.scss'; 3 | import '@fortawesome/fontawesome-free/scss/brands.scss'; 4 | import '@fortawesome/fontawesome-free/scss/solid.scss'; 5 | 6 | import './roq.scss'; -------------------------------------------------------------------------------- /roq-theme/default/src/main/web/scss/_variables.scss: -------------------------------------------------------------------------------- 1 | $body-color: #515151; 2 | $white: #ffffff; 3 | $lightgray: #fafafa; 4 | $gray: #ecf0f1; 5 | $dark-gray: #a0a0a0; 6 | $dark-blue: #263959; 7 | $dark: #333030; 8 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/web/scss/parts/_404-page.scss: -------------------------------------------------------------------------------- 1 | body.page-not-found { 2 | width: 100vw; 3 | background-color: white; 4 | .wrapper { 5 | height: 100vh; 6 | max-width: 100%; 7 | 8 | .main { 9 | height: 100%; 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | justify-content: center; 14 | 15 | img { 16 | height: 200px; 17 | } 18 | } 19 | } 20 | } 21 | 22 | -------------------------------------------------------------------------------- /roq-theme/default/src/main/web/scss/parts/_about-page.scss: -------------------------------------------------------------------------------- 1 | .authors { 2 | display: grid; 3 | grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); 4 | gap: 20px; 5 | padding: 20px; 6 | 7 | } 8 | 9 | .author-card { 10 | display: flex; 11 | flex-direction: column; 12 | align-items: center; 13 | background-color: #f9f9f9; 14 | padding: 15px; 15 | border-radius: 10px; 16 | box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); 17 | transition: transform 0.3s ease; 18 | 19 | &:hover { 20 | transform: translateY(-5px); 21 | } 22 | 23 | .avatar { 24 | width: 80px; 25 | height: 80px; 26 | overflow: hidden; 27 | border-radius: 50%; 28 | margin-bottom: 15px; 29 | 30 | img { 31 | width: 100%; 32 | height: auto; 33 | } 34 | } 35 | 36 | .details { 37 | text-align: center; 38 | display: flex; 39 | flex-direction: column; 40 | 41 | .name { 42 | margin-block-start: 0.2em; 43 | font-size: 1.5em; 44 | font-weight: bold; 45 | margin-bottom: 0; 46 | color: #333; 47 | } 48 | 49 | .author { 50 | font-weight: 500; 51 | font-size: 0.8rem; 52 | color: $dark-gray; 53 | } 54 | 55 | .login { 56 | font-size: 1.2em; 57 | color: #777; 58 | margin-bottom: 10px; 59 | } 60 | 61 | .profile-link { 62 | font-size: 1em; 63 | color: #007bff; 64 | text-decoration: none; 65 | transition: color 0.3s ease; 66 | 67 | &:hover { 68 | color: #0056b3; 69 | } 70 | } 71 | } 72 | } -------------------------------------------------------------------------------- /roq-theme/default/src/main/web/scss/parts/_series.scss: -------------------------------------------------------------------------------- 1 | .series { 2 | li { 3 | margin-bottom: 5px; 4 | } 5 | li, li a { 6 | display: flex; 7 | } 8 | 9 | a { 10 | text-decoration: none; 11 | font-weight: bold; 12 | } 13 | 14 | .index { 15 | background-color: $dark-gray; 16 | color: white; 17 | border-radius: 50%; 18 | display: inline-block; 19 | width: 30px; 20 | height: 30px; 21 | line-height: 30px; 22 | vertical-align: middle; 23 | text-align: center; 24 | font-weight: bold; 25 | margin-right: 10px; 26 | min-width: 30px; 27 | max-width: 30px; 28 | } 29 | 30 | a .index { 31 | background-color: $body-color; 32 | } 33 | } -------------------------------------------------------------------------------- /roq-theme/default/src/main/web/scss/parts/_tag.scss: -------------------------------------------------------------------------------- 1 | .blog-tags { 2 | width: 100%; 3 | background-color: $white; 4 | padding: 0 20px 20px; 5 | h1 { 6 | font-size: 30px; 7 | text-align: center; 8 | line-height: 1.3; 9 | color: $dark-blue; 10 | } 11 | h2 { 12 | color: $dark-blue; 13 | margin: 10px 0; 14 | } 15 | } 16 | 17 | .tags { 18 | margin: 0; 19 | padding: 10px; 20 | li { 21 | display: inline-block; 22 | margin: 5px; 23 | list-style: none; 24 | a { 25 | text-decoration: none; 26 | color: $dark-blue; 27 | display: inline-block; 28 | padding: 5px 10px; 29 | border: 1px solid $gray; 30 | background-color: $lightgray; 31 | transition: all .3s; 32 | &:hover { 33 | background-color: $gray; 34 | } 35 | } 36 | } 37 | } 38 | 39 | .tag-list { 40 | span { 41 | a { 42 | text-decoration: none; 43 | color: $dark-blue; 44 | &:hover { 45 | text-decoration: underline; 46 | opacity: .8; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /roq-theme/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-theme-parent 12 | pom 13 | Quarkus Roq - Themes 14 | 15 | 16 | default 17 | 18 | 19 | -------------------------------------------------------------------------------- /roq.java: -------------------------------------------------------------------------------- 1 | ///usr/bin/env jbang "$0" "$@" ; exit $? 2 | 3 | //DEPS io.vertx:vertx-core:4.5.7 4 | //DEPS io.vertx:vertx-web:4.5.7 5 | //DEPS io.netty:netty-all:4.1.109.Final 6 | 7 | import io.vertx.core.Vertx; 8 | import io.vertx.ext.web.Router; 9 | import io.vertx.ext.web.handler.StaticHandler; 10 | import java.nio.file.Path; 11 | import java.nio.file.Files; 12 | 13 | public class roq { 14 | 15 | public static void main(String[] args) { 16 | 17 | String directory = args.length > 0 ? args[0] : "target/roq/"; 18 | 19 | if (!Files.isDirectory(Path.of(directory))) { 20 | System.err.println("Directory not found: " + directory); 21 | System.exit(1); 22 | } 23 | 24 | System.out.println("Serving: " + directory); 25 | 26 | String port = args.length > 1 ? args[1]: "8181"; 27 | 28 | Vertx vertx = Vertx.vertx(); 29 | Router router = Router.router(vertx); 30 | 31 | router.route().handler(StaticHandler.create().setWebRoot(directory)); 32 | 33 | vertx.createHttpServer() 34 | .requestHandler(router) 35 | .listen(Integer.parseInt(port), result -> { 36 | if (result.succeeded()) { 37 | System.out.println("Server started on port http://localhost:" + port); 38 | } else { 39 | System.err.println("Failed to start server: " + result.cause()); 40 | } 41 | }); 42 | } 43 | } -------------------------------------------------------------------------------- /roq/deployment/src/main/resources/dummy.txt: -------------------------------------------------------------------------------- 1 | to trigger source jar -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | %no-file-slugify.site.slugify-files=false 2 | site.escaped-pages=posts/escaped** -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/error-image-site.md: -------------------------------------------------------------------------------- 1 | error image {site.image('not-found.png')} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/error-static-file.md: -------------------------------------------------------------------------------- 1 | # Hello! 2 | 3 | Here is the link {site.file('not-found.pdf')} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/ignore/.foo: -------------------------------------------------------------------------------- 1 | {error} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/2010-08-05-hello-world/hello-page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq/integration-tests/src/main/resources/content/posts/2010-08-05-hello-world/hello-page.png -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/2010-08-05-hello-world/hello.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq/integration-tests/src/main/resources/content/posts/2010-08-05-hello-world/hello.pdf -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/2010-08-05-hello-world/index.md: -------------------------------------------------------------------------------- 1 | # Hello! 2 | 3 | Here are the links: {page.file('hello.pdf')} and {page.file('./hello.pdf')} 4 | 5 | and an images: {site.image('hello.png')}, {site.image('hello.foo.png')} and {page.image('hello-page.png')} and {page.image('./hello-page.png')} 6 | 7 | page by path: {site.page('élo you$@.html').url} 8 | document by path: {site.document('posts/markdown-post-k8s.md').url} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/error-file-dir/index.md: -------------------------------------------------------------------------------- 1 | # Hello! 2 | 3 | {page.file('not-found.pdf')} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/error-file.md: -------------------------------------------------------------------------------- 1 | # Hello! 2 | 3 | Here is the link {page.file('not-found.pdf')} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/error-image-dir/index.md: -------------------------------------------------------------------------------- 1 | # Hello! 2 | 3 | {page.image('not-found.png')} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/error-image.md: -------------------------------------------------------------------------------- 1 | error image {page.image('not-found.png')} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/escape-data.md: -------------------------------------------------------------------------------- 1 | --- 2 | escape: true 3 | --- 4 | 5 | {foo} {{{{}}}}} bar {#if} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/escaped-config.md: -------------------------------------------------------------------------------- 1 | --- 2 | --- 3 | 4 | {foo} {{{{}}}}} bar {#if} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/posts/markdown-post-k8s.md: -------------------------------------------------------------------------------- 1 | --- 2 | k8s: true 3 | layout: :theme/post 4 | title: K8S Post 5 | description: This aims to solve the issue 158 6 | foo: bar 7 | date: 2024-09-09 10:45:00 +0200 8 | --- 9 | 10 | # A K8S post made with markdown 11 | 12 | ```yaml 13 | --- 14 | kind: Deployment 15 | --- 16 | kind: Pod 17 | ``` 18 | 19 | Hello! 20 | 21 | This is an attached file: {site.file("hello.txt")} 22 | 23 | Legacy: {page.image('legacy.png')} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/content/élo you$@.html: -------------------------------------------------------------------------------- 1 | {site.page('élo you.html').url} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/public/hello.txt: -------------------------------------------------------------------------------- 1 | Hello {world} -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/public/images/hello.foo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq/integration-tests/src/main/resources/public/images/hello.foo.png -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/public/images/hello.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq/integration-tests/src/main/resources/public/images/hello.png -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/public/static/assets/images/legacy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq/integration-tests/src/main/resources/public/static/assets/images/legacy.png -------------------------------------------------------------------------------- /roq/integration-tests/src/main/resources/templates/partials/roq-default/sidebar-copyright.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /roq/integration-tests/src/test/java/io/quarkiverse/roq/RoqNoSlugifyFilesTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq; 2 | 3 | import static org.hamcrest.Matchers.containsString; 4 | 5 | import org.junit.jupiter.api.Test; 6 | 7 | import io.quarkus.test.junit.QuarkusTest; 8 | import io.quarkus.test.junit.QuarkusTestProfile; 9 | import io.quarkus.test.junit.TestProfile; 10 | import io.restassured.RestAssured; 11 | 12 | @QuarkusTest 13 | @TestProfile(RoqNoSlugifyFilesTest.NoSlugifyConfig.class) 14 | public class RoqNoSlugifyFilesTest { 15 | 16 | @Test 17 | public void testPageDir() { 18 | RestAssured.when().get("/posts/2010-08-05-hello-world").then().statusCode(200).log().ifValidationFails() 19 | .body(containsString( 20 | "and an images: /images/hello.png, /images/hello.foo.png and /posts/2010-08-05-hello-world/hello-page.png and /posts/2010-08-05-hello-world/hello-page.png")); 21 | RestAssured.when().get("/images/hello.foo.png").then().statusCode(200).log().ifValidationFails(); 22 | } 23 | 24 | public static class NoSlugifyConfig implements QuarkusTestProfile { 25 | @Override 26 | public String getConfigProfile() { 27 | return "no-file-slugify"; 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /roq/integration-tests/src/test/java/io/quarkiverse/roq/RoqTemplateExtensionTest.java: -------------------------------------------------------------------------------- 1 | package io.quarkiverse.roq; 2 | 3 | import java.util.List; 4 | 5 | import org.junit.jupiter.api.Assertions; 6 | import org.junit.jupiter.api.Test; 7 | 8 | import io.quarkiverse.roq.frontmatter.runtime.RoqTemplateExtension; 9 | 10 | public class RoqTemplateExtensionTest { 11 | @Test 12 | public void testAsStrings() { 13 | var tags = List.of("tag1", "tag2", "tag3", "tag-four"); 14 | Assertions.assertEquals(tags, 15 | RoqTemplateExtension.asStrings("tag1 tag2 tag3 tag-four")); 16 | Assertions.assertEquals(tags, 17 | RoqTemplateExtension.asStrings("tag1,tag2,tag3,tag-four")); 18 | Assertions.assertEquals(tags, 19 | RoqTemplateExtension.asStrings("tag1, tag2, tag3, tag-four")); 20 | Assertions.assertEquals(tags, 21 | RoqTemplateExtension.asStrings("tag1;tag2;tag3;tag-four")); 22 | Assertions.assertEquals(tags, 23 | RoqTemplateExtension.asStrings("tag1; tag2; tag3; tag-four")); 24 | Assertions.assertEquals(tags, 25 | RoqTemplateExtension.asStrings("tag1\ttag2\ttag3\ttag-four")); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /roq/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.quarkiverse.roq 7 | quarkus-roq-project-parent 8 | 999-SNAPSHOT 9 | ../pom.xml 10 | 11 | quarkus-roq-parent 12 | pom 13 | Quarkus Roq - Parent 14 | 15 | 16 | deployment 17 | runtime 18 | 19 | 20 | 21 | it 22 | 23 | 24 | performRelease 25 | !true 26 | 27 | 28 | 29 | integration-tests 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/.github/workflows/deploy.yml: -------------------------------------------------------------------------------- 1 | name: Roq Site Deploy 2 | 3 | on: 4 | push: 5 | branches: [ main ] # Switch to the branch which should be deployed to GitHub Pages 6 | workflow_dispatch: 7 | 8 | jobs: 9 | build: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@v4 13 | - name: Generate Roq Site 14 | uses: quarkiverse/quarkus-roq@v1 15 | with: 16 | github-token: ${{ secrets.GITHUB_TOKEN }} # Used to automatically get the GitHub Pages url 17 | deploy: 18 | environment: 19 | name: github-pages 20 | url: ${{ steps.deployment.outputs.page_url }} 21 | permissions: 22 | pages: write # to deploy to Pages 23 | id-token: write # to verify the deployment originates from an appropriate source 24 | runs-on: ubuntu-latest 25 | needs: build 26 | steps: 27 | - name: Deploy to GitHub Pages 28 | id: deployment 29 | uses: actions/deploy-pages@v4 -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/content/404.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: :theme/404 3 | image: iamroq.png 4 | --- 5 | -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/content/about.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: About 3 | description: | 4 | Roq is a powerful static site generator that combines the best features of tools like Jekyll and Hugo, but within the Java ecosystem. It offers a modern approach with Quarkus at its core, requiring zero configuration to get started —ideal for developers who want to jump right in, while still being flexible enough for advanced users to hook into Java for deeper customization. 5 | layout: :theme/page 6 | --- 7 | 8 | # About Roq 9 | 10 | Roq is a powerful static site generator that combines the best features of tools like Jekyll and Hugo, but within the Java ecosystem. It offers a modern approach with Quarkus at its core, requiring zero configuration to get started —ideal for developers who want to jump right in, while still being flexible enough for advanced users to hook into Java for deeper customization. 11 | 12 | ## Authors 13 | 14 |
15 | 16 | {#for id in cdi:authors.fields} 17 | {#let author=cdi:authors.get(id)} 18 | 19 | {#author-card name=author.name avatar=author.avatar nickname=author.nickname profile=author.profile /} 20 | {/for} 21 |
22 | 23 | -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/content/index.html: -------------------------------------------------------------------------------- 1 | --- 2 | title: Hello, world! I'm Roq 3 | description: I provide you with all the tools to generate static websites with Quarkus super-powers. 4 | name: I am ROQ 5 | simple-name: ROQ 6 | image: iamroq.png 7 | social-twitter: quarkusio 8 | social-facebook: 9 | social-github: quarkiverse/quarkus-roq 10 | social-linkedin: quarkusio 11 | layout: :theme/index 12 | --- 13 | 14 |

Ready to Roq my world!

-------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/content/posts/2024-10-13-the-first-roq/blog.avif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/content/posts/2024-10-13-the-first-roq/blog.avif -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/content/posts/2024-10-13-the-first-roq/index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "The First Roq!" 3 | description: This is my first article ever made with Quarkus Roq 4 | image: blog.avif 5 | tags: blogging 6 | author: roqqy 7 | cool: this is cool :) 8 | fun: and fun! 9 | --- 10 | 11 | You can access page data like this: 12 | ```markdown 13 | * \{page.data.cool} 14 | * \{page.data.fun} 15 | ``` 16 | **will render ⤵** 17 | 18 | * {page.data.cool} 19 | * {page.data.fun} 20 | 21 | 22 | There are a few helpers on the `page` variable ([more on variables](https://iamroq.com/docs/basics/#_variables)): 23 | 24 | ```markdown 25 | > \{page.date.format('YYYY')}: \{page.description} 26 | ``` 27 | **will render ⤵** 28 | 29 | > {page.date.format('YYYY')}: {page.description} 30 | 31 | --- 32 | 33 | It's time to write awesome articles! 34 | 35 | __Thank you!__ 36 | 37 | **PS:** To make the tag work ([#blogging]({site.url.resolve('posts/tag/blogging')})), you need to [enable tagging](https://iamroq.com/docs/plugins/#plugin-tagging). -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/data/authors.yml: -------------------------------------------------------------------------------- 1 | roqqy: 2 | name: "Roqqy Balboa" 3 | job: Roq Boxer 4 | nickname: roqqy 5 | profile: "https://github.com/quarkiverse/quarkus-roq" 6 | avatar: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/refs/heads/main/blog/public/images/iamroq.png" 7 | bio: | 8 | Quarkus is my go-to framework for making Java development not only faster but more fun. 9 | I’m driven by the mission to create high-performance, lightweight microservices that scale effortlessly in the cloud. 10 | With Quarkus, I can push Java to its limits, and nothing excites me more than exploring new ways to optimize and streamline applications with this amazing toolkit. 11 | -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/data/menu.yml: -------------------------------------------------------------------------------- 1 | items: 2 | - title: "Blog" 3 | path: "/" 4 | icon: "fa-regular fa-newspaper" 5 | - title: "Documentation" 6 | path: "https://iamroq.com/docs/" 7 | icon: "fa-solid fa-book" 8 | target: "_blank" 9 | - title: "About" 10 | path: "/about" 11 | icon: "fa fa-thumbs-up" -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/public/images/iamroq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/quarkiverse/quarkus-roq/a09ddaf80c261c416930728cde61e39feb25ee76/roq/runtime/src/main/codestarts/quarkus/roq-codestart/base/public/images/iamroq.png -------------------------------------------------------------------------------- /roq/runtime/src/main/codestarts/quarkus/roq-codestart/codestart.yml: -------------------------------------------------------------------------------- 1 | name: roq-codestart 2 | ref: roq 3 | type: code 4 | tags: extension-codestart 5 | metadata: 6 | title: Roq 7 | description: This codestart provides a starter Roq site. 8 | related-guide-section: https://quarkiverse.github.io/quarkiverse-docs/quarkus-roq/dev/ 9 | language: 10 | base: 11 | dependencies: 12 | - "io.quarkiverse.roq:quarkus-roq-theme-default:${project.version}" 13 | -------------------------------------------------------------------------------- /roq/runtime/src/main/resources/META-INF/quarkus-extension.yaml: -------------------------------------------------------------------------------- 1 | name: Roq 2 | description: Hello, world! I’m Roq — a fun little SSG (Static Site Generator) with a Java soul and Quarkus energy. 3 | metadata: 4 | keywords: 5 | - website 6 | - static 7 | - generate 8 | - jekyll 9 | - hugo 10 | - ssg 11 | - lume 12 | - site 13 | - generator 14 | - web 15 | guide: https://iamroq.com/docs/ 16 | icon-url: "https://raw.githubusercontent.com/quarkiverse/quarkus-roq/main/docs/modules/ROOT/assets/images/roq.svg" 17 | categories: 18 | - "web" 19 | config: 20 | - "quarkus.roq" 21 | status: "preview" 22 | codestart: 23 | name: "roq" 24 | languages: 25 | - "java" 26 | - "kotlin" 27 | - "scala" 28 | artifact: "io.quarkiverse.roq:quarkus-roq:codestarts:jar:${project.version}" 29 | --------------------------------------------------------------------------------