{"id":27559434,"url":"https://github.com/elixir-tools/tableau","last_synced_at":"2026-01-08T21:13:04.176Z","repository":{"id":40567516,"uuid":"381558501","full_name":"elixir-tools/tableau","owner":"elixir-tools","description":"Static Site Generator","archived":false,"fork":false,"pushed_at":"2025-04-17T02:16:21.000Z","size":376,"stargazers_count":216,"open_issues_count":2,"forks_count":12,"subscribers_count":5,"default_branch":"main","last_synced_at":"2025-04-20T00:02:57.636Z","etag":null,"topics":["elixir","static-site-generator"],"latest_commit_sha":null,"homepage":"","language":"Elixir","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/elixir-tools.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2021-06-30T03:00:39.000Z","updated_at":"2025-04-17T02:16:15.000Z","dependencies_parsed_at":"2023-10-11T01:49:10.288Z","dependency_job_id":"2dfa1a64-46f2-46f9-b260-802b58e730ac","html_url":"https://github.com/elixir-tools/tableau","commit_stats":null,"previous_names":["mhanberg/tableau"],"tags_count":30,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-tools%2Ftableau","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-tools%2Ftableau/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-tools%2Ftableau/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/elixir-tools%2Ftableau/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/elixir-tools","download_url":"https://codeload.github.com/elixir-tools/tableau/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253518294,"owners_count":21921030,"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","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":["elixir","static-site-generator"],"created_at":"2025-04-20T00:02:43.730Z","updated_at":"2026-01-08T21:13:04.170Z","avatar_url":"https://github.com/elixir-tools.png","language":"Elixir","funding_links":[],"categories":["Elixir"],"sub_categories":[],"readme":"# Tableau\n\n[![Discord](https://img.shields.io/badge/Discord-5865F3?style=flat\u0026logo=discord\u0026logoColor=white\u0026link=https://discord.gg/nNDMwTJ8)](https://discord.gg/6XdGnxVA2A)\n[![Hex.pm](https://img.shields.io/hexpm/v/tableau)](https://hex.pm/packages/tableau)\n[![Hex Docs](https://img.shields.io/badge/hex-docs-lightgreen.svg)](https://hexdocs.pm/tableau/)\n[![GitHub Discussions](https://img.shields.io/github/discussions/elixir-tools/tableau)](https://github.com/elixir-tools/tableau/discussions)\n\nStatic Site Generator for Elixir.\n\n## Goals\n\n- [x] Good code and browser reloading on file change\n- [x] Easy to use the current Node.js JS/CSS tooling\n- [x] Extensions\n- [x] Ability to work with \"data\" (either dynamic data or static files)\n    - [x] YAML Files\n    - [x] Elixir scripts (.exs files)\n- [ ] Handles stuff like Posts, RSS, sitemap, SEO.\n    - [x] Posts\n    - [x] RSS\n    - [x] Sitemap\n    - [x] Tags\n    - [ ] SEO\n- [x] Project generator\n\n## Installation\n\nThe easiest way to get started is to generate a new project using the `tableau.new` mix task.\n\nCurrently the generator can create a website using several different template syntaxes and assets frameworks.\n\n- Templates\n  - [HEEx](https://github.com/phoenixframework/phoenix)\n  - [Temple](https://github.com/mhanberg/temple)\n  - EEx\n- Assets\n  - [TailwindCSS](https://tailwindcss.com)\n  - Vanilla (Just a regular CSS file)\n\nPlease run `mix help tableau.new` or `mix tableau.new --help` to see all of the possible flags.\n\n```\nmix archive.install hex tableau_new\n\nmix tableau.new my_awesome_site\n```\n\nOtherwise, you can just install Tableau into a new mix project.\n\n```elixir\ndef deps do\n  [\n    {:tableau, \"~\u003e 0.26\"}\n  ]\nend\n```\n\nDocumentation can be found at \u003chttps://hexdocs.pm/tableau\u003e.\n\n## Built with Tableau\n\n| Site                                                       | Template                                                                      | Styling    | Template | Source                                                                            |\n|------------------------------------------------------------|-------------------------------------------------------------------------------|------------|----------|-----------------------------------------------------------------------------------|\n| [www.elixir-tools.dev](https://www.elixir-tools.dev)       | [Temple](https://github.com/mhanberg/temple)                                  | Tailwind   |          | [elixir-tools/elixir-tools.dev](https://github.com/elixir-tools/elixir-tools.dev) |\n| [www.mitchellhanberg.com](https://www.mitchellhanberg.com) |  [Temple](https://github.com/mhanberg/temple)                                  | Tailwind   |          | [mhanberg/blog](https://github.com/mhanberg/blog)                                 |\n| [pdx.su](https://pdx.su)                                   | [Temple](https://github.com/mhanberg/temple)                                  | CSS        |          | [paradox460/pdx.su](https://github.com/paradox460/pdx.su)                         |\n| [Xmeyers](https://andyl.github.io/xmeyers)                 | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | Tailwind   |          | [andyl/xmeyers](https://github.com/andyl/xmeyers)                                 |\n| [0x7f](https://0x7f.dev)                                   | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | magick.css |          | [0x7fdev/site](https://github.com/0x7fdev/site)                                   |\n| Hackery                                                    | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | Tailwind   | ✅       | [mhanberg/hackery](https://github.com/mhanberg/hackery)                           |\n| [doneth.dev](https://doneth.dev)                           | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | Tailwind   |          | [JohnDoneth/doneth.dev](https://github.com/JohnDoneth/doneth.dev)                 |\n| [joelkoch.dev](https://joelkoch.dev)                       | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | Tailwind   |          | [joelpaulkoch/joelkoch.dev](https://github.com/joelpaulkoch/joelkoch.dev)         |\n| [www.ethangunderson.com](https://www.ethangunderson.com/)  | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | Tailwind   |          | [ethangunderson/website](https://github.com/ethangunderson/website)               |\n| [https://adrienanselme.com/](https://adrienanselme.com/)   | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | Tailwind   |          | [adanselm/adanselm.github.io](https://github.com/adanselm/adanselm.github.io)     |\n| [acrogenesis.com](https://acrogenesis.com)                  | [HEEx](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) | CSS        |          | [acrogenesis/acrogenesis.com](https://github.com/acrogenesis/acrogenesis.com)     |\n\n## Getting Started\n\nThe examples in the README use the [Temple](https://github.com/mhanberg/temple) library to demonstrate that Tableau can be used with any markup language of your choice. You could easily use the builtin EEx, or use HEEx, Surface, or HAML.\n\n### Layouts\n\nLayouts are modules that use the `use Tableau.Layout` macro.\n\nLayouts have access to the `@site` and `@page` assign.\n\nThe `@site` assign contains your site's config.\n\nThe `@page` assign contains all the options passed to the `use Tableau.Page` macro.\n\n```elixir\ndefmodule MySite.RootLayout do\n  use Tableau.Layout\n\n  import Temple\n\n  def template(assigns) do\n    temple do\n      \"\u003c!DOCTYPE html\u003e\"\n\n      html lang: \"en\" do\n        head do\n          meta charset: \"utf-8\"\n          meta http_equiv: \"X-UA-Compatible\", content: \"IE=edge\"\n          meta name: \"viewport\", content: \"width=device-width, initial-scale=1.0\"\n\n          title do\n            @page.some_assign\n          end\n\n          link rel: \"stylesheet\", href: \"/css/site.css\"\n        end\n\n        body class: \"font-sans\" do\n          main class: \"container mx-auto px-2\" do\n            div class: \"border-4 border-green-500\" do\n              a class: \"text-blue-500 hover:underline\", href: \"/about\" do\n                \"About\"\n              end\n\n              a class: \"text-blue-500 hover:underline\", href: \"/posts\" do\n                \"Posts\"\n              end\n\n              render @inner_content\n            end\n          end\n        end\n\n        if Mix.env() == :dev do\n          c \u0026Tableau.live_reload/1\n        end\n      end\n    end\n  end\nend\n```\n\n#### Page\n\nPages are modules that use the `use Tableau.Page` macro.\n\nRequired options:\n\n* `:layout` - which layout module to use.\n* `:permalink` - the permalink of the page\n\nAny remaining options are arbitrary and will be available under the `@page` assign available to layout and page templates.\n\n```elixir\ndefmodule MySite.AboutPage do\n  use Tableau.Page,\n    layout: MySite.RootLayout,\n    permalink: \"/about\",\n    some_assign: \"foo\"\n\n  import Temple\n\n  def template(assigns) do\n    temple do\n      span class: \"text-red-500 font-bold\" do\n        \"i'm a super cool and smart!\"\n      end\n    end\n  end\nend\n```\n\n### Live Reloading\n\nYou can specify a set of directories/files to watch for changes, and the browser will automatically refresh.\n\n```elixir\n# config/config.exs\nimport Config\n\nconfig :tableau, :reloader,\n  patterns: [\n    ~r\"lib/layouts/.*.ex\",\n    ~r\"lib/pages/.*.ex\",\n    ~r\"lib/components.ex\",\n    ~r\"_site/.*.css\"\n  ]\n```\n\nAll you need to do is render the `Tableau.live_reload/1` component right after your `body` tag.\n\n```elixir\n# lib/layouts/app.ex\n\ndefmodule YourApp.Layouts.App do\n  use Tableau.Layout\n\n  import Temple\n\n  def template(assigns) do\n    temple do\n      \"\u003c!DOCTYPE html\u003e\"\n\n      html lang: \"en\" do\n        head do\n          meta charset: \"utf-8\"\n          meta http_equiv: \"X-UA-Compatible\", content: \"IE=edge\"\n          meta name: \"viewport\", content: \"width=device-width, initial-scale=1.0\"\n\n          link rel: \"stylesheet\", href: \"/css/site.css\"\n        end\n\n        body class: \"font-sans\" do\n          main class: \"container mx-auto px-2\" do\n            render(@inner_content)\n          end\n        end\n\n        if Mix.env() == :dev do\n          c \u0026Tableau.live_reload/1\n        end\n      end\n    end\n  end\nend\n```\n\n\n### JS/CSS\n\nYou can arbitrarily start other build tools as \"watchers\". This is inspired by the way Phoenix does it.\n\n```elixir\n# config/config.exs\n\nimport Config\n\nconfig :tableau, :assets,\n  npx: [\n    \"tailwindcss\",\n    \"-o\",\n    \"_site/css/site.css\",\n    \"--watch\"\n  ]\n\n# or if you are using a package similar to the TailwindCSS hex package\n\nconfig :tableau, :assets, tailwind: {Tailwind, :install_and_run, [:default, ~w(--watch)]}\n\nimport_config \"#{config_env()}.exs\"\n```\n\nThis will start a long running process that will independently build your CSS as it sees files change.\n\nThese are started automatically when you run `mix tableau.server`.\n\n### Static Assets\n\nOther static assets can be copied into the \"out\" directory by placing them in an `extra` directory in the root of your project.\n\nThis directory can be configured.\n\n```elixir\nconfig :tableau, :config,\n  include_dir: \"static\"\n```\n\n### Development\n\nThe dev server can be started with `mix tableau.server`. On file change, a browser reload will be triggered and the page your requesting will be re-built during the request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-tools%2Ftableau","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Felixir-tools%2Ftableau","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Felixir-tools%2Ftableau/lists"}