{"id":13558323,"url":"https://github.com/cloudhead/toto","last_synced_at":"2025-05-14T22:08:01.177Z","repository":{"id":705098,"uuid":"351406","full_name":"cloudhead/toto","owner":"cloudhead","description":"the 10 second blog-engine for hackers","archived":false,"fork":false,"pushed_at":"2015-11-08T23:17:44.000Z","size":589,"stargazers_count":1491,"open_issues_count":61,"forks_count":243,"subscribers_count":31,"default_branch":"master","last_synced_at":"2025-04-13T18:44:37.814Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/cloudhead.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}},"created_at":"2009-10-27T14:24:27.000Z","updated_at":"2025-03-23T17:40:21.000Z","dependencies_parsed_at":"2022-07-05T09:44:06.979Z","dependency_job_id":null,"html_url":"https://github.com/cloudhead/toto","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudhead%2Ftoto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudhead%2Ftoto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudhead%2Ftoto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudhead%2Ftoto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudhead","download_url":"https://codeload.github.com/cloudhead/toto/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254235696,"owners_count":22036963,"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-08-01T12:04:52.764Z","updated_at":"2025-05-14T22:07:56.161Z","avatar_url":"https://github.com/cloudhead.png","language":"Ruby","funding_links":[],"categories":["Ruby","Happy Exploring 🤘","Git Powered Blogs/Sites","others"],"sub_categories":[],"readme":"toto\n====\n\nthe tiniest blogging engine in Oz!\n\nintroduction\n------------\n\ntoto is a git-powered, minimalist blog engine for the hackers of Oz. The engine weighs around ~300 sloc at its worse.\nThere is no toto client, at least for now; everything goes through git.\n\nblog in 10 seconds\n------------------\n\n    $ git clone git://github.com/cloudhead/dorothy.git myblog\n    $ cd myblog\n    $ heroku create myblog\n    $ git push heroku master\n\nphilosophy\n----------\n\nEverything that can be done better with another tool should be, but one should not have too much pie to stay fit.\nIn other words, toto does away with web frameworks or DSLs such as sinatra, and is built right on top of **rack**.\nThere is no database or ORM either, we use plain text files.\n\nToto was designed to be used with a reverse-proxy cache, such as [Varnish](http://varnish-cache.org).\nThis makes it an ideal candidate for [heroku](http://heroku.com).\n\nOh, and everything that can be done with git, _is_.\n\nhow it works\n------------\n\n- content is entirely managed through **git**; you get full fledged version control for free.\n- articles are stored as _.txt_ files, with embedded metadata (in yaml format).\n- articles are processed through a markdown converter (rdiscount) by default.\n- templating is done through **ERB**.\n- toto is built right on top of **Rack**.\n- toto was built to take advantage of _HTTP caching_.\n- toto was built with heroku in mind.\n- comments are handled by [disqus](http://disqus.com)\n- individual articles can be accessed through urls such as _/2009/11/21/blogging-with-toto_\n- the archives can be accessed by year, month or day, with the same format as above.\n- arbitrary metadata can be included in articles files, and accessed from the templates.\n- summaries are generated intelligently by toto, following the `:max` setting you give it.\n- you can also define how long your summary is, by adding `~` at the end of it (`:delim`).\n\ndorothy\n-------\n\nDorothy is toto's default template, you can get it at \u003chttp://github.com/cloudhead/dorothy\u003e. It\ncomes with a very minimalistic but functional template, and a _config.ru_ file to get you started.\nIt also includes a _.gems_ file, for heroku.\n\nsynopsis\n--------\n\nOne would start by installing _toto_, with `sudo gem install toto`, and then forking or\ncloning the `dorothy` repo, to get a basic skeleton:\n\n    $ git clone git://github.com/cloudhead/dorothy.git weblog\n    $ cd weblog/\n\nOne would then edit the template at will, it has the following structure:\n\n    templates/\n    |\n    +- layout.rhtml      # the main site layout, shared by all pages\n    |\n    +- index.builder     # the builder template for the atom feed\n    |\n    +- pages/            # pages, such as home, about, etc go here\n       |\n       +- index.rhtml    # the default page loaded from `/`, it displays the list of articles\n       |\n       +- article.rhtml  # the article (post) partial and page\n       |\n       +- about.rhtml\n\nOne could then create a .txt article file in the `articles/` folder, and make sure it has the following format:\n\n    title: The Wonderful Wizard of Oz\n    author: Lyman Frank Baum\n    date: 1900/05/17\n\n    Dorothy lived in the midst of the great Kansas prairies, with Uncle Henry,\n    who was a farmer, and Aunt Em, who was the farmer's wife.\n\nIf one is familiar with webby or aerial, this shouldn't look funny. Basically the top of the file is in YAML format,\nand the rest of it is the blog post. They are delimited by an empty line `/\\n\\n/`, as you can see above.\nNone of the information is compulsory, but it's strongly encouraged you specify it.\nNote that one can also use `rake` to create an article stub, with `rake new`.\n\nOnce he finishes writing his beautiful tale, one can push to the git repo, as usual:\n\n    $ git add articles/wizard-of-oz.txt\n    $ git commit -m 'wrote the wizard of oz.'\n    $ git push remote master\n\nWhere `remote` is the name of your remote git repository. The article is now published.\n\n### deployment\n\nToto is built on top of **Rack**, and hence has a **rackup** file: _config.ru_.\n\n#### on your own server\n\nOnce you have created the remote git repo, and pushed your changes to it, you can run toto with any Rack compliant web server,\nsuch as **thin**, **mongrel** or **unicorn**.\n\nWith thin, you would do something like:\n\n    $ thin start -R config.ru\n\nWith unicorn, you can just do:\n\n    $ unicorn\n\n#### on heroku\n\nToto was designed to work well with [heroku](http://heroku.com), it makes the most out of it's state-of-the-art caching,\nby setting the _Cache-Control_ and _Etag_ HTTP headers. Deploying on Heroku is really easy, just get the heroku gem,\ncreate a heroku app with `heroku create`, and push with `git push heroku master`.\n\n    $ heroku create weblog\n    $ git push heroku master\n    $ heroku open\n\n### configuration\n\nYou can configure toto, by modifying the _config.ru_ file. For example, if you want to set the blog author to 'John Galt',\nyou could add `set :author, 'John Galt'` inside the `Toto::Server.new` block. Here are the defaults, to get you started:\n\n    set :author,      ENV['USER']                               # blog author\n    set :title,       Dir.pwd.split('/').last                   # site title\n    set :url,         'http://example.com'                      # site root URL\n    set :prefix,      ''                                        # common path prefix for all pages\n    set :root,        \"index\"                                   # page to load on /\n    set :date,        lambda {|now| now.strftime(\"%d/%m/%Y\") }  # date format for articles\n    set :markdown,    :smart                                    # use markdown + smart-mode\n    set :disqus,      false                                     # disqus id, or false\n    set :summary,     :max =\u003e 150, :delim =\u003e /~\\n/              # length of article summary and delimiter\n    set :ext,         'txt'                                     # file extension for articles\n    set :cache,       28800                                     # cache site for 8 hours\n\n    set :to_html   do |path, page, ctx|                         # returns an html, from a path \u0026 context\n      ERB.new(File.read(\"#{path}/#{page}.rhtml\")).result(ctx)\n    end\n\n    set :error     do |code|                                    # The HTML for your error page\n      \"\u003cfont style='font-size:300%'\u003etoto, we're not in Kansas anymore (#{code})\u003c/font\u003e\"\n    end\n\nthanks\n------\n\nTo heroku for making this easy as pie.\nTo adam wiggins, as I stole a couple of ideas from Scanty.\nTo the developers of Rack, for making such an awesome platform.\n\nCopyright (c) 2009-2010 cloudhead. See LICENSE for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudhead%2Ftoto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudhead%2Ftoto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudhead%2Ftoto/lists"}