Skip to content
Permalink
Browse files

Merge branch 'build' into announcing-v080

  • Loading branch information...
jodosha committed Jul 20, 2016
2 parents fb680fd + 0bb4469 commit fe27b7945025abab27c058727d4b1d1b2df31f48
Showing with 4,291 additions and 462 deletions.
  1. +45 −3 config.rb
  2. +103 −0 data/guides.yml
  3. +23 −0 lib/github_style_titles.rb
  4. +2 −1 source/_footer.erb
  5. +13 −0 source/_head.erb
  6. +34 −0 source/_navbar.erb
  7. +1 −1 source/blog.html.erb
  8. +21 −0 source/blog/2016-02-09-announcing-hanami-072.html.markdown
  9. BIN source/blog/2016-02-09-announcing-hanami-072/cover.jpg
  10. +85 −0 source/blog/2016-05-16-validations-predicates.html.markdown
  11. BIN source/blog/2016-05-16-validations-predicates/cover.jpg
  12. +21 −0 source/blog/2016-05-23-announcing-hanami-073.html.markdown
  13. BIN source/blog/2016-05-23-announcing-hanami-073/cover.jpg
  14. +7 −1 source/community.html.erb
  15. +20 −0 source/donate.html.erb
  16. +1 −1 source/guides/actions/basic-usage.md
  17. +2 −2 source/guides/actions/control-flow.md
  18. +1 −1 source/guides/actions/cookies.md
  19. +1 −1 source/guides/actions/exception-handling.md
  20. +1 −1 source/guides/actions/exposures.md
  21. +1 −1 source/guides/actions/http-caching.md
  22. +1 −1 source/guides/actions/mime-types.md
  23. +8 −1 source/guides/actions/overview.md
  24. +1 −1 source/guides/actions/parameters.md
  25. +1 −1 source/guides/actions/rack-integration.md
  26. +1 −1 source/guides/actions/request-and-response.md
  27. +1 −1 source/guides/actions/sessions.md
  28. +1 −1 source/guides/actions/share-code.md
  29. +1 −1 source/guides/actions/testing.md
  30. +1 −1 source/guides/applications/initializers.md
  31. +7 −7 source/guides/applications/rake.md
  32. +1 −1 source/guides/architectures/application.md
  33. +2 −2 source/guides/architectures/container.md
  34. +1 −1 source/guides/architectures/overview.md
  35. +1 −1 source/guides/assets/compressors.md
  36. +1 −1 source/guides/assets/content-delivery-network.md
  37. +1 −1 source/guides/assets/overview.md
  38. +1 −1 source/guides/assets/preprocessors.md
  39. +1 −1 source/guides/command-line/applications.md
  40. +1 −1 source/guides/command-line/assets.md
  41. +1 −1 source/guides/command-line/database.md
  42. +1 −1 source/guides/command-line/destroy.md
  43. +1 −1 source/guides/command-line/generators.md
  44. +1 −1 source/guides/command-line/routes.md
  45. +1 −1 source/guides/command-line/version.md.erb
  46. +16 −13 source/guides/getting-started.md
  47. +1 −1 source/guides/helpers/assets.md
  48. +1 −1 source/guides/helpers/custom-helpers.md
  49. +1 −1 source/guides/helpers/escape.md
  50. +25 −25 source/guides/helpers/forms.md
  51. +1 −1 source/guides/helpers/html5.md
  52. +1 −1 source/guides/helpers/links.md
  53. +1 −1 source/guides/helpers/numbers.md
  54. +1 −1 source/guides/helpers/overview.md
  55. +1 −1 source/guides/helpers/routing.md
  56. +1 −1 source/guides/index.md
  57. +1 −1 source/guides/mailers/basic-usage.md
  58. +3 −4 source/guides/mailers/delivery.md
  59. +1 −1 source/guides/mailers/overview.md
  60. +1 −1 source/guides/mailers/share-code.md
  61. +2 −2 source/guides/mailers/templates.md
  62. +1 −1 source/guides/mailers/testing.md
  63. +1 −1 source/guides/migrations/alter-table.md
  64. +1 −1 source/guides/migrations/create-table.md
  65. +3 −1 source/guides/migrations/overview.md
  66. +1 −1 source/guides/models/entities.md
  67. +4 −3 source/guides/models/overview.md
  68. +1 −1 source/guides/models/repositories.md
  69. +2 −2 source/guides/routing/basic-usage.md
  70. +1 −1 source/guides/routing/overview.md
  71. +5 −5 source/guides/routing/restful-resources.md
  72. +1 −1 source/guides/upgrade-notes/v060.md
  73. +1 −1 source/guides/upgrade-notes/v070.md
  74. +2 −2 source/guides/views/basic-usage.md
  75. +1 −1 source/guides/views/custom-error-pages.md
  76. +1 −1 source/guides/views/layouts.md
  77. +1 −1 source/guides/views/mime-types.md
  78. +1 −1 source/guides/views/overview.md
  79. +1 −1 source/guides/views/share-code.md
  80. +1 −1 source/guides/views/templates.md
  81. +2 −2 source/guides/views/testing.md
  82. +1 −1 source/hackday.html.erb
  83. BIN source/images/logo.png
  84. +1 −1 source/index.html.erb
  85. +2 −44 source/layouts/blog.erb
  86. +18 −185 source/layouts/guides.erb
  87. +7 −49 source/layouts/home.erb
  88. +2 −43 source/layouts/layout.erb
  89. +1 −1 source/mailing-list.html.erb
  90. BIN source/ml/0008/images/header.jpg
  91. BIN source/ml/0008/images/img48.png
  92. BIN source/ml/0008/images/img50.png
  93. BIN source/ml/0008/images/img52.png
  94. BIN source/ml/0008/images/img53.jpg
  95. BIN source/ml/0008/images/img54.png
  96. BIN source/ml/0008/images/railsconf.jpg
  97. BIN source/ml/0008/images/to-hanami-1.jpg
  98. BIN source/ml/0008/images/to-hanami-3.jpg
  99. BIN source/ml/0008/images/what-i-learned.jpg
  100. +1,707 −0 source/ml/0008/index.html
  101. BIN source/ml/0009/images/brighton-ruby.jpg
  102. BIN source/ml/0009/images/donations.jpg
  103. BIN source/ml/0009/images/hanami-emails.jpg
  104. BIN source/ml/0009/images/hanami-oauth.jpg
  105. BIN source/ml/0009/images/hanami-user-group.jpg
  106. BIN source/ml/0009/images/header.jpg
  107. BIN source/ml/0009/images/img48.png
  108. BIN source/ml/0009/images/img50.png
  109. BIN source/ml/0009/images/img52.png
  110. BIN source/ml/0009/images/img54.png
  111. BIN source/ml/0009/images/railsconf.jpg
  112. +1,796 −0 source/ml/0009/index.html
  113. +197 −0 source/status.html.erb
  114. +33 −1 source/stylesheets/application-minimal.css
  115. +15 −7 source/stylesheets/guides.css
  116. +1 −1 source/stylesheets/toolkit-minimal.css
@@ -2,8 +2,10 @@

Bundler.require(:default, ENV['SITE_ENV']) if defined?(Bundler)

require 'ostruct'
require 'rack/utils'
require 'middleman-syntax'
require 'lib/github_style_titles'
require File.expand_path('../extensions/build_cleaner.rb', __FILE__)

###
@@ -112,6 +114,46 @@ def article_image_url(article)
GUIDES_ROOT = 'source/guides'.freeze
GUIDES_EDIT_URL = 'https://github.com/hanami/hanami.github.io/edit/build/'.freeze

def guide_title(item)
item.title || item.path.split('-').map(&:capitalize).join(' ')
end

def guide_url(category, page)
File.join('/guides', category.path, page.path)
end

def guide_pager(current_page, guides)
current_url = current_page.url.tr('/', '')
flat_guides = guides.categories.flat_map { |category|
category.pages.map { |page|
OpenStruct.new(
category: category,
page: page,
)
}
}
current_guide_index = flat_guides.index { |guide_page|
guide_url(guide_page.category, guide_page.page).tr('/', '') == current_url
}
if current_guide_index
links = []
prev_guide = flat_guides[current_guide_index - 1]
if 0 < current_guide_index && prev_guide
prev_url = guide_url(prev_guide.category, prev_guide.page)
prev_title = "#{guide_title(prev_guide.category)} - #{guide_title(prev_guide.page)}"
links << %(<div class="pull-left">Prev: <a href="#{prev_url}">#{prev_title}</a></div>)
end

next_guide = flat_guides[current_guide_index + 1]
if next_guide
next_url = guide_url(next_guide.category, next_guide.page)
next_title = "#{guide_title(next_guide.category)} - #{guide_title(next_guide.page)}"
links << %(<div class="pull-right">Next: <a href="#{next_url}">#{next_title}</a></div>)
end
links.join
end
end

def guides_navigation
result = ''

@@ -148,7 +190,7 @@ def guides_section_articles(section)

def guides_edit_article(source)
url = GUIDES_EDIT_URL + source.gsub("#{ Dir.pwd }/", '')
%(<span class="icon icon-pencil" id="edit-guides-article" title="Edit this article"><a href="#{ url }" target="_blank"></a></span>)
%(<a href="#{ url }" target="_blank"><span class="icon icon-pencil" id="edit-guides-article" title="Edit this article"></span></a>)
end

#
@@ -170,7 +212,7 @@ def encode_text(text)
end

def hanami_version
'0.7.1'
'0.7.3'
end
end

@@ -179,7 +221,7 @@ def hanami_version
set :images_dir, 'images'

set :markdown_engine, :redcarpet
set :markdown, fenced_code_blocks: true, smartypants: true
set :markdown, fenced_code_blocks: true, smartypants: true, renderer: GithubStyleTitles

# Build-specific configuration
configure :build do
@@ -0,0 +1,103 @@
categories:
- path: /
title: Introduction
pages:
- path: getting-started
- path: architectures
pages:
- path: overview
- path: container
- path: application
- path: applications
pages:
- path: initializers
- path: rake
- path: routing
pages:
- path: overview
- path: basic-usage
- path: restful-resources
title: RESTful Resource(s)
- path: actions
pages:
- path: overview
- path: basic-usage
- path: parameters
- path: request-and-response
title: Request & Response
- path: exposures
- path: rack-integration
- path: mime-types
title: MIME Types
- path: cookies
- path: sessions
- path: exception-handling
- path: control-flow
- path: http-caching
title: HTTP Caching
- path: share-code
- path: testing
- path: views
pages:
- path: overview
- path: basic-usage
- path: templates
- path: mime-types
title: MIME Types
- path: layouts
- path: custom-error-pages
- path: share-code
- path: testing
- path: models
pages:
- path: overview
- path: entities
- path: repositories
- path: migrations
pages:
- path: overview
- path: create-table
- path: alter-table
- path: helpers
pages:
- path: overview
- path: html5
title: HTML5
- path: forms
- path: routing
- path: assets
- path: links
- path: escape
title: Markup Escape
- path: numbers
- path: custom-helpers
- path: mailers
pages:
- path: overview
- path: basic-usage
- path: templates
- path: delivery
- path: share-code
- path: testing
- path: assets
pages:
- path: overview
- path: preprocessors
- path: compressors
- path: content-delivery-network
title: Content Delivery Network (CDN)
- path: command-line
pages:
- path: applications
- path: generators
- path: destroy
- path: database
- path: assets
- path: routes
- path: version
- path: upgrade-notes
pages:
- path: v060
title: v0.6.0
- path: v070
title: v0.7.0
@@ -0,0 +1,23 @@
require 'middleman-core/renderers/redcarpet'

class GithubStyleTitles < Middleman::Renderers::MiddlemanRedcarpetHTML
def header(title, level)
@headers ||= []
permalink = title.gsub(/\W+/, '-').downcase
@headers << permalink

%(
<h#{level} id=\"#{permalink}\" class="title"><a name="#{permalink}" class="anchor" href="##{permalink}">#{anchor_svg}</a>#{title}</h#{level}>
)
end

private

def anchor_svg
<<-eos
<svg aria-hidden="true" class="octicon octicon-link" height="16" version="1.1" viewBox="0 0 16 16" width="16">
<path d="M4 9h1v1h-1c-1.5 0-3-1.69-3-3.5s1.55-3.5 3-3.5h4c1.45 0 3 1.69 3 3.5 0 1.41-0.91 2.72-2 3.25v-1.16c0.58-0.45 1-1.27 1-2.09 0-1.28-1.02-2.5-2-2.5H4c-0.98 0-2 1.22-2 2.5s1 2.5 2 2.5z m9-3h-1v1h1c1 0 2 1.22 2 2.5s-1.02 2.5-2 2.5H9c-0.98 0-2-1.22-2-2.5 0-0.83 0.42-1.64 1-2.09v-1.16c-1.09 0.53-2 1.84-2 3.25 0 1.81 1.55 3.5 3 3.5h4c1.45 0 3-1.69 3-3.5s-1.5-3.5-3-3.5z"></path>
</svg>
eos
end
end
@@ -9,6 +9,7 @@
<li><a href="https://github.com/hanami" target="_blank">GitHub</a></li>
<li><a href="https://twitter.com/hanamirb" target="_blank">Twitter</a></li>
<li><a href="https://rubygems.org/gems/hanami" target="_blank">Rubygems</a></li>
<li><a href="/status" target="_blank">Gems Status</a></li>
</ul>
</div>
<div class="col-sm-2 m-b">
@@ -23,7 +24,7 @@
</div>
<div class="col-sm-2 m-b">
<ul class="list-unstyled list-spaced">
<a href="http://dnsimple.link/resolving-lotus" target="_blank">
<a href="http://dnsimple.link/resolving-hanami" target="_blank">
<span>Resolving with<br/></span>
<img src="https://cdn.dnsimple.com/assets/resolving-with-us/logo-dark.png" alt="DNSimple" style="display:block;margin:0;padding:0;width:100px;"/>
</a>
@@ -0,0 +1,13 @@
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" content="Hanami - The web, with simplicity" />
<meta name="keywords" content="hanami,hanamirb,lotus,lotusrb,web,framework,ruby,open source,oss,os,software,free,free software,architecture,fast,lightweight,testing,tdd,bdd,test driven development,behaviour driven development,full stack,mvc,model view object,pattern,patterns,design patterns,oop,object oriented programming,testability,http,https,routing,router,http router,restful,resource,resources,convention,controller,models,repository,query,sql,interactors,two-step view,view,template,presenters,render,rendering,helpers,erb,haml,tilt,json,xml,yaml,yml,framwork,framewrok,riby,free sowftare"/>
<meta name="author" content="Luca Guidi">
<meta content="width=device-width, initial-scale=1.0" name="viewport" />
<link href="/atom.xml" rel="alternate" title="Hanami" type="application/atom+xml" />

<title>Hanami | <%= current_page.data.title || "The web, with simplicity." %></title>

<link href="http://fonts.googleapis.com/css?family=Roboto:100,300,400,700" rel="stylesheet">
<%= stylesheet_link_tag 'toolkit-minimal' %>
<%= stylesheet_link_tag 'application-minimal' %>
@@ -0,0 +1,34 @@
<nav class="navbar navbar-default navbar-static-top navbar-padded text-uppercase app-navbar">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed p-x-0" data-toggle="collapse" data-target="#navbar-collapse">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">
<span>Hanami</span>
</a>
</div>
<div class="navbar-collapse collapse" id="navbar-collapse">
<ul class="nav navbar-nav navbar-right">
<li>
<a href="/guides">Guides</a>
</li>
<li>
<a href="/community">Community</a>
</li>
<li>
<a href="/donate">Donate</a>
</li>
<li>
<a href="https://github.com/hanami" target="_blank">Source Code</a>
</li>
<li>
<a href="/blog">Blog</a>
</li>
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
@@ -1,5 +1,5 @@
---
title: Hanami | Blog
title: Blog
---
<div class="container container-blog">
<div class="block block-inverse text-center">
@@ -0,0 +1,21 @@
---
title: Announcing Hanami v0.7.2
date: 2016-02-09 11:46 UTC
tags: announcements
author: Luca Guidi
image: true
excerpt: >
Fix for static assets middleware
---

This release fixes only one regression introduced by [v0.7.1](/blog/2016/02/05/announcing-hanami-071.html).

## Bug Fixes

### hanami [v0.7.2](https://github.com/hanami/hanami/blob/master/CHANGELOG.md#v072---2016-02-09)

- Fixed routing issue when static assets server tried to hijiack paths that are matching directories in public directory [[Alfonso Uceda Pompa](https://github.com/AlfonsoUceda)]

## Upgrade Instructions

In order to get these bug fixes edit `Gemfile` to make sure it uses the right dependencies and then run `bundle update` from the root of the project.
Binary file not shown.
@@ -0,0 +1,85 @@
---
title: Validations Predicates
date: 2016-05-16 07:37 UTC
tags: announcements
author: Luca Guidi
image: true
excerpt: >
Hanami will introduce a new syntax for validations based on predicates. It features builtin and custom predicates, type safety, specific coercions for HTTP params, whitelisting, custom error messages with optional i18n support. This release will start a new alliance between Hanami and dry-rb.
---

For long time [Hanami::Validations](https://github.com/hanami/validations) had problems that we struggled to solve and new features were problematic to add.
Data management is complex task with thousands of cases to cover and because validations deal untrusted input, edge cases are common.
Even simple cases like _blank values_ management became an issue.

We tried to fix these problems, but over the time we realized that we hit the limit of that syntax, which led to lack of flexibility for us and for developers themselves.

At the same time [dry-rb](http://dry-rb.org) folks released a new, stronger validations gem: `dry-validation`.
It changes, for the good, the way we express validation rules.
So we took the decision to radically change our syntax and to adopt `dry-validation` as a validations backend for us.

## How It Will Work?

`Hanami::Validations` will work with input hashes and let define a set of validation rules **for each** key/value pair.
These rules are wrapped by lambdas (or special DSL) that check the input for a specific key to determine if it's valid or not.
To do that, we translate business requirements into predicates that are chained together with Ruby _faux boolean logic_ operators (eg. `&` or `|`).

Think of a signup form.
We need to ensure data integrity for the `name` field with the following rules.
It is required, it has to be: filled **and** a string **and** its size must be greater than 3 chars, but lesser than 64.
Here’s the code, **read it aloud** and notice how it perfectly expresses our needs for `name`.

```ruby
class Signup
include Hanami::Validations
validations do
required(:name) { filled? & str? & size?(3..64) }
end
end
result = Signup.new(name: "Luca").validate
result.success? # => true
result = Signup.new({}).validate
result.success? # => false
result.messages.fetch(:name) # => ["must be filled"]
```

### Boolean Logic

When we check data, we expect only two outcomes: an input can be valid or not.
No grey areas, nor fuzzy results.
It’s white or black, 1 or 0, `true` or `false` and _boolean logic_ is the perfect tool to express these two states.
Indeed, a Ruby _boolean expression_ can only return `true` or `false`.

To better recognise the pattern, let’s get back to the example above.
This time we will map the natural language rules with programming language rules.

```ruby
A name must be filled and be a string and its size fall between 3 and 64.
👇 👇 👇 👇 👇 👇 👇 👇
required(:name) { filled? & str? & size? (3 .. 64) }
```

Now, I hope you’ll never format code like that, but in this case, that formatting serves well our purpose to show how Ruby’s simplicity helps to define complex rules with no effort.

From a high level perspective, we can tell that input data for `name` is _valid_ only if **all** the requirements are satisfied. That’s because we used `&`.

But there is more. Rule composition with blocks is powerful, but it can become verbose.
To **reduce verbosity**, Hanami offers convenient macros that are internally expanded (aka interpreted) to an equivalent block expression.

```ruby
required(:name).filled(:str?, size?: 3..64)
```

### The Advantages

With this new syntax we give more control to developers: they can decide the order of execution of the validations.
They can define [custom predicates](https://github.com/hanami/validations#custom-predicates) and [custom error messages](https://github.com/hanami/validations#messages), [opt in for internationalization (i18n)](https://github.com/hanami/validations#internationalization-i18n) with small effort.
They can [dry code via macros](https://github.com/hanami/validations#macros), [reuse validators](https://github.com/hanami/validations#composition), [enforce types](https://github.com/hanami/validations#type-safety), [whitelist params](https://github.com/hanami/validations#whitelisting).

To summarize: we fixed old bugs, implemented features that developers asked for, increased internal code robustness and started a new alliance with **dry-rb** <3.

**These chances were just merged in [master](https://github.com/hanami/validations) and they will be released in a few months with `hanami` `v0.8.0`.**
Binary file not shown.

0 comments on commit fe27b79

Please sign in to comment.
You can’t perform that action at this time.