{"id":19848650,"url":"https://github.com/polterguy/magic.web.markdown-articles","last_synced_at":"2026-03-04T02:31:40.453Z","repository":{"id":84670131,"uuid":"568422030","full_name":"polterguy/magic.web.markdown-articles","owner":"polterguy","description":null,"archived":false,"fork":false,"pushed_at":"2022-11-21T05:49:51.000Z","size":29,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T23:02:31.483Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://ainiro.io","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/polterguy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-11-20T13:42:32.000Z","updated_at":"2023-04-13T17:47:44.000Z","dependencies_parsed_at":null,"dependency_job_id":"26a66eaa-e650-47d4-bd8e-2faa0cb79e4a","html_url":"https://github.com/polterguy/magic.web.markdown-articles","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/polterguy/magic.web.markdown-articles","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polterguy%2Fmagic.web.markdown-articles","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polterguy%2Fmagic.web.markdown-articles/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polterguy%2Fmagic.web.markdown-articles/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polterguy%2Fmagic.web.markdown-articles/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/polterguy","download_url":"https://codeload.github.com/polterguy/magic.web.markdown-articles/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/polterguy%2Fmagic.web.markdown-articles/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30070079,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T01:03:42.280Z","status":"online","status_checked_at":"2026-03-04T02:00:07.464Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-12T13:17:53.468Z","updated_at":"2026-03-04T02:31:40.405Z","avatar_url":"https://github.com/polterguy.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n# Markdown article plugin for magic.web\r\n\r\nThis plugin allows you to easily implement Markdown article support for your dynamically rendered Hyperlambda\r\nwebsites. Each article is supplied by creating a Markdown file within some folder, with front matter parts\r\ndeclaring the title of the article, and its content such as follows.\r\n\r\n```markdown\r\n---\r\ntitle: Hello world\r\n---\r\nThis is an example article.\r\n\r\n1. This is some numbered list\r\n2. This is another list item\r\n\r\nThis is a [hyperlink](https://aista.com) leading to Aista's website.\r\n```\r\n\r\nThe plugin contains several _\"mixin\"_ components that can be used to list articles, get article\r\ncontent, etc.\r\n\r\n## Listing articles\r\n\r\nAssuming you have this plugin inside of _\"/etc/plugins/magic.web.markdown-articles/\"_, and your actual\r\narticles inside of _\"/etc/articles/\"_ this mixin allows you to render a list of articles in your\r\ninstallation such as follows.\r\n\r\n**/index.hl**\r\n\r\n```\r\n.list-articles\r\n   io.file.mixin:/etc/plugins/magic.web.markdown-articles/list.html\r\n      .root-url:/articles/\r\n      .root-folder:/etc/articles/\r\n   return:x:-\r\n```\r\n\r\nThe above **[.root-url]** is the root URL of where you want users to be able to read your articles, and\r\nthe above **[.root-folder]** parts is the physical folder on disc where you keep your Markdown files.\r\nThe above could be referenced in your HTML such as follows.\r\n\r\n**/index.html**\r\n\r\n```html\r\n\u003cdiv class=\"articles\"\u003e\r\n{{*/.list-articles}}\r\n\u003c/div\u003e\r\n```\r\n\r\nThe above will return a bulleted list of all articles it can find in your _\"/etc/articles/\"_ folder.\r\nThe **[.root-url]** argument is the root URL of where individual articles can be found. If you for\r\ninstance have a file named _\"/etc/articles/hello-world.md\"_ the above will result in the following\r\nroot URL _\"/articles/hello-world\"_. Below is an example of its output.\r\n\r\n```html\r\n\u003cul\u003e\r\n  \u003cli\u003e\u003ca href=\"/articles/hello-world\"\u003eHello World\u003c/a\u003e\u003c/li\u003e\r\n\u003c/ul\u003e\r\n```\r\n\r\nYou can also invoke the list articles mixin with a **[.verbose]** argument with a value of `true`,\r\nat which point the returned HTML will resemble the following.\r\n\r\n```html\r\n\u003cul\u003e\r\n  \u003cli\u003e\r\n    \u003ca href=\"/articles/hello-world\"\u003e\r\n      \u003ch3\u003eHello world\u003c/h3\u003e\r\n      \u003cimg src=\"https://aista.com/wp-content/uploads/2022/11/twitter-elon.jpg\" alt=\"Hello world\"\u003e\r\n      \u003cspan\u003eThis is an excerpt\u003c/span\u003e\r\n    \u003c/a\u003e\r\n  \u003c/li\u003e\r\n\u003c/ul\u003e\r\n```\r\n\r\nNotice, if you do, your article Markdown files needs to have at least the following front matter\r\nparts declared.\r\n\r\n```markdown\r\n---\r\ntitle: Hello world\r\nexcerpt: This is an excerpt\r\nimage: https://aista.com/wp-content/uploads/2022/11/twitter-elon.jpg\r\n---\r\n... article content ...\r\n```\r\n\r\n## Displaying articles\r\n\r\nTo actually resolve individual articles, you'll need a _\"default.hl\"_ file, a _\"default.html\"_\r\nfile, and an _\"interceptor.hl\"_ file that can be found in whatever **[.root-url]** folder you choose\r\nto render your articles from. Below is an example of all 3 required files.\r\n\r\n**/articles/interceptor.hl**\r\n\r\n```\r\n/*\r\n * Interceptor for articles, doing all the heavy lifting, actually\r\n * loading articles, by intercepting the main display article Hyperlambda file.\r\n */\r\n\r\n// Executing get-article Hyperlambda file, putting content into [.article] node.\r\n.article\r\nadd:x:@.article\r\n   io.file.execute:/etc/plugins/magic.web.markdown-articles/get-article.hl\r\n      .root-folder:/etc/articles/\r\n\r\n// Interceptor node, replaced by default.hl Hyperlambda content.\r\n.interceptor\r\n```\r\n\r\n**/articles/default.html**\r\n\r\n```\r\n\u003chtml\u003e\r\n  \u003chead\u003e\r\n    \u003ctitle\u003e{{@.article/*/title}}\u003c/title\u003e\r\n  \u003c/head\u003e\r\n  \u003cbody\u003e\r\n    \u003ch1\u003e{{@.article/*/title}}\u003c/h1\u003e\r\n    \u003cdiv\u003e\r\n{{@.article/*/content}}\r\n    \u003c/div\u003e\r\n  \u003c/body\u003e\r\n\u003c/html\u003e\r\n```\r\n\r\n**/articles/default.hl**\r\n\r\n```\r\n/*\r\n * Since we don't have any logic in our actual article Hyperlambda file,\r\n * this file can be empty, since all the heavy lifting is actually done\r\n * in the interceptor file, and expressions in HTML file are leading\r\n * directly to nodes in our interceptor file.\r\n *\r\n * However, the file still needs to exist on disc, otherwise the endpoint\r\n * resolver will load the file as static content, and never return the file\r\n * as a mixin.\r\n */\r\n```\r\n\r\nThe point with the above, is that your interceptor loads the article's content once,\r\nand then adds the semantic content from your Markdown file into its **[.blog]** node,\r\nbefore the default URL resolver executes, which at that point can reference values\r\nfrom your blog, such as its content, title, etc. The URL dynamically ends up resolving\r\nto the filename of whatever article the user is requesting. A URL of for\r\ninstance _\"/articles/foo\"_ resolves to the physical file _\"/etc/articles/foo.md\"_.\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolterguy%2Fmagic.web.markdown-articles","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpolterguy%2Fmagic.web.markdown-articles","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpolterguy%2Fmagic.web.markdown-articles/lists"}