bem-on-rails 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +145 -0
- data/Rakefile +1 -0
- data/app/helpers/bemonrails/bem_render_helper.rb +82 -0
- data/app/views/bemonrails/essences/_content.html.haml +8 -0
- data/bem-on-rails.gemspec +25 -0
- data/lib/bem-on-rails.rb +8 -0
- data/lib/bem-on-rails/build/bem_names.rb +110 -0
- data/lib/bem-on-rails/engine.rb +5 -0
- data/lib/bem-on-rails/generators/install_generator.rb +40 -0
- data/lib/bem-on-rails/generators/templates/bem.tt +291 -0
- data/lib/bem-on-rails/generators/templates/coffee.tt +4 -0
- data/lib/bem-on-rails/generators/templates/haml.tt +2 -0
- data/lib/bem-on-rails/generators/templates/initializer.tt +101 -0
- data/lib/bem-on-rails/generators/templates/md.tt +0 -0
- data/lib/bem-on-rails/generators/templates/sass.tt +1 -0
- data/lib/bem-on-rails/version.rb +3 -0
- metadata +120 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: fff2737501c065e32082282035389196d6c04ff6
|
4
|
+
data.tar.gz: 21b73fe7f203438ec35752ac6b39e47b51c25b6b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6bb146bef1547d553da012d8ae3c1376902e503bd034d4ae6e8071745b0b5ac2fa65125d2ef18fcd0af310e1e195959b58522e9e67ede62e095e58f6baa4b8d3
|
7
|
+
data.tar.gz: b5fcfb9413c4cff5d583f25cccfa7f48e490d55c2f8c99fc7f9cafe1a10b3fc9b6e4ce4572e3791bde0ae3d906e58f6bab4a23bd2331a3bf8aeaca89b9a40991
|
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Anton Winogradov
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
# BEM On Rails
|
2
|
+
|
3
|
+
Work with BEM methodology in Rails applications. BEM On Rails is ruby copy from bem-tools.
|
4
|
+
You can read about bem-tools [here](http://bem.info/tools/bem/) and BEM methodology [here](http://bem.info/method/).
|
5
|
+
|
6
|
+
## Installation
|
7
|
+
|
8
|
+
Add this line to your application's Gemfile:
|
9
|
+
|
10
|
+
gem 'bem-on-rails'
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install bem-on-rails
|
19
|
+
|
20
|
+
Then you should run install generator:
|
21
|
+
|
22
|
+
$ rails g bemonrails:install
|
23
|
+
|
24
|
+
This generator adds lines to application_controller.rb, application_helper.rb and creates Thor task with templates.
|
25
|
+
You should run to watch your new instruments:
|
26
|
+
|
27
|
+
$ thor -T
|
28
|
+
|
29
|
+
Also generator creates initializer bem.rb with BEM constant. You can customize everythink!
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
You can create blocks, elements, modificators and groups for blocks. It's awesome! Also you can remove them and watch lists of blocks, block elements, blocks mods and etc. Try thor help for more info.
|
34
|
+
|
35
|
+
Default blocks folder structure:
|
36
|
+
- **blocks**
|
37
|
+
- **block_name**
|
38
|
+
- **elements**
|
39
|
+
- **__element_name**
|
40
|
+
- __element_name.html.haml
|
41
|
+
- __element_name.css.sass
|
42
|
+
- __element_name.coffee
|
43
|
+
- __element_name.md
|
44
|
+
- **mods**
|
45
|
+
- **_mod_name**
|
46
|
+
- **_mod_value**
|
47
|
+
- _mod_name.css.sass
|
48
|
+
- _mod_name.coffee
|
49
|
+
- _mod_name.md
|
50
|
+
- block_name.html.haml
|
51
|
+
- block_name.css.sass
|
52
|
+
- block_name.coffee
|
53
|
+
- block_name.md
|
54
|
+
- **group_name**
|
55
|
+
- **block_name**
|
56
|
+
|
57
|
+
You can specify all prefixes for blocks, elements and mods in bem.rb initializer.
|
58
|
+
|
59
|
+
### Creating
|
60
|
+
|
61
|
+
Easy block creating look like:
|
62
|
+
|
63
|
+
$ thor bem:create -b test
|
64
|
+
|
65
|
+
Block with modificator:
|
66
|
+
|
67
|
+
$ thor bem:create -b test -m large
|
68
|
+
|
69
|
+
Block with pretty mod with value:
|
70
|
+
|
71
|
+
$ thor bem:create -b test -m color -v red
|
72
|
+
|
73
|
+
Create element:
|
74
|
+
|
75
|
+
$ thor bem:create -b test -e icon
|
76
|
+
|
77
|
+
Element with mod:
|
78
|
+
|
79
|
+
$ thor bem:create -b test -e icon -m large
|
80
|
+
|
81
|
+
Element with pretty mod:
|
82
|
+
|
83
|
+
$ thor bem:create -b test -e icon -m size -v small
|
84
|
+
|
85
|
+
Block in special technolody:
|
86
|
+
$ thor bem:create -b test -T sass
|
87
|
+
|
88
|
+
Element in special tehcnology creates like block. List of know technologies you can see in bem.rb
|
89
|
+
initializer. You can customize it. After block, element or mod creating generator
|
90
|
+
adds to assets main file (application) require string. Ex:
|
91
|
+
```sass
|
92
|
+
//= require test/elements/__field/__field.css.sass
|
93
|
+
```
|
94
|
+
You should remember! You are not in any case should not be writing styles and scripts in assets application files.
|
95
|
+
Use them like configs, for require only. This involves using Sprockets.
|
96
|
+
|
97
|
+
### Rendering
|
98
|
+
|
99
|
+
In your view you should write this:
|
100
|
+
```ruby
|
101
|
+
= b "test", mods: {color: "red"}, content: [{ elem: "icon", elemMods: {size: "small"} }]
|
102
|
+
```
|
103
|
+
|
104
|
+
If block in group:
|
105
|
+
```ruby
|
106
|
+
= b "test", group: "name", mods: {color: "red"}, content: []
|
107
|
+
```
|
108
|
+
|
109
|
+
Syntax is look like [bemhtml](http://ru.bem.info/articles/bemhtml-reference/).
|
110
|
+
|
111
|
+
### Templates
|
112
|
+
|
113
|
+
Now templates exists for haml, sass, coffee and md technologies, but you will create your templates in
|
114
|
+
lib/tasks/templates. For example, you can watch haml template:
|
115
|
+
```haml
|
116
|
+
%div{ bemclass }
|
117
|
+
= bemcontent
|
118
|
+
```
|
119
|
+
Bemclass and bemcontent is BEM helpers for rendering.
|
120
|
+
|
121
|
+
### You want more BEM?
|
122
|
+
|
123
|
+
You can use CSSO instead of YUI compressor for precompile assets.
|
124
|
+
Read [here](http://habrahabr.ru/post/181880/) about it.
|
125
|
+
|
126
|
+
If you want it, please watch [here](https://github.com/Vasfed/csso-rails).
|
127
|
+
|
128
|
+
## Tomorrow
|
129
|
+
|
130
|
+
1. Rendering blocks in block.
|
131
|
+
2. Custom tag for block or element.
|
132
|
+
3. Add attrs for blocks and elements.
|
133
|
+
4. Add custom classes for blocks and elements.
|
134
|
+
5. Flags bem and js.
|
135
|
+
6. Mix blocks and elements.
|
136
|
+
7. Mods with restructure. Now you can't use mods with templates(haml, slim and etc.), but they generates.
|
137
|
+
8. Bem exutable. Work with Thor is not convenient.
|
138
|
+
|
139
|
+
## Contributing
|
140
|
+
|
141
|
+
1. Fork it
|
142
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
143
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
144
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
145
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module Bemonrails
|
2
|
+
module BemRenderHelper
|
3
|
+
|
4
|
+
include Bemonrails::BemNames
|
5
|
+
|
6
|
+
def render_block(name, builder={})
|
7
|
+
unless name.blank?
|
8
|
+
# Generate block paths
|
9
|
+
path = File.join BEM[:blocks][:dir], build_path_for(:block, builder)
|
10
|
+
target = File.join path, block(name), block(name)
|
11
|
+
# Block details
|
12
|
+
@block_name = name
|
13
|
+
@block_mods = builder[:mods]
|
14
|
+
@content = builder[:content]
|
15
|
+
# Render block in view
|
16
|
+
template_exists?(target) ? render(file: target) : bemempty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
alias :b :render_block
|
20
|
+
|
21
|
+
def render_element(name, builder={})
|
22
|
+
unless name.blank?
|
23
|
+
# Generate element paths
|
24
|
+
path = File.join build_path_for(:element, builder)
|
25
|
+
target = File.join path, element(name), element(name)
|
26
|
+
# Element details
|
27
|
+
@element_name = name
|
28
|
+
@element_mods = builder[:elemMods]
|
29
|
+
puts @element_mods
|
30
|
+
@content = builder[:content]
|
31
|
+
# Render element in block
|
32
|
+
template_exists?(target) ? render(file: target) : bemempty
|
33
|
+
end
|
34
|
+
end
|
35
|
+
alias :e :render_element
|
36
|
+
|
37
|
+
def render_class
|
38
|
+
if @block_name && !@element_name
|
39
|
+
classes_array = [ block(@block_name) ]
|
40
|
+
# Install mods
|
41
|
+
if @block_mods
|
42
|
+
@block_mods.each do |mod_name, mod_value|
|
43
|
+
# Generate mods classes
|
44
|
+
if mod_value
|
45
|
+
classes_array.push block(@block_name) + mod(mod_name.to_s) + mod(mod_name.to_s, mod_value)
|
46
|
+
else
|
47
|
+
classes_array.push block(@block_name) + mod(mod_name.to_s)
|
48
|
+
end
|
49
|
+
|
50
|
+
# TODO: Find mod with restructure .haml, .erb or etc.
|
51
|
+
end
|
52
|
+
end
|
53
|
+
elsif @element_name
|
54
|
+
classes_array = [ block(@block_name) + element(@element_name) ]
|
55
|
+
# Install mods
|
56
|
+
if @element_mods
|
57
|
+
@element_mods.each do |mod_name, mod_value|
|
58
|
+
# Generate mods classes
|
59
|
+
if mod_value
|
60
|
+
classes_array.push block(@block_name) + element(@element_name) + mod(mod_name.to_s) + mod(mod_name.to_s, mod_value)
|
61
|
+
else
|
62
|
+
classes_array.push block(@block_name) + element(@element_name) + mod(mod_name.to_s)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
{ class: classes_array.join(" ") }
|
69
|
+
end
|
70
|
+
alias :bemclass :render_class
|
71
|
+
|
72
|
+
def render_empty
|
73
|
+
"<div class=#{ bemclass }></div>".html_safe
|
74
|
+
end
|
75
|
+
alias :bemempty :render_empty
|
76
|
+
|
77
|
+
def render_content
|
78
|
+
render "bemonrails/essences/content"
|
79
|
+
end
|
80
|
+
alias :bemcontent :render_content
|
81
|
+
end
|
82
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'bem-on-rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "bem-on-rails"
|
8
|
+
spec.version = Bemonrails::VERSION
|
9
|
+
spec.authors = ["Anton Winogradov"]
|
10
|
+
spec.email = ["winogradovaa@gmail.com"]
|
11
|
+
spec.description = %q{Gem for work with BEM methodology in Rails applications}
|
12
|
+
spec.summary = %q{BEM Tools for Rails applications}
|
13
|
+
spec.homepage = "https://github.com/verybigman/bem-on-rails"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
#spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_dependency "thor", "~> 0.16"
|
24
|
+
spec.add_dependency "activesupport"
|
25
|
+
end
|
data/lib/bem-on-rails.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
module Bemonrails
|
2
|
+
module BemNames
|
3
|
+
# Directories paths.
|
4
|
+
def build_path_for(essence, builder=options)
|
5
|
+
# I think all block can be in groups
|
6
|
+
path = [builder[:group]]
|
7
|
+
case essence
|
8
|
+
when :mod
|
9
|
+
# This is for mods with value
|
10
|
+
if builder[:block] && builder[:element] && builder[:value]
|
11
|
+
path.push(mod_directory(:element), mod)
|
12
|
+
elsif builder[:block] && builder[:value]
|
13
|
+
path.push(mod_directory(:block), mod)
|
14
|
+
# This is for mods without value
|
15
|
+
elsif builder[:block] && builder[:element]
|
16
|
+
path.push(mod_directory(:element))
|
17
|
+
elsif builder[:block]
|
18
|
+
path.push(mod_directory(:block))
|
19
|
+
else
|
20
|
+
raise print_message("Mods must be for block or element.", 'red')
|
21
|
+
end
|
22
|
+
when :element
|
23
|
+
path.push(element_directory)
|
24
|
+
when :block
|
25
|
+
# Yea! Do nothing!
|
26
|
+
else
|
27
|
+
raise print_message("Unknown params. Try 'thor help bem:create'", 'red')
|
28
|
+
end
|
29
|
+
File.join(path.compact)
|
30
|
+
end
|
31
|
+
|
32
|
+
def generate_names(builder=options)
|
33
|
+
names = {}
|
34
|
+
# Generate names for block, his mods and they values
|
35
|
+
if builder[:block]
|
36
|
+
|
37
|
+
names[:klass] = names[:name] = block
|
38
|
+
|
39
|
+
if builder[:mod]
|
40
|
+
names[:name] = mod
|
41
|
+
names[:klass] = block + names[:name]
|
42
|
+
end
|
43
|
+
|
44
|
+
if builder[:value]
|
45
|
+
names[:name] = mod(builder[:value])
|
46
|
+
names[:klass] = block + mod + names[:name]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# Generate names for elements, his mods and they values
|
51
|
+
if builder[:element]
|
52
|
+
|
53
|
+
names[:name] = element
|
54
|
+
names[:klass] += names[:name]
|
55
|
+
|
56
|
+
if builder[:mod]
|
57
|
+
names[:name] = mod
|
58
|
+
names[:klass] = block + element + names[:name]
|
59
|
+
end
|
60
|
+
|
61
|
+
if builder[:value]
|
62
|
+
names[:name] = mod(builder[:value])
|
63
|
+
names[:klass] = block + element + mod + names[:name]
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
names
|
68
|
+
end
|
69
|
+
|
70
|
+
def block(name=options[:block])
|
71
|
+
BEM[:blocks][:prefix] + name
|
72
|
+
end
|
73
|
+
|
74
|
+
def element_directory
|
75
|
+
block_name = @block_name ? @block_name : options[:block]
|
76
|
+
File.join(block(block_name), BEM[:elements][:dir])
|
77
|
+
end
|
78
|
+
|
79
|
+
def element(name=options[:element])
|
80
|
+
BEM[:elements][:prefix] + name
|
81
|
+
end
|
82
|
+
|
83
|
+
def mod_directory(essence)
|
84
|
+
case essence
|
85
|
+
when :block
|
86
|
+
File.join(block, BEM[:mods][:dir])
|
87
|
+
when :element
|
88
|
+
File.join(element_directory, element, BEM[:mods][:dir])
|
89
|
+
else
|
90
|
+
File.join(block, BEM[:mods][:dir])
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def mod(name= options[:mod], value=false)
|
95
|
+
if value
|
96
|
+
BEM[:mods][:prefix] + value
|
97
|
+
else
|
98
|
+
BEM[:mods][:prefix] + name
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def template_exists?(file)
|
103
|
+
BEM[:techs].each do |tech, extension|
|
104
|
+
if File.exists? file + extension
|
105
|
+
return true
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
|
3
|
+
module Bemonrails
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
source_root File.expand_path("../templates/", __FILE__)
|
7
|
+
|
8
|
+
def add_render_helpers
|
9
|
+
app_helper = 'app/helpers/application_helper.rb'
|
10
|
+
first_string = "module ApplicationHelper"
|
11
|
+
bem_render_helpers = "\n\t# Add BEM blocks rendering helpers\n\tinclude Bemonrails::BemRenderHelper\n"
|
12
|
+
|
13
|
+
insert_into_file app_helper, bem_render_helpers, :after => first_string
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_blocks_folder
|
17
|
+
app_controller = 'app/controllers/application_controller.rb'
|
18
|
+
protection_str = "protect_from_forgery\n"
|
19
|
+
bem_block_folder = "\n\t# Add BEM blocks folder to default views scope\n\tbefore_filter { prepend_view_path(BEM[:blocks][:dir]) }\n"
|
20
|
+
|
21
|
+
insert_into_file app_controller, bem_block_folder, :after => protection_str
|
22
|
+
end
|
23
|
+
|
24
|
+
def add_initializer
|
25
|
+
template "initializer.tt", File.join(Rails.root, "config", "initializers", "bem.rb")
|
26
|
+
end
|
27
|
+
|
28
|
+
def install_bem_tasks
|
29
|
+
template "bem.tt", File.join(Rails.root, "lib", "tasks", "bem.thor")
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_blocks_templates
|
33
|
+
%w(haml.tt coffee.tt md.tt sass.tt).each do |t|
|
34
|
+
template t, File.join(Rails.root, "lib", "tasks", "templates", t)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,291 @@
|
|
1
|
+
require File.expand_path('config/environment.rb')
|
2
|
+
|
3
|
+
class Bem < Thor
|
4
|
+
include Thor::Actions
|
5
|
+
include Bemonrails::BemNames
|
6
|
+
|
7
|
+
# Templates for techs
|
8
|
+
source_root File.expand_path('../templates', __FILE__)
|
9
|
+
|
10
|
+
desc 'create', 'Create block, element or mod'
|
11
|
+
method_option :block, type: :string, aliases: "-b", desc: "Create block in default techs."
|
12
|
+
method_option :element, type: :string, aliases: "-e", desc: "Create element in default techs. Use with block param."
|
13
|
+
method_option :mod, type: :string, aliases: "-m", desc: "Create modificator for block or element."
|
14
|
+
method_option :value, type: :string, aliases: "-v", desc: "Value for modificator."
|
15
|
+
method_option :tech, type: :string, aliases: "-T", desc: "Create essence in spec tech."
|
16
|
+
method_option :group, type: :string, aliases: "-G", desc: "Create essence in group. Work for blocks only!"
|
17
|
+
method_option :force, type: :boolean, desc: "Force existing block, element or mod files."
|
18
|
+
def create
|
19
|
+
# Minimum one param is required for creating
|
20
|
+
if options[:block] && !options[:element] && !options[:mod]
|
21
|
+
path = build_path_for(:block)
|
22
|
+
destination = File.join(path, block)
|
23
|
+
unless essence_exist?(destination)
|
24
|
+
create_essence(BEM[:blocks], path)
|
25
|
+
update_assets(block, path)
|
26
|
+
end
|
27
|
+
elsif options[:element] && !options[:mod]
|
28
|
+
path = build_path_for(:element)
|
29
|
+
destination = File.join(path, element)
|
30
|
+
unless essence_exist?(destination)
|
31
|
+
create_essence(BEM[:elements], path)
|
32
|
+
update_assets(element, path)
|
33
|
+
end
|
34
|
+
elsif options[:mod]
|
35
|
+
path = build_path_for(:mod)
|
36
|
+
essence = options[:value] ? options[:value] : options[:mod]
|
37
|
+
destination = File.join(path, mod(essence))
|
38
|
+
unless essence_exist?(destination)
|
39
|
+
create_essence(BEM[:mods], path)
|
40
|
+
update_assets(mod(essence), path)
|
41
|
+
end
|
42
|
+
else
|
43
|
+
raise print_message("You should set params. Try 'thor help bem:create' for more information", 'red')
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
desc 'remove', 'Remove block, element or mod'
|
50
|
+
method_option :block, type: :string, aliases: "-b", desc: "Remove block in default techs."
|
51
|
+
method_option :element, type: :string, aliases: "-e", desc: "Remove element in default techs. Use with block param."
|
52
|
+
method_option :mod, type: :string, aliases: "-m", desc: "Remove modificator for block or element."
|
53
|
+
method_option :value, type: :string, aliases: "-v", desc: "Value for modificator."
|
54
|
+
method_option :tech, type: :string, aliases: "-T", desc: "Remove essence in spec tech."
|
55
|
+
method_option :group, type: :string, aliases: "-G", desc: "Remove essence in group. Work for blocks only!"
|
56
|
+
def remove
|
57
|
+
# Minimum one param is required for deleting
|
58
|
+
if options[:block] && !options[:element] && !options[:mod]
|
59
|
+
path = build_path_for(:block)
|
60
|
+
destination = File.join(path, block)
|
61
|
+
if essence_exist?(destination, false)
|
62
|
+
remove_essence(BEM[:blocks], path)
|
63
|
+
cut_assets(block, path)
|
64
|
+
end
|
65
|
+
elsif options[:element] && !options[:mod]
|
66
|
+
path = build_path_for(:element)
|
67
|
+
destination = File.join(path, element)
|
68
|
+
if essence_exist?(destination, false)
|
69
|
+
remove_essence(BEM[:elements], path)
|
70
|
+
cut_assets(element, path)
|
71
|
+
end
|
72
|
+
elsif options[:mod]
|
73
|
+
path = build_path_for(:mod)
|
74
|
+
essence = options[:value] ? options[:value] : options[:mod]
|
75
|
+
destination = File.join(path, mod(essence))
|
76
|
+
if essence_exist?(destination, false)
|
77
|
+
remove_essence(BEM[:mods], path)
|
78
|
+
cut_assets(mod(essence), path)
|
79
|
+
end
|
80
|
+
else
|
81
|
+
raise print_message("You should set params. Try 'thor help bem:remove' for more information", 'red')
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
|
86
|
+
|
87
|
+
desc 'usage', 'Essence usage information'
|
88
|
+
method_option :block, type: :string, aliases: "-b", desc: "Block usage."
|
89
|
+
method_option :element, type: :string, aliases: "-e", desc: "Element usage"
|
90
|
+
method_option :mod, type: :string, aliases: "-m", desc: "Mod usage."
|
91
|
+
method_option :value, type: :string, aliases: "-v", desc: "Mod value usage."
|
92
|
+
method_option :group, type: :string, aliases: "-G", desc: "Search essence in group."
|
93
|
+
def usage
|
94
|
+
if options[:block] && !options[:element] && !options[:mod]
|
95
|
+
path = build_path_for(:block)
|
96
|
+
search_usage_information(block, path)
|
97
|
+
elsif options[:element] && !options[:mod]
|
98
|
+
path = build_path_for(:element)
|
99
|
+
search_usage_information(element, path)
|
100
|
+
elsif options[:mod]
|
101
|
+
path = build_path_for(:mod)
|
102
|
+
essence = options[:value] ? options[:value] : options[:mod]
|
103
|
+
search_usage_information(mod(essence), path)
|
104
|
+
else
|
105
|
+
raise print_message("You should set params. Try 'thor help bem:usage' for more information", 'red')
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
|
111
|
+
desc 'list', 'See list of group, block elements, mods and etc.'
|
112
|
+
method_option :block, type: :string, aliases: "-b", desc: "All block elements, mods and mods values"
|
113
|
+
method_option :element, type: :string, aliases: "-e", desc: "All element mods and mods values"
|
114
|
+
method_option :mod, type: :string, aliases: "-m", desc: "All mod values."
|
115
|
+
method_option :group, type: :string, aliases: "-G", desc: "All blocks in group."
|
116
|
+
def list
|
117
|
+
if options[:block] && !options[:element] && !options[:mod]
|
118
|
+
# Print all block elements and mods
|
119
|
+
path = build_path_for(:block)
|
120
|
+
print_elements_list(block, path)
|
121
|
+
print_mods_list(block, path)
|
122
|
+
elsif options[:element] && !options[:mod]
|
123
|
+
# Print all element mods
|
124
|
+
path = build_path_for(:element)
|
125
|
+
print_mods_list(element, path)
|
126
|
+
elsif options[:mod]
|
127
|
+
# Print all mod values
|
128
|
+
path = build_path_for(:mod)
|
129
|
+
print_values_list(element, path)
|
130
|
+
else
|
131
|
+
# Print all blocks
|
132
|
+
path = build_path_for(:block)
|
133
|
+
print_blocks_list(path)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
|
139
|
+
protected
|
140
|
+
|
141
|
+
def essence_exist?(essence_dir, creating=true)
|
142
|
+
if File.directory?(File.join(BEM[:blocks][:path], essence_dir))
|
143
|
+
puts print_message("Essence with this name is already exists. Try 'thor help bem:list' or 'thor help bem:usage ", 'red') if creating
|
144
|
+
true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def create_essence(essence_options, path)
|
149
|
+
|
150
|
+
names = generate_names
|
151
|
+
|
152
|
+
@css_class = '.' + names[:klass]
|
153
|
+
|
154
|
+
# [!] Templates exist only for wiki, haml, sass and coffee.
|
155
|
+
# If you need more templates. Please create them into templates
|
156
|
+
# directory. Watch existing templates for example.
|
157
|
+
# What is .tt? It is custom extension for finding templates in other files.
|
158
|
+
if options[:tech] # Maybe recive from command line
|
159
|
+
template "#{options[:tech]}.tt", File.join(essence_options[:path], path, names[:name], names[:name] + BEM[:techs][options[:tech].to_sym])
|
160
|
+
else
|
161
|
+
# You can customize this list of defaults. See on top of file.
|
162
|
+
BEM[:default].each do |tech, extension|
|
163
|
+
template "#{tech}.tt", File.join(essence_options[:path], path, names[:name], names[:name] + extension)
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def remove_essence(essence_options, path)
|
169
|
+
|
170
|
+
names = generate_names
|
171
|
+
|
172
|
+
if options[:tech]
|
173
|
+
destination = File.join(essence_options[:path], path, names[:name], names[:name] + BEM[:techs][options[:tech].to_sym])
|
174
|
+
FileUtils.rm(destination)
|
175
|
+
else
|
176
|
+
destination = File.join(essence_options[:path], path, names[:name])
|
177
|
+
FileUtils.rm_rf(destination)
|
178
|
+
end
|
179
|
+
|
180
|
+
puts "\e[0;31m remove\e[0m " + destination.to_s.gsub(Rails.root.to_s + "/", "")
|
181
|
+
end
|
182
|
+
|
183
|
+
def update_assets(name, path)
|
184
|
+
BEM[:assets].each do |type, tech|
|
185
|
+
asset = File.join(Rails.root, "app", "assets", type.to_s, "application" + tech[:ext])
|
186
|
+
destination = [path, name, name + tech[:ext]].reject(&:empty?)
|
187
|
+
line = "#{tech[:import]} #{File.join(destination)}#{tech[:postfix]}"
|
188
|
+
File.open(asset, "a") do |f|
|
189
|
+
f.write("\n" + line)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
def cut_assets(name, path)
|
195
|
+
BEM[:assets].each do |type, tech|
|
196
|
+
asset = File.join(Rails.root, "app", "assets", type.to_s, "application" + tech[:ext])
|
197
|
+
destination = [path, name, name + tech[:ext]].reject(&:empty?)
|
198
|
+
line = "#{tech[:import]} #{File.join(destination)}#{tech[:postfix]}"
|
199
|
+
|
200
|
+
# Open temporary file
|
201
|
+
tmp = Tempfile.new("temp")
|
202
|
+
# Write good lines to temporary file.
|
203
|
+
open(asset, 'r').each do |l|
|
204
|
+
tmp << l unless l.chomp == line || l.empty?
|
205
|
+
end
|
206
|
+
# Close tmp, or troubles ahead.
|
207
|
+
tmp.close
|
208
|
+
# Temp to original.
|
209
|
+
FileUtils.mv(tmp.path, asset)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
def search_usage_information(essence, path)
|
214
|
+
BEM[:usage].each do |tech, extension|
|
215
|
+
file_destination = File.join(BEM[:blocks][:path] + path, essence, essence + extension)
|
216
|
+
if File.exist?(file_destination)
|
217
|
+
puts tech.to_s + ": " + file_destination
|
218
|
+
puts "BEM[:usage]:\t"
|
219
|
+
File.readlines(file_destination).each do |line|
|
220
|
+
puts line
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
def print_blocks_list(essence="", path)
|
227
|
+
directory_destination = File.join(BEM[:blocks][:path] + path, essence)
|
228
|
+
puts directory_destination
|
229
|
+
print_message("BEM[:blocks]:\t", 'green')
|
230
|
+
Dir[directory_destination + "/*"].each do |name|
|
231
|
+
# Show only essences. No files. No groups.
|
232
|
+
# Essences have't ext.
|
233
|
+
# Get dir name.
|
234
|
+
name = name.split('/')[-1]
|
235
|
+
if name.split('.').size == 1
|
236
|
+
puts " - " + name
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
def print_elements_list(essence="", path)
|
242
|
+
directory_destination = File.join(BEM[:blocks][:path] + path, essence, BEM[:elements][:dir])
|
243
|
+
print_message("BEM[:elements]:\t", 'purple')
|
244
|
+
Dir[directory_destination + "/*"].each do |name|
|
245
|
+
# Get dir name.
|
246
|
+
name = name.split('/')[-1]
|
247
|
+
puts " - " + name.split(BEM[:elements][:prefix])[1]
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
251
|
+
def print_mods_list(essence="", path)
|
252
|
+
directory_destination = File.join(BEM[:blocks][:path] + path, essence, BEM[:mods][:dir])
|
253
|
+
print_message("BEM[:mods]:\t", 'cyan')
|
254
|
+
Dir[directory_destination + "/*"].each do |name|
|
255
|
+
# Get dir name.
|
256
|
+
name = name.split('/')[-1]
|
257
|
+
puts " - " + name.split(BEM[:mods][:prefix])[1]
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
def print_values_list(essence="", path)
|
262
|
+
directory_destination = File.join(BEM[:blocks][:path] + path, essence)
|
263
|
+
print_message("VALUES:\t", 'yellow')
|
264
|
+
Dir[directory_destination + "/*"].each do |name|
|
265
|
+
# Get dir name.
|
266
|
+
name = name.split('/')[-1]
|
267
|
+
puts " - " + name.split(BEM[:mods][:prefix])[1]
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
def print_message(message, color)
|
272
|
+
check_argument_data_type(message, String)
|
273
|
+
check_argument_data_type(color, String)
|
274
|
+
|
275
|
+
color = case color
|
276
|
+
when 'green' then "\e[0;32m"
|
277
|
+
when 'red' then "\e[0;31m"
|
278
|
+
when 'blue' then "\e[0;34m"
|
279
|
+
when 'cyan' then "\e[0;36m"
|
280
|
+
when 'purple' then "\e[0;35m"
|
281
|
+
when 'yellow' then "\e[1;33m"
|
282
|
+
else ''
|
283
|
+
end
|
284
|
+
|
285
|
+
puts "#{color + message} \e[0m"
|
286
|
+
end
|
287
|
+
|
288
|
+
def check_argument_data_type(argument, type)
|
289
|
+
raise print_message("#{argument} must be a #{type.to_s}", 'red') unless argument.kind_of? type
|
290
|
+
end
|
291
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
BEM = {}
|
2
|
+
|
3
|
+
# List of known techs.
|
4
|
+
BEM[:techs] = {
|
5
|
+
haml: ".html.haml",
|
6
|
+
slim: ".html.slim",
|
7
|
+
erb: "html.erb",
|
8
|
+
jade: ".jade",
|
9
|
+
sass: ".css.sass",
|
10
|
+
scss: ".css.scss",
|
11
|
+
less: ".css.less",
|
12
|
+
styl: ".css.styl",
|
13
|
+
css: ".css",
|
14
|
+
coffee: ".coffee",
|
15
|
+
js: ".js",
|
16
|
+
md: ".md",
|
17
|
+
wiki: ".wiki"
|
18
|
+
}
|
19
|
+
|
20
|
+
# List of default techs, generating if -T is empty.
|
21
|
+
BEM[:default] = {
|
22
|
+
haml: BEM[:techs][:haml],
|
23
|
+
sass: BEM[:techs][:sass],
|
24
|
+
coffee: BEM[:techs][:coffee],
|
25
|
+
md: BEM[:techs][:md]
|
26
|
+
}
|
27
|
+
|
28
|
+
# Usage files variants.
|
29
|
+
BEM[:usage] = {
|
30
|
+
md: BEM[:techs][:md],
|
31
|
+
wiki: BEM[:techs][:wiki]
|
32
|
+
}
|
33
|
+
|
34
|
+
# Default directories, try to customize.
|
35
|
+
# Blocks directory in root of rails app.
|
36
|
+
BEM[:blocks] = {
|
37
|
+
dir: "blocks",
|
38
|
+
path: Rails.root.join("blocks"),
|
39
|
+
prefix: "",
|
40
|
+
postfix: ""
|
41
|
+
}
|
42
|
+
|
43
|
+
# Elements directory in every block directory.
|
44
|
+
# Write 'dir: ""' for creating elements in root of block.
|
45
|
+
BEM[:elements] = {
|
46
|
+
dir: "elements",
|
47
|
+
path: BEM[:blocks][:path], # This is individualy for every block
|
48
|
+
prefix: "__",
|
49
|
+
postfix: ""
|
50
|
+
}
|
51
|
+
|
52
|
+
# Mods directory in every block directory.
|
53
|
+
# Write 'dir: ""' for creating mods in root of block.
|
54
|
+
BEM[:mods] = {
|
55
|
+
dir: "mods",
|
56
|
+
path: BEM[:blocks][:path], # This is individualy for every block or element
|
57
|
+
prefix: "_",
|
58
|
+
postfix: ""
|
59
|
+
}
|
60
|
+
|
61
|
+
# [!] If you work with sass and you want to create blocks, elements and mods in sass,
|
62
|
+
# you should convert 'application.css' to 'application.css.sass'. Because, when
|
63
|
+
# blocks, elements or mods is created, technology files will be included to application
|
64
|
+
# files. This also applies to scss, styl, less and coffee. Customize this for use your
|
65
|
+
# favorite techs. Asset type may have postfix and it's optional.
|
66
|
+
# Example:
|
67
|
+
#
|
68
|
+
# assets = {
|
69
|
+
# stylesheets:
|
70
|
+
# {
|
71
|
+
# ext: BEM[:techs][:scss],
|
72
|
+
# import: '//= require',
|
73
|
+
# posfix: ';'
|
74
|
+
# }
|
75
|
+
# }
|
76
|
+
|
77
|
+
BEM[:assets] = {
|
78
|
+
stylesheets:
|
79
|
+
{
|
80
|
+
ext: BEM[:techs][:sass],
|
81
|
+
import: '//= require'
|
82
|
+
},
|
83
|
+
javascripts:
|
84
|
+
{
|
85
|
+
ext: BEM[:techs][:js],
|
86
|
+
import: '//= require'
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
# You must use application files in
|
91
|
+
# assets as a configs, don't write code in them.
|
92
|
+
# This is need to sprokets includes.
|
93
|
+
Rails.application.config.assets.paths << BEM[:blocks][:dir]
|
94
|
+
|
95
|
+
# Use CSSO instead of YUI.
|
96
|
+
# Watch here https://github.com/Vasfed/csso-rails
|
97
|
+
# Add to gem file:
|
98
|
+
# gem 'csso-rails'
|
99
|
+
|
100
|
+
# And uncomment this
|
101
|
+
# Rails.config.assets.css_compressor = :csso
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= @css_class %>
|
metadata
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bem-on-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Anton Winogradov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-09-08 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: thor
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.16'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.16'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Gem for work with BEM methodology in Rails applications
|
70
|
+
email:
|
71
|
+
- winogradovaa@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- CHANGELOG.md
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- app/helpers/bemonrails/bem_render_helper.rb
|
83
|
+
- app/views/bemonrails/essences/_content.html.haml
|
84
|
+
- bem-on-rails.gemspec
|
85
|
+
- lib/bem-on-rails.rb
|
86
|
+
- lib/bem-on-rails/build/bem_names.rb
|
87
|
+
- lib/bem-on-rails/engine.rb
|
88
|
+
- lib/bem-on-rails/generators/install_generator.rb
|
89
|
+
- lib/bem-on-rails/generators/templates/bem.tt
|
90
|
+
- lib/bem-on-rails/generators/templates/coffee.tt
|
91
|
+
- lib/bem-on-rails/generators/templates/haml.tt
|
92
|
+
- lib/bem-on-rails/generators/templates/initializer.tt
|
93
|
+
- lib/bem-on-rails/generators/templates/md.tt
|
94
|
+
- lib/bem-on-rails/generators/templates/sass.tt
|
95
|
+
- lib/bem-on-rails/version.rb
|
96
|
+
homepage: https://github.com/verybigman/bem-on-rails
|
97
|
+
licenses:
|
98
|
+
- MIT
|
99
|
+
metadata: {}
|
100
|
+
post_install_message:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
103
|
+
- lib
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
110
|
+
requirements:
|
111
|
+
- - '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
requirements: []
|
115
|
+
rubyforge_project:
|
116
|
+
rubygems_version: 2.0.7
|
117
|
+
signing_key:
|
118
|
+
specification_version: 4
|
119
|
+
summary: BEM Tools for Rails applications
|
120
|
+
test_files: []
|