{"id":13463253,"url":"https://github.com/mustache/mustache","last_synced_at":"2025-05-12T15:21:35.705Z","repository":{"id":672772,"uuid":"316198","full_name":"mustache/mustache","owner":"mustache","description":"Logic-less Ruby templates.","archived":false,"fork":false,"pushed_at":"2024-07-09T21:48:32.000Z","size":1179,"stargazers_count":3049,"open_issues_count":52,"forks_count":268,"subscribers_count":67,"default_branch":"master","last_synced_at":"2025-04-18T13:01:34.569Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://mustache.github.io/","language":"Ruby","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/mustache.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.md","contributing":"CONTRIBUTING.md","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":"2009-09-24T08:20:21.000Z","updated_at":"2025-04-17T11:50:04.000Z","dependencies_parsed_at":"2023-01-13T10:35:39.516Z","dependency_job_id":"f1f5fabb-1bfe-49db-ad4e-e40348998521","html_url":"https://github.com/mustache/mustache","commit_stats":{"total_commits":714,"total_committers":76,"mean_commits":9.394736842105264,"dds":"0.43557422969187676","last_synced_commit":"9fefaabd2b1e68ef8186a210af1f0e18ef48bb55"},"previous_names":["defunkt/mustache"],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mustache%2Fmustache","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mustache%2Fmustache/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mustache%2Fmustache/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mustache%2Fmustache/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mustache","download_url":"https://codeload.github.com/mustache/mustache/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250357683,"owners_count":21417327,"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":[],"created_at":"2024-07-31T13:00:49.025Z","updated_at":"2025-04-23T17:11:37.545Z","avatar_url":"https://github.com/mustache.png","language":"Ruby","readme":"# Mustache\n\n[![Gem Version](https://badge.fury.io/rb/mustache.svg)](http://badge.fury.io/rb/mustache)\n[![Build Status](https://travis-ci.org/mustache/mustache.svg?branch=master)](https://travis-ci.org/mustache/mustache)\n\nInspired by [ctemplate][1] and [et][2], Mustache is a\nframework-agnostic way to render logic-free views.\n\nAs ctemplates says, \"It emphasizes separating logic from presentation:\nit is impossible to embed application logic in this template language.\"\n\nFor a list of implementations (other than Ruby) and tips, see\n\u003chttp://mustache.github.io/\u003e.\n\n\n## Overview\n\nThink of Mustache as a replacement for your views. Instead of views\nconsisting of ERB or HAML with random helpers and arbitrary logic,\nyour views are broken into two parts: a Ruby class and an HTML\ntemplate.\n\nWe call the Ruby class the \"view\" and the HTML template the\n\"template.\"\n\nAll your logic, decisions, and code is contained in your view. All\nyour markup is contained in your template. The template does nothing\nbut reference methods in your view.\n\nThis strict separation makes it easier to write clean templates,\neasier to test your views, and more fun to work on your app's front end.\n\n\n## Why?\n\nI like writing Ruby. I like writing HTML. I like writing JavaScript.\n\nI don't like writing ERB, Haml, Liquid, Django Templates, putting Ruby\nin my HTML, or putting JavaScript in my HTML.\n\n\n## Installation\n\nInstall the gem locally with:\n\n    $ gem install mustache\n\nOr add it to your `Gemfile`:\n\n```ruby\ngem \"mustache\", \"~\u003e 1.0\"\n```\n\n\n## Usage\n\nQuick example:\n\n    \u003e\u003e require 'mustache'\n    =\u003e true\n    \u003e\u003e Mustache.render(\"Hello {{planet}}\", planet: \"World!\")\n    =\u003e \"Hello World!\"\n\nWe've got an `examples` folder but here's the canonical one:\n\n```ruby\nclass Simple \u003c Mustache\n  def name\n    \"Chris\"\n  end\n\n  def value\n    10_000\n  end\n\n  def taxed_value\n    value * 0.6\n  end\n\n  def in_ca\n    true\n  end\nend\n```\n\nWe simply create a normal Ruby class and define methods. Some methods\nreference others, some return values, some return only booleans.\n\nNow let's write the template:\n\n    Hello {{name}}\n    You have just won {{value}} dollars!\n    {{#in_ca}}\n    Well, {{taxed_value}} dollars, after taxes.\n    {{/in_ca}}\n\nThis template references our view methods. To bring it all together,\nhere's the code to render actual HTML;\n```ruby\nSimple.render\n```\nWhich returns the following:\n\n    Hello Chris\n    You have just won 10000 dollars!\n    Well, 6000.0 dollars, after taxes.\n\nSimple.\n\n\n## Tag Types\n\nFor a language-agnostic overview of Mustache's template syntax, see\nthe `mustache(5)` manpage or\n\u003chttp://mustache.github.io/mustache.5.html\u003e.\n\n\n## Escaping\n\nMustache does escape all values when using the standard double\nMustache syntax. Characters which will be escaped: `\u0026 \\ \" \u003c \u003e` (as\nwell as `'` in Ruby `\u003e= 2.0`). To disable escaping, simply use triple\nmustaches like `{{{unescaped_variable}}}`.\n\nExample: Using `{{variable}}` inside a template for `5 \u003e 2` will\nresult in `5 \u0026gt; 2`, where as the usage of `{{{variable}}}` will\nresult in `5 \u003e 2`.\n\n\n## Dict-Style Views\n\nctemplate and friends want you to hand a dictionary to the template\nprocessor. Mustache supports a similar concept. Feel free to mix the\nclass-based and this more procedural style at your leisure.\n\nGiven this template (winner.mustache):\n\n    Hello {{name}}\n    You have just won {{value}} bucks!\n\nWe can fill in the values at will:\n\n```ruby\nview = Winner.new\nview[:name] = 'George'\nview[:value] = 100\nview.render\n```\nWhich returns:\n\n    Hello George\n    You have just won 100 bucks!\n\nWe can re-use the same object, too:\n\n```ruby\nview[:name] = 'Tony'\nview.render # =\u003e Hello Tony\\nYou have just won 100 bucks!\n```\n\n## Templates\n\nA word on templates. By default, a view will try to find its template\non disk by searching for an HTML file in the current directory that\nfollows the classic Ruby naming convention.\n\n    TemplatePartial =\u003e ./template_partial.mustache\n\nYou can set the search path using `Mustache.template_path`. It can be set on a\nclass by class basis:\n\n```ruby\nclass Simple \u003c Mustache\n  self.template_path = __dir__\nend\n```\nNow `Simple` will look for `simple.mustache` in the directory it resides\nin, no matter the cwd.\n\nIf you want to just change what template is used you can set\n`Mustache.template_file` directly:\n\n```ruby\nSimple.template_file = './blah.mustache'\n```\nMustache also allows you to define the extension it'll use.\n\n```ruby\nSimple.template_extension = 'xml'\n```\nGiven all other defaults, the above line will cause Mustache to look\nfor './blah.xml'\n\nFeel free to set the template directly:\n\n```ruby\nSimple.template = 'Hi {{person}}!'\n```\n\nOr set a different template for a single instance:\n```ruby\nSimple.new.template = 'Hi {{person}}!'\n```\n\nWhatever works.\n\n\n## Views\n\nMustache supports a bit of magic when it comes to views. If you're\nauthoring a plugin or extension for a web framework (Sinatra, Rails,\netc), check out the `view_namespace` and `view_path` settings on the\n`Mustache` class. They will surely provide needed assistance.\n\n\n## Helpers\n\nWhat about global helpers? Maybe you have a nifty `gravatar` function\nyou want to use in all your views? No problem.\n\nThis is just Ruby, after all.\n\n```ruby\nmodule ViewHelpers\n  def gravatar\n    gravatar_id = Digest::MD5.hexdigest(self[:email].to_s.strip.downcase)\n    gravatar_for_id(gravatar_id)\n  end\n\n  def gravatar_for_id(gid, size = 30)\n    \"#{gravatar_host}/avatar/#{gid}?s=#{size}\"\n  end\n\n  def gravatar_host\n    @ssl ? 'https://secure.gravatar.com' : 'http://www.gravatar.com'\n  end\nend\n```\n\nThen just include it:\n\n```ruby\nclass Simple \u003c Mustache\n  include ViewHelpers\n\n  def name\n    \"Chris\"\n  end\n\n  def value\n    10_000\n  end\n\n  def taxed_value\n    value * 0.6\n  end\n\n  def in_ca\n    true\n  end\n\n  def users\n    User.all\n  end\nend\n```\n\nGreat, but what about that `@ssl` ivar in `gravatar_host`? There are\nmany ways we can go about setting it.\n\nHere's an example which illustrates a key feature of Mustache: you\nare free to use the `initialize` method just as you would in any\nnormal class.\n\n```ruby\nclass Simple \u003c Mustache\n  include ViewHelpers\n\n  def initialize(ssl = false)\n    @ssl = ssl\n  end\nend\n```\n\nNow:\n\n```ruby\nSimple.new(request.ssl?).render\n```\n\nFinally, our template might look like this:\n\n    \u003cul\u003e\n      {{# users}}\n        \u003cli\u003e\u003cimg src=\"{{ gravatar }}\"\u003e {{ login }}\u003c/li\u003e\n      {{/ users}}\n    \u003c/ul\u003e\n\n\n## Integrations\n\n### Sinatra\n\nSinatra integration is available with the\n[mustache-sinatra gem](https://github.com/mustache/mustache-sinatra).\n\nAn example Sinatra application is also provided:\n\u003chttps://github.com/defunkt/mustache-sinatra-example\u003e\n\nIf you are upgrading to Sinatra 1.0 and Mustache 0.9.0+ from Mustache\n0.7.0 or lower, the settings have changed. But not that much.\n\nSee [this diff][diff] for what you need to\ndo. Basically, things are named properly now and all should be\ncontained in a hash set using `set :mustache, hash`.\n\n\n### [Rack::Bug][4]\n\nMustache also provides a `Rack::Bug` panel.\nFirst you have to install the `rack-bug-mustache_panel` gem, then in your `config.ru` add  the following code:\n\n```ruby\nrequire 'rack/bug/panels/mustache_panel'\nuse Rack::Bug::MustachePanel\n```\n\nUsing Rails? Add this to your initializer or environment file:\n\n```ruby\nrequire 'rack/bug/panels/mustache_panel'\nconfig.middleware.use \"Rack::Bug::MustachePanel\"\n```\n\n![Rack::Bug][5]\n\n\n### Vim\n\nvim-mustache-handlebars is available at [mustache/vim-mustache-handlebars][vim]\n\n### Emacs\n\nmustache-mode.el is available at [mustache/emacs][emacs]\n\n\n### TextMate\n\n[Mustache.tmbundle][tmbundle]\n\nSee \u003chttps://gist.github.com/defunkt/323624\u003e for installation instructions.\n\n\n### Command Line\n\nSee `mustache(1)` man page or \u003chttp://mustache.github.io/mustache.1.html\u003e\nfor command line docs.\n\n\n## Acknowledgements\n\nThanks to [Tom Preston-Werner](https://github.com/mojombo) for showing\nme ctemplate and [Leah Culver](https://github.com/leah) for the name \"Mustache.\"\n\nSpecial thanks to [Magnus Holm](http://judofyr.net/) for all his\nawesome work on Mustache's parser.\n\n\n## Contributing\n\nOnce you've made your great commits:\n\n1. [Fork][fk] Mustache\n2. Create a topic branch - `git checkout -b my_branch`\n3. Push to your branch - `git push origin my_branch`\n4. Create an [Issue][is] with a link to your branch\n5. That's it!\n\n\n## Mailing List\n\n~~To join the list simply send an email to \u003cmustache@librelist.com\u003e. This\nwill subscribe you and send you information about your subscription,\nincluding unsubscribe information.\n\nThe archive can be found at \u003chttp://librelist.com/browser/mustache/\u003e.~~\n\nThe mailing list hasn't been updated in quite a while, please join us on Gitter\nor IRC:\n\n[![Join the chat at https://gitter.im/mustache/mustache](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/mustache/mustache?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge)\n\n[#{ on Freenode][irc]\n\n## Meta\n\n* Code: `git clone https://github.com/mustache/mustache.git`\n* Home: \u003chttp://mustache.github.io\u003e\n* Bugs: \u003chttps://github.com/mustache/mustache/issues\u003e\n* List: \u003cmustache@librelist.com\u003e\n* Gems: \u003chttps://rubygems.org/gems/mustache\u003e\n\n[1]: https://github.com/olafvdspek/ctemplate\n[2]: http://www.ivan.fomichev.name/2008/05/erlang-template-engine-prototype.html\n[3]: http://google-ctemplate.googlecode.com/svn/trunk/doc/howto.html\n[4]: https://github.com/brynary/rack-bug/\n[5]: http://img.skitch.com/20091027-n8pxwwx8r61tc318a15q1n6m14.png\n[fk]: https://help.github.com/forking/\n[is]: https://github.com/mustache/mustache/issues\n[irc]: irc://irc.freenode.net/#{\n[vim]: https://github.com/mustache/vim-mustache-handlebars\n[emacs]: https://github.com/mustache/emacs\n[tmbundle]: https://github.com/defunkt/Mustache.tmbundle\n[diff]: https://gist.github.com/defunkt/345490\n","funding_links":[],"categories":["HTML \u0026 Markup","Ruby","Tool","Template Engine"],"sub_categories":["Template Engines","Miscs"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmustache%2Fmustache","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmustache%2Fmustache","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmustache%2Fmustache/lists"}