{"id":19961589,"url":"https://github.com/mxrnx/woah","last_synced_at":"2025-07-10T06:39:38.110Z","repository":{"id":32630439,"uuid":"138419694","full_name":"mxrnx/woah","owner":"mxrnx","description":"Unobtrusive web framework","archived":false,"fork":false,"pushed_at":"2024-02-28T23:24:06.000Z","size":70,"stargazers_count":9,"open_issues_count":2,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-03-15T14:42:49.987Z","etag":null,"topics":["framework","gem","rack","ruby","ruby-gem","web","web-framework"],"latest_commit_sha":null,"homepage":null,"language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mxrnx.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":"2018-06-23T17:11:29.000Z","updated_at":"2021-11-12T15:45:40.000Z","dependencies_parsed_at":"2023-02-10T17:00:18.570Z","dependency_job_id":null,"html_url":"https://github.com/mxrnx/woah","commit_stats":null,"previous_names":["knarka/woah"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxrnx%2Fwoah","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxrnx%2Fwoah/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxrnx%2Fwoah/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mxrnx%2Fwoah/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mxrnx","download_url":"https://codeload.github.com/mxrnx/woah/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224374752,"owners_count":17300691,"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":["framework","gem","rack","ruby","ruby-gem","web","web-framework"],"created_at":"2024-11-13T02:07:52.221Z","updated_at":"2024-11-13T02:07:52.827Z","avatar_url":"https://github.com/mxrnx.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Woah!\n[![Build Status](https://travis-ci.org/knarka/woah.svg?branch=master)](https://travis-ci.org/knarka/woah)\n[![Coverage Status](https://coveralls.io/repos/github/knarka/woah/badge.svg?branch=master\u0026service=github)](https://coveralls.io/github/knarka/woah?branch=master)\n[![Code Climate](https://codeclimate.com/github/knarka/woah/badges/gpa.svg)](https://codeclimate.com/github/knarka/woah)\n[![Gem Version](https://badge.fury.io/rb/woah.svg)](https://badge.fury.io/rb/woah)\n\nWoah! is an unobtrusive, (extremely) minimal web framework built on Rack.\n\n## Installation\n`gem install woah`\n\n## What do I do with it???\nYou're gonna want to extend Woah::Base, which will be your app's, er, base.\n\n```ruby\nrequire 'woah'\n\nclass MyApp \u003c Woah::Base\nend\n\nMyApp.run!\n```\n\nYou now have an app that serves 404 errors on every route. Not very useful, so let's extend that.\n\nBy the way, the lines `require 'woah'` and `MyApp.run!` will always be necessary, but to keep this file a little neater, they'll be omitted in the next examples. Just pretend they're there.\n\n```ruby\nclass MyApp \u003c Woah::Base\n\ton '/hello' do\n\t\t\"hey, what's up\"\n\tend\nend\n```\n\nWhen someone stumbles upon `/hello` now, they'll be greeted properly. Nice. These blocks of code are called **routes**. There's more types of blocks than just routes though. Check this out:\n\n```ruby\nclass MyApp \u003c Woah::Base\n\tbefore do\n\t\t@@num ||= 1\n\tend\n\n\ton '/' do\n\t\t\"this is the root of this app, and page hit nr. #{@@num}\"\n\tend\n\n\ton '/hello' do\n\t\t\"hey, what's up. this is page hit nr. #{@@num}\"\n\tend\n\n\tafter do\n\t\t@@num += 1\n\tend\nend\n```\n\nThere's two new blocks here: `before` and `after`. They do things before and after the relevant route gets executed. This example will increment a counter everytime a page is hit, regardless of what page it is.\n\nOf course, getting pages isn't everything you can do on the Internet. There's other HTTP verbs as well, like POST. Behold:\n\n```ruby\nclass MyApp \u003c Woah::Base\n\tbefore do\n\t\t@@content ||=\n\t\t'\u003cform action=\"/\" method=\"post\"\u003e'\\\n\t\t\t'\u003cinput type=\"submit\" value=\"click me please\" /\u003e'\\\n\t\t'\u003c/form\u003e'\n\tend\n\n\ton '/' do\n\t\t@@content\n\tend\n\n\ton '/', 'POST' do\n\t\t@@content = 'thanks for clicking!'\n\tend\nend\n```\n\nAs soon as you click the button on `/`, the message on the page will transform.\n\nOf course, sometimes you want routes to be flexible, and to catch more than one expression. For this, you can use regular expressions instead of strings as your routes, just like this:\n\n```ruby\nclass MyApp \u003c Woah::Base\n\ton %r{^/greet/(\\w+)$} do\n\t\t\"oh, hello, I didn't see you there #{match[1]}\"\n\tend\nend\n```\n\nNow, visiting `/greet/Socrates` will greet you with your own name (assuming your name is Socrates). Wonderful. By the way, you may have noticed the regex here is delimited by `%r{}`, instead of the more common `//`. This is because of how common slashes are in routes, so it's recommended to use this syntax. You can use slashes to delimit your regex though, if you like. I won't judge you.\n\nRedirects are possible as well:\n\n```ruby\nclass MyApp \u003c Woah::Base\n\ton '/' do\n\t\tredirect_to '/landing'\n\tend\n\n\ton '/landing' do\n\t\t'welcome'\n\tend\nend\n```\n\nSo are cookies:\n\n```ruby\nclass MyApp \u003c Woah::Base\n\ton '/' do\n\t\tcookie 'chunky' || 'no cookie set'\n\tend\n\n\ton '/set' do\n\t\tcookie 'chunky', 'bacon'\n\tend\n\n\ton '/del' do\n\t\tcookie 'chunky', :delete\n\tend\nend\n```\n\nUpon first visiting, this page will tell you there's no cookie set. After visiting `/set` however, it'll display `bacon`, as that is now the content of the `chunky` cookie. Visiting `/del` will delete the cookie again.\n\nWe're nearing the end of this little guide already, I'm afraid. However, there's still one more trick you need to see. Look, sometimes, you might disagree with the things Woah! thinks up for you. That's why you can override everything Woah! is about to send, if you so please. Por exemplo:\n\n```ruby\nclass MyApp \u003c Woah::Base\n\ton '/' do\n\t\t'(insert super secret information)'\n\tend\n\n\ton %r{^/pass/(\\w+)$} do\n\t\t@password = match[1]\n\t\t'logged in! \u003ca href=\"/\"\u003eback to root\u003c/a\u003e'\n\tend\n\n\tafter do\n\t\tunless @password \u0026\u0026 @password == 'penguin'\n\t\t\tset :status, 403\n\t\t\tset :body, 'log in first!'\n\t\tend\n\tend\nend\n```\n\nThat's all. Have fun!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxrnx%2Fwoah","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmxrnx%2Fwoah","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmxrnx%2Fwoah/lists"}