{"id":13878269,"url":"https://github.com/opal/paggio","last_synced_at":"2025-08-23T15:16:55.289Z","repository":{"id":46053741,"uuid":"15139334","full_name":"opal/paggio","owner":"opal","description":"Ruby, HTML and CSS at war.","archived":false,"fork":false,"pushed_at":"2024-03-14T14:17:43.000Z","size":78,"stargazers_count":42,"open_issues_count":5,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-08-15T13:55:08.254Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Ruby","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/opal.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2013-12-12T15:19:47.000Z","updated_at":"2024-06-12T06:49:31.000Z","dependencies_parsed_at":"2024-06-19T05:31:11.751Z","dependency_job_id":"3b6938ea-78a6-43cf-9996-c54b685eac54","html_url":"https://github.com/opal/paggio","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/opal/paggio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opal%2Fpaggio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opal%2Fpaggio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opal%2Fpaggio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opal%2Fpaggio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/opal","download_url":"https://codeload.github.com/opal/paggio/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/opal%2Fpaggio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271754357,"owners_count":24815182,"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-08-23T02:00:09.327Z","response_time":69,"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-08-06T08:01:44.688Z","updated_at":"2025-08-23T15:16:55.225Z","avatar_url":"https://github.com/opal.png","language":"Ruby","readme":"paggio\n======\nA Ruby DSL to generate HTML and CSS.\n\nHTML\n----\nInspired by markaby with some specialized additions for certain kinds of\nelements.\n\n```ruby\nrequire 'paggio/now'\n\n# html! avoids outputting the doctype and \u003chtml\u003e tags\nhtml! do\n  div.content! do\n    p \u003c\u003c-EOS\n      I like trains\n    EOS\n  end\nend\n```\n\nThis will output:\n\n```html\n\u003cdiv id=\"content\"\u003e\n  \u003cp\u003e\n    I like trains.\n  \u003c/p\u003e\n\u003c/div\u003e\n```\n\nCSS\n---\nInspired by SCSS with some nice CSS unit handling monkey-patching.\n\n```ruby\nrequire 'paggio/now'\n\ncss do\n  rule '.content' do\n    background :black\n    color :white\n\n    rule '\u0026:hover' do\n      background :white\n      color :black\n    end\n\n    rule '.stuff' do\n      font size: 50.px\n    end\n  end\nend\n```\n\nThis will output:\n```css\n.content {\n        background: black;\n        color: white;\n}\n\n.content .stuff {\n        font-size: 50px;\n}\n\n.content:hover {\n        background: white;\n        color: black;\n}\n```\n\nWith Sinatra\n------------\nBecause why not.\n\n```ruby\nrequire 'sinatra'\nrequire 'paggio'\n\nget '/' do\n  Paggio.html do\n    head do\n      title \"Yo, I'm on Sinatra\"\n\n      style do\n        rule 'html', 'body' do\n          width  100.%\n          height 100.%\n\n          # reset some stuff\n          margin  0\n          padding 0\n          position :absolute\n          top 0\n\n          background :black\n          color :white\n        end\n\n        rule '#content' do\n          width 50.%\n          height 100.%\n\n          margin 0, :auto\n\n          border left:  [3.px, :solid, :white],\n                 right: [3.px, :solid, :white]\n\n          text align: :center\n          font size: 23.px\n\n          rule '\u0026 \u003e div' do\n            padding 20.px\n          end\n        end\n      end\n    end\n\n    body do\n      div.content! do\n        div 'Hello world!'\n      end\n    end\n  end\nend\n```\n\nWith Markdown\n-------------\nYou'll need the `kramdown` gem.\n\n```ruby\nrequire 'paggio/now'\nrequire 'paggio/markdown'\n\nhtml do\n  markdown \u003c\u003c-MD\n    Here comes a bunch of **shitty** markdown.\n  MD\nend\n```\n\nSince *paggio* does internal heredoc indentation pruning, you don't have to\nworry about that.\n\nWith Opal\n---------\nYou'll need the `--pre sourcify` gem and the `opal` gem.\n\n```ruby\nrequire 'paggio/now'\nrequire 'paggio/script'\n\nhtml do\n  head do\n    script src: 'js/opal.js'\n    script src: 'js/browser.js'\n\n    script do\n      alert 'Yo dawg'\n    end\n  end\nend\n```\n\nCalling local methods inside the DSLs\n-------------------------------------\nDon't you just love `instance_eval`? Well, I do, but sometimes it's not the\nbest tool for the job, in fact you cannot call local methods or access instance\nvariables inside the DSLs since they're evaluated in another context.\n\nWell, fear not, doing that is as easy as adding a parameter to the DSL block.\n\n```ruby\nclass Page\n  def initialize(title, content)\n    @title   = title\n    @content = content\n  end\n\n  def to_html\n    Paggio.html do |_|\n      _.html do\n        _.head do\n          title @title\n        end\n\n        _.body do\n          @content\n        end\n      end\n    end\n  end\nend\n\nputs Page.new(\"foo\", \"bar\").to_html\n```\n\nWhy?\n----\nBecause HAML, SCSS and CoffeeScript are too mainstream.\n\nOn a serious note, why have templating systems and syntax sugar when you can\njust write Ruby?\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopal%2Fpaggio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopal%2Fpaggio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopal%2Fpaggio/lists"}