{"id":26022972,"url":"https://github.com/agrison/jssg","last_synced_at":"2025-07-26T09:16:53.805Z","repository":{"id":145285693,"uuid":"8329591","full_name":"agrison/jssg","owner":"agrison","description":"Java static site generator","archived":false,"fork":false,"pushed_at":"2014-06-12T05:03:39.000Z","size":1262,"stargazers_count":20,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-09T06:05:29.035Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/agrison.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-02-21T06:20:41.000Z","updated_at":"2024-06-28T12:53:55.000Z","dependencies_parsed_at":"2023-06-03T17:15:06.866Z","dependency_job_id":null,"html_url":"https://github.com/agrison/jssg","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/agrison/jssg","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agrison%2Fjssg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agrison%2Fjssg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agrison%2Fjssg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agrison%2Fjssg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/agrison","download_url":"https://codeload.github.com/agrison/jssg/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/agrison%2Fjssg/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267144726,"owners_count":24042641,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"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":"2025-03-06T10:37:37.011Z","updated_at":"2025-07-26T09:16:53.778Z","avatar_url":"https://github.com/agrison.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Jssg: Java Static Site Generator\n\nJssg is a simple static site generator like Jekyll, but with less features and written in Java.\nThe concept behind is the same as all static site generators.\nThe program takes a directory containing blog posts and site pages written in either `Markdown` or `Textile`, and merge the generated markup in a complete set of `HTML` files using `Freemarker`.\nThen the site can be easily put on any web server, or even on GitHub.\n\n## Getting Started\n\n### Install Jssg\n\nTo get a copy of **jssg** just clone the git repository and `mvn package`.\n\n    $ git clone git://github.com/agrison/jssg.git\n    $ cd jssg\n    $ mvn package\n    -- add jsgg to your $PATH\n\n### Init\n\nTo create a default site structure, just call `jssg -init`.\n\n    $ mkdir myblog\n    $ cd myblog\n    $ jssg -init\n\nAfter the `init` command has finish to run, you should have the following structure:\n\n    + _layout/\n    |--+ index.html\n    |--+ blog.html\n    + _posts/\n    |--+ yyyy-MM-dd-Hello.markdown\n    |--+ 2011-11-20-Unix-Prompt.markdown\n    + index.textile\n    + config.properties\n\nYou can edit some of the properties in the `config.properties` file, for instance the path to `pygments`.\n\n* A default index page content is written in the `index.textile` file, and its layout is written in `_layout/index.html`.\n* A default blog post is written in the `_posts/yyyy-MM-dd-Hello.mkd` file, and its layout is written in `_layout/blog.html`.\n\n### Write content\n\nWith the `jssg -init` command you have already a default index page and a first blog post, but you can add more if you want.\n\n    $ cat \u003c\u003cEOF \u003e _posts/2011-10-29-Hello.mkd\n    ---\n    title: Hello\n    layout: blog\n    description: Welcome\n    date: 2011-10-29\n    comments: true\n    url: /2011/10/29/Hello\n    ---\n\n    Hello\n    ==============\n    Welcome to my blog.\n    EOF\n\nWrite an about page.\n\n    $ cat \u003c\u003cEOF \u003e about.textile\n    ---\n    title: My awesome webpage\n    layout: index\n    description: About page\n    ---\n\n    h2. About\n\n    I'm what's up New York.\n\n### Create your layout\n\nIf you need to customize the layouts, the files are located in `_layouts`, below are two commands that shows what are the defaults\nbundled in the sample.\n\n    $ cat \u003c\u003cEOF \u003e _layout/blog.html\n    \u003c!DOCTYPE html\u003e\n    \u003chtml\u003e\n       \u003chead\u003e\n          \u003ctitle\u003e${header['title']}\u003c/title\u003e\n       \u003c/head\u003e\n       \u003cbody\u003e\n           \u003cdiv class=\"content\"\u003e\n               \u003cspan\u003e${header['date']?date?string.medium}\u003c/span\u003e\n\n               ${content}\n\n               \u003c#if header['comments']??\u003e\n               \u003cdiv id=\"comments\"\u003e\n                   \u003cdiv id=\"disqus_thread\"\u003e\u003c/div\u003e\n                   \u003cscript type=\"text/javascript\"\u003e\n                     var disqus_shortname = '***';\n                     var disqus_identifier = '/blog/${header['title']}';\n                     var disqus_url = 'http://www.foo.com${header['url']}';\n                     var disqus_developer = 1;\n                     (function() {\n                         var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;\n                         dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';\n                         (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);\n                     })();\n                   \u003c/script\u003e\n                   \u003cnoscript\u003ePlease enable JavaScript to view the \u003ca href=\"http://disqus.com/?ref_noscript\"\u003ecomments powered by Disqus.\u003c/a\u003e\u003c/noscript\u003e\n               \u003c/div\u003e\n               \u003c/#if\u003e\n           \u003c/div\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e\n\nCreate the index page:\n\n    $ cat \u003c\u003cEOF \u003e _layout/index.html\n    \u003c!DOCTYPE html\u003e\n    \u003chtml\u003e\n       \u003chead\u003e\n          \u003ctitle\u003eWelcome to my website\u003c/title\u003e\n       \u003c/head\u003e\n       \u003cbody\u003e\n          \u003cdiv class=\"content\"\u003e\n              ${content}\n\n             \u003ch2\u003eBlog posts\u003c/h2\u003e\n             \u003cul\u003e\n             \u003c#assign blogPosts = posts?sort_by(\"date\")\u003e\n             \u003c#foreach post in blogPosts?reverse\u003e\n                \u003cli\u003e\u003cspan class=\"date\"\u003e${post.date?date?string.medium}\u003c/span\u003e \u0026mdash; \u003ca href=\"${post.url}\"\u003e${post.title}\u003c/a\u003e\u003c/li\u003e\n             \u003c/#foreach\u003e\n             \u003c/ul\u003e\n          \u003c/div\u003e\n        \u003c/body\u003e\n    \u003c/html\u003e\n\n### Run jssg\n\nRun the command `jssg -build -serve` to generate the whole site, then browse the site.\n\n    $ jssg -build -serve\n          .--.\n        .--,`|   .--.--.      .--.--.      ,----._,.\n        |  |.   /  /    '    /  /    '    /   /  ' /\n        '--`_  |  :  /`./   |  :  /`./   |   :     |\n        ,--,'| |  :  ;_     |  :  ;_     |   | .\\  .\n        |  | '  \\  \\    `.   \\  \\    `.  .   ; ';  |\n        :  | |   `----.   \\   `----.   \\ '   .   . |\n      __|  : '  /  /`--'  /  /  /`--'  /  `---`-'| |\n    .'__/\\_: | '--'.     /  '--'.     /   .'__/\\_: |\n    |   :    :   `--'---'     `--'---'    |   :    :\n     \\   \\  /                              \\   \\  /\n      `--`-'                                `--`-'\n\n    Looking for posts in _posts/\n      About to process 1 file\n        + Processing 2011-10-29-Hello.markdown...\n\n    Looking for pages in ./\n      About to process 1 file\n        + Processing index.textile...\n\n    Site generated in 0.50 sec\n    Starting the Jetty server at http://localhost:9876 ...\n\n    $ curl http://localhost:9876/2011/10/29/Hello | grep Hello\n    \u003ctitle\u003eHello\u003c/title\u003e\n         \u003ch1 id=\"hello\"\u003eHello\u003c/h1\u003e\n               var disqus_identifier = '/blog/Hello';\n               var disqus_url = 'http://www.foo.com/2011/10/29/Hello';\n\n    $ curl http://localhost:9876 | grep personal\n    \u003cp\u003eWelcome to my personal web site. You will find some great stuff here.\u003c/p\u003e\n\n    $ open http://localhost:9876\n\nWhen you run `jssg` with the `-serve` argument, it rebuilds any post or static page that you modify when it notices it,\nso that you just have to refresh your browser.\n\n## How it works\n\nInvoking `jssg -build` will build the website by doing specific tasks:\n\n* Scan the `_posts/` directory for each file having the pattern `yyyy-MM-dd-something.(mkd|markdown|textile)`\n    * Detect code snippets (if any)\n    * Generate the HTML markup equivalent for the `Markdown` or `Textile` file content\n    * Highlight code snippets with (`Jygments` / `Pygments`)\n    * Merge the HTML into the layout found in the `_layout/` directory using Freemarker\n    * Write the whole content in `_build/yyyy/MM/dd/something`\n* Scan the current directory for each file having the `mkd|markdown|textile` extension\n    * Do exactly the same as above\n* Copy everything that is in the current directory that has not already been processed into the `_build/` directory.\n\nAll these tasks are being executed automatically and takes just seconds.\n\n## Dependencies\n\n**Jssg** supports code snippets higlighting through `Pygments`, so it should be in your `PATH` or you may set the path to it in the `config.properties` file.\n\n**Jssg** is packaged as only one big fat JAR which includes all its dependencies.\nThese dependencies are resolved through Maven or via the `libs` directory bundled with the source code:\n\n* Spring\n* Google Guava\n* Markdown4J\n* Textile4j\n* Freemarker\n* SnakeYaml\n* Jsoup\n* Jygments\n* Logback\n* Args4j\n* Jetty\n\n## Todos\n\n* Refactoring of external formatters, to generate multiple outputs like `LaTeX`, `PDF` through `Flying Saucer`, ...\n* More features\n* Less bugs.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagrison%2Fjssg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fagrison%2Fjssg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fagrison%2Fjssg/lists"}