Skip to content

Commit

Permalink
Merge branch 'build' into announcing-v080
Browse files Browse the repository at this point in the history
  • Loading branch information
jodosha committed Jul 20, 2016
2 parents fb680fd + 0bb4469 commit fe27b79
Show file tree
Hide file tree
Showing 116 changed files with 4,291 additions and 462 deletions.
48 changes: 45 additions & 3 deletions config.rb
Expand Up @@ -2,8 +2,10 @@


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


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


### ###
Expand Down Expand Up @@ -112,6 +114,46 @@ def article_image_url(article)
GUIDES_ROOT = 'source/guides'.freeze GUIDES_ROOT = 'source/guides'.freeze
GUIDES_EDIT_URL = 'https://github.com/hanami/hanami.github.io/edit/build/'.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 def guides_navigation
result = '' result = ''


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


def guides_edit_article(source) def guides_edit_article(source)
url = GUIDES_EDIT_URL + source.gsub("#{ Dir.pwd }/", '') 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 end


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


def hanami_version def hanami_version
'0.7.1' '0.7.3'
end end
end end


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


set :markdown_engine, :redcarpet 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 # Build-specific configuration
configure :build do configure :build do
Expand Down
103 changes: 103 additions & 0 deletions data/guides.yml
@@ -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
23 changes: 23 additions & 0 deletions lib/github_style_titles.rb
@@ -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
3 changes: 2 additions & 1 deletion source/_footer.erb
Expand Up @@ -9,6 +9,7 @@
<li><a href="https://github.com/hanami" target="_blank">GitHub</a></li> <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://twitter.com/hanamirb" target="_blank">Twitter</a></li>
<li><a href="https://rubygems.org/gems/hanami" target="_blank">Rubygems</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> </ul>
</div> </div>
<div class="col-sm-2 m-b"> <div class="col-sm-2 m-b">
Expand All @@ -23,7 +24,7 @@
</div> </div>
<div class="col-sm-2 m-b"> <div class="col-sm-2 m-b">
<ul class="list-unstyled list-spaced"> <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> <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;"/> <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> </a>
Expand Down
13 changes: 13 additions & 0 deletions source/_head.erb
@@ -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' %>
34 changes: 34 additions & 0 deletions source/_navbar.erb
@@ -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>
2 changes: 1 addition & 1 deletion source/blog.html.erb
@@ -1,5 +1,5 @@
--- ---
title: Hanami | Blog title: Blog
--- ---
<div class="container container-blog"> <div class="container container-blog">
<div class="block block-inverse text-center"> <div class="block block-inverse text-center">
Expand Down
21 changes: 21 additions & 0 deletions source/blog/2016-02-09-announcing-hanami-072.html.markdown
@@ -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.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
85 changes: 85 additions & 0 deletions source/blog/2016-05-16-validations-predicates.html.markdown
@@ -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`.**
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit fe27b79

Please sign in to comment.