phlex-rails 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.editorconfig +13 -0
- data/.rubocop.yml +31 -0
- data/Appraisals +13 -0
- data/CONTRIBUTING.md +23 -0
- data/Gemfile +7 -4
- data/README.md +14 -30
- data/SECURITY.md +5 -0
- data/fixtures/dummy/app/assets/config/manifest.js +0 -0
- data/fixtures/dummy/app/components/comment_component.html.erb +14 -0
- data/fixtures/dummy/app/components/comment_component.rb +8 -0
- data/fixtures/dummy/app/components/reaction_component.html.erb +3 -0
- data/fixtures/dummy/app/components/reaction_component.rb +7 -0
- data/fixtures/dummy/app/controllers/articles_controller.rb +4 -0
- data/fixtures/dummy/app/controllers/comments_controller.rb +4 -0
- data/fixtures/dummy/app/views/application_view.rb +7 -0
- data/fixtures/dummy/app/views/articles/form.rb +15 -0
- data/fixtures/dummy/app/views/articles/index.html.erb +14 -0
- data/fixtures/dummy/app/views/articles/new.html.erb +1 -0
- data/fixtures/dummy/app/views/card.rb +15 -0
- data/fixtures/dummy/app/views/comments/comment.rb +25 -0
- data/fixtures/dummy/app/views/comments/index.html.erb +3 -0
- data/fixtures/dummy/app/views/comments/reaction.rb +17 -0
- data/fixtures/dummy/app/views/comments/show.html.erb +3 -0
- data/fixtures/dummy/app/views/heading.rb +9 -0
- data/fixtures/dummy/config/database.yml +3 -0
- data/fixtures/dummy/config/routes.rb +5 -0
- data/fixtures/dummy/config/storage.yml +3 -0
- data/fixtures/dummy/db/schema.rb +6 -0
- data/fixtures/dummy/log/.gitignore +1 -0
- data/fixtures/dummy/public/favicon.ico +0 -0
- data/fixtures/rails_helper.rb +9 -0
- data/fixtures/view_helper.rb +16 -0
- data/lib/generators/phlex/collection/USAGE +8 -0
- data/lib/generators/phlex/collection/collection_generator.rb +13 -0
- data/lib/generators/phlex/collection/templates/collection.rb.erb +16 -0
- data/lib/generators/phlex/controller/USAGE +10 -0
- data/lib/generators/phlex/controller/controller_generator.rb +54 -0
- data/lib/generators/phlex/controller/templates/controller.rb.erb +10 -0
- data/lib/generators/phlex/controller/templates/view.rb.erb +14 -0
- data/lib/generators/phlex/layout/USAGE +8 -0
- data/lib/generators/phlex/layout/layout_generator.rb +13 -0
- data/lib/generators/phlex/layout/templates/layout.rb.erb +31 -0
- data/lib/generators/phlex/page/USAGE +8 -0
- data/lib/generators/phlex/page/page_generator.rb +13 -0
- data/lib/generators/phlex/page/templates/page.rb.erb +13 -0
- data/lib/generators/phlex/table/USAGE +8 -0
- data/lib/generators/phlex/table/table_generator.rb +14 -0
- data/lib/generators/phlex/table/templates/table.rb.erb +11 -0
- data/lib/generators/phlex/view/USAGE +9 -0
- data/lib/generators/phlex/view/templates/view.rb.erb +14 -0
- data/lib/generators/phlex/view/view_generator.rb +23 -0
- data/lib/generators/rspec/view/templates/view_spec.rb.erb +10 -0
- data/lib/generators/rspec/view/view_generator.rb +14 -0
- data/lib/generators/test_unit/templates/view_test.rb.erb +15 -0
- data/lib/generators/test_unit/view_generator.rb +12 -0
- data/lib/install/phlex.rb +38 -0
- data/lib/phlex/rails/buffer.rb +18 -0
- data/lib/phlex/rails/engine.rb +10 -0
- data/lib/phlex/rails/form.rb +67 -0
- data/lib/phlex/rails/helpers.rb +126 -0
- data/lib/phlex/rails/layout.rb +16 -0
- data/lib/phlex/rails/renderable.rb +35 -0
- data/lib/phlex/rails/version.rb +3 -3
- data/lib/phlex/rails.rb +9 -6
- data/lib/phlex/testing/rails.rb +19 -0
- data/lib/phlex-rails.rb +3 -0
- data/lib/tasks/phlex_tasks.rake +11 -0
- data/phlex_logo.png +0 -0
- metadata +124 -16
- data/.gitignore +0 -8
- data/CHANGELOG.md +0 -5
- data/Rakefile +0 -12
- data/bin/console +0 -15
- data/bin/setup +0 -8
- data/phlex-rails.gemspec +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6ef3316773401cb9a664f24dfaf751f282bdceafc22db5d5aa59173d96b0794c
|
4
|
+
data.tar.gz: 253849ceeeb4af1c1a3dd673c6e862cb17f8b1c3a13695556ccfc5b8d2855ce0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e3cedfb00ab5762f2ffeeecf66e59a28dd8eac55d44272521c3c4094f0bd66d41d6a64925242cf429678417e87c536d644b3da0ebc0a566900665fb8863e894
|
7
|
+
data.tar.gz: a88ea4826134ece2cda7cfae473e362dc1571822a4e27865e99b695bbdcf5bf2cd4d745334d6a1927a10cd463c7ccac54244af99d7255be6b28a144b5f6020e3
|
data/.editorconfig
ADDED
data/.rubocop.yml
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
inherit_from:
|
2
|
+
- "https://www.goodcop.style/rubocop.yml"
|
3
|
+
- "https://www.goodcop.style/tabs.yml"
|
4
|
+
|
5
|
+
AllCops:
|
6
|
+
TargetRubyVersion: 2.7
|
7
|
+
Exclude:
|
8
|
+
- "lib/phlex-rails.rb"
|
9
|
+
|
10
|
+
Style/PercentLiteralDelimiters:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Layout/CaseIndentation:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/StringConcatenation:
|
17
|
+
Enabled: false
|
18
|
+
|
19
|
+
|
20
|
+
|
21
|
+
Security/Eval:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Style/MethodCallWithoutArgsParentheses:
|
25
|
+
Enabled: false
|
26
|
+
|
27
|
+
Style/MixinUsage:
|
28
|
+
Enabled: false
|
29
|
+
|
30
|
+
Style/ConditionalAssignment:
|
31
|
+
Enabled: false
|
data/Appraisals
ADDED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# Contributing to Phlex
|
2
|
+
|
3
|
+
## Priorities
|
4
|
+
|
5
|
+
We’re trying to provide the best possible developer experience for the people using Phlex in their apps and the best possible performance for the users of those apps.
|
6
|
+
|
7
|
+
Phlex is incredibly complex and requires a lot of meta-programming but when you use it, it feels simple. Phlex views feel like plain old Ruby objects. You just subclass and define a couple of methods. That’s it. That’s how it should be.
|
8
|
+
|
9
|
+
## Setup
|
10
|
+
|
11
|
+
- Install dependencies `bundle install`
|
12
|
+
- Run the tests `bundle exec sus`
|
13
|
+
- Run Rubocop and auto-correct `bundle exec rubocop -A`
|
14
|
+
|
15
|
+
## Tests
|
16
|
+
|
17
|
+
We use the **[Sus](https://github.com/ioquatix/sus)** testing framework. It feels a bit like RSpec with a few small differences. There’s no documentation for Sus at the moment, but you should be able to pick up the basics from reading other tests or looking at the implementation in the Sus repo.
|
18
|
+
|
19
|
+
You can run all the tests with `bundle exec sus`.
|
20
|
+
|
21
|
+
## Documentation
|
22
|
+
|
23
|
+
Documentation is deployed when it’s merged into the `latest` branch with a release. But you can build and preview the docs locally by running `bin/docs`.
|
data/Gemfile
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
source "https://rubygems.org"
|
4
|
+
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
|
4
5
|
|
5
|
-
# Specify your gem's dependencies in phlex-rails.gemspec
|
6
6
|
gemspec
|
7
7
|
|
8
|
-
gem "
|
9
|
-
|
10
|
-
gem "
|
8
|
+
gem "phlex", github: "joeldrapper/phlex"
|
9
|
+
gem "sus"
|
10
|
+
gem "combustion"
|
11
|
+
gem "rubocop"
|
12
|
+
gem "solargraph"
|
13
|
+
gem "appraisal", github: "excid3/appraisal", branch: "fix-bundle-env"
|
data/README.md
CHANGED
@@ -1,43 +1,27 @@
|
|
1
|
-
|
1
|
+
<a href="https://www.phlex.fun"><img alt="Phlex logo" src="phlex_logo.png" width="180" /></a>
|
2
2
|
|
3
|
-
|
3
|
+
Phlex is a framework that lets you compose web views in pure Ruby.
|
4
4
|
|
5
|
-
|
5
|
+
### Documentation 📗
|
6
6
|
|
7
|
-
|
7
|
+
Documentation can be found at [www.phlex.fun](https://www.phlex.fun).
|
8
8
|
|
9
|
-
|
9
|
+
### Support ✋
|
10
10
|
|
11
|
-
|
12
|
-
gem 'phlex-rails'
|
13
|
-
```
|
11
|
+
If you run into any trouble, please [start a discussion](https://github.com/joeldrapper/phlex/discussions/new), or [open an issue](https://github.com/joeldrapper/phlex/issues/new) if you think you’ve found a bug.
|
14
12
|
|
15
|
-
|
13
|
+
### Community 🙌
|
16
14
|
|
17
|
-
|
15
|
+
Everyone interacting in Phlex codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/joeldrapper/phlex/blob/main/CODE_OF_CONDUCT.md).
|
18
16
|
|
19
|
-
|
17
|
+
### Sponsorship 💖
|
20
18
|
|
21
|
-
|
19
|
+
Maintaining a library is a lot of work. If your company benefits from this work or is likely to benefit from it in the future, please consider [sponsorship](https://github.com/sponsors/joeldrapper). Phlex is actively developed and maintained by **[Joel Drapper](https://github.com/sponsors/joeldrapper)**.
|
22
20
|
|
23
|
-
|
21
|
+
### Security 🚨
|
24
22
|
|
25
|
-
|
23
|
+
If you’ve found a potential security issue, please email [security@phlex.fun](mailto:security@phlex.fun).
|
26
24
|
|
27
|
-
|
25
|
+
### Thanks 🙏
|
28
26
|
|
29
|
-
|
30
|
-
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
32
|
-
|
33
|
-
## Contributing
|
34
|
-
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/phlex-rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/phlex-rails/blob/master/CODE_OF_CONDUCT.md).
|
36
|
-
|
37
|
-
## License
|
38
|
-
|
39
|
-
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
40
|
-
|
41
|
-
## Code of Conduct
|
42
|
-
|
43
|
-
Everyone interacting in the Phlex::Rails project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/phlex-rails/blob/master/CODE_OF_CONDUCT.md).
|
27
|
+
Thanks [Logology](https://www.logology.co) for sponsoring our logo.
|
data/SECURITY.md
ADDED
File without changes
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div>
|
2
|
+
<span>
|
3
|
+
<%= @name %>
|
4
|
+
</span>
|
5
|
+
<span>
|
6
|
+
<%= @body %>
|
7
|
+
</span>
|
8
|
+
|
9
|
+
<%= content %>
|
10
|
+
|
11
|
+
<%= render Views::Comments::Reaction.new(emoji: 'hamburger') do |reaction| %>
|
12
|
+
<p>Emoji reaction for a comment from <%= @name %> with body <%= @body %></p>
|
13
|
+
<% end %>
|
14
|
+
</div>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<p>Before</p>
|
2
|
+
|
3
|
+
<%= render(Views::Heading.new) { "Hello World!" } %>
|
4
|
+
|
5
|
+
<%= render Views::Card.new do |a| %>
|
6
|
+
<p>Start Card A</p>
|
7
|
+
<%= a.title "Hello from A" %>
|
8
|
+
<%= render Views::Card.new do |b| %>
|
9
|
+
<p>Start Card B</p>
|
10
|
+
<%= b.title "Hello from B" %>
|
11
|
+
<p>End Card B</p>
|
12
|
+
<% end %>
|
13
|
+
<p>End Card A</p>
|
14
|
+
<% end %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render Views::Articles::Form.new %>
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Views
|
4
|
+
module Comments
|
5
|
+
class Comment < ApplicationView
|
6
|
+
def initialize(name:, body:)
|
7
|
+
@name = name
|
8
|
+
@body = body
|
9
|
+
end
|
10
|
+
|
11
|
+
def template(&block)
|
12
|
+
div {
|
13
|
+
span { @name }
|
14
|
+
span { @body }
|
15
|
+
|
16
|
+
yield_content(&block)
|
17
|
+
|
18
|
+
render(::ReactionComponent.new(emoji: "hamburger")) do
|
19
|
+
p { "Emoji reaction for a comment from #{@name} with body #{@body}" }
|
20
|
+
end
|
21
|
+
}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
*.log
|
File without changes
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ViewHelper
|
4
|
+
def self.extended(parent)
|
5
|
+
parent.class_exec do
|
6
|
+
let(:output) { example.call }
|
7
|
+
let(:example) { view.new }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def view(&block)
|
12
|
+
let :view do
|
13
|
+
Class.new(Phlex::HTML, &block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Phlex
|
4
|
+
module Generators
|
5
|
+
class CollectionGenerator < ::Rails::Generators::NamedBase
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
def create_view
|
9
|
+
template "collection.rb.erb", File.join("app/views", class_path, "#{file_name}.rb")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
module Views
|
3
|
+
class <%= class_name %> < Phlex::HTML
|
4
|
+
include ApplicationView
|
5
|
+
include Phlex::Collection
|
6
|
+
|
7
|
+
def collection_template(&)
|
8
|
+
ul(&)
|
9
|
+
end
|
10
|
+
|
11
|
+
def item_template
|
12
|
+
li { @item }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
<% end %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
Description:
|
2
|
+
Generates a Rails controller with Phlex views for the supplied actions
|
3
|
+
|
4
|
+
Example:
|
5
|
+
rails generate phlex:controller Articles index show
|
6
|
+
|
7
|
+
This will create:
|
8
|
+
app/controllers/articles_controller.rb
|
9
|
+
app/views/articles/index.rb
|
10
|
+
app/views/articles/show.rb
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Phlex
|
4
|
+
module Generators
|
5
|
+
class ControllerGenerator < ::Rails::Generators::NamedBase # :nodoc:
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
argument :actions, type: :array, default: [], banner: "action action"
|
9
|
+
class_option :skip_routes, type: :boolean, desc: "Don't add routes to config/routes.rb."
|
10
|
+
class_option :parent, type: :string, default: "ApplicationController", desc: "The parent class for the generated controller"
|
11
|
+
|
12
|
+
check_class_collision suffix: "Controller"
|
13
|
+
|
14
|
+
def create_controller_files
|
15
|
+
template "controller.rb.erb", File.join("app/controllers", class_path, "#{file_name}_controller.rb")
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_view_files
|
19
|
+
base_path = File.join("app/views", class_path, file_name)
|
20
|
+
empty_directory base_path
|
21
|
+
|
22
|
+
actions.each do |action|
|
23
|
+
Rails::Generators.invoke("phlex:view", [remove_possible_suffix(name) + "/" + action])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_routes
|
28
|
+
return if options[:skip_routes]
|
29
|
+
return if actions.empty?
|
30
|
+
|
31
|
+
routing_code = actions.map { |action| "get '#{file_name}/#{action}'" }.join("\n")
|
32
|
+
route routing_code, namespace: regular_class_path
|
33
|
+
end
|
34
|
+
|
35
|
+
hook_for :test_framework, as: :controller do |generator|
|
36
|
+
invoke generator, [remove_possible_suffix(name), actions]
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def parent_class_name
|
42
|
+
options[:parent]
|
43
|
+
end
|
44
|
+
|
45
|
+
def file_name
|
46
|
+
@_file_name ||= remove_possible_suffix(super)
|
47
|
+
end
|
48
|
+
|
49
|
+
def remove_possible_suffix(name)
|
50
|
+
name.sub(/_?controller$/i, "")
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
class <%= class_name %>Controller < <%= parent_class_name.classify %>
|
3
|
+
<% actions.each do |action| -%>
|
4
|
+
def <%= action %>
|
5
|
+
render Views::<%= class_name %>::<%= action.camelize %>.new
|
6
|
+
end
|
7
|
+
<%= "\n" unless action == actions.last -%>
|
8
|
+
<% end -%>
|
9
|
+
end
|
10
|
+
<% end -%>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
module Views
|
3
|
+
class <%= class_name %>::<%= @action.camelize %> < Phlex::HTML
|
4
|
+
include ApplicationView
|
5
|
+
|
6
|
+
def template
|
7
|
+
<%= "# " unless @has_layout %>render Layout.new(title: "<%= class_name.gsub("::", " ").titlecase %> - <%= @action.titlecase %>") do
|
8
|
+
h1 { "<%= class_name %>#<%= @action %>" }
|
9
|
+
p { "Find me in <%= @path %>" }
|
10
|
+
<%= "# " unless @has_layout %>end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Phlex
|
4
|
+
module Generators
|
5
|
+
class LayoutGenerator < ::Rails::Generators::NamedBase
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
def create_view
|
9
|
+
template "layout.rb.erb", File.join("app/views", class_path, "#{file_name}.rb")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
module Views
|
3
|
+
class <%= class_name %> < Phlex::HTML
|
4
|
+
include ApplicationView
|
5
|
+
include Phlex::Rails::Layout
|
6
|
+
|
7
|
+
def initialize(title:)
|
8
|
+
@title = title
|
9
|
+
end
|
10
|
+
|
11
|
+
def template(&)
|
12
|
+
doctype
|
13
|
+
|
14
|
+
html do
|
15
|
+
head do
|
16
|
+
meta charset: "utf-8"
|
17
|
+
csp_meta_tag
|
18
|
+
csrf_meta_tags
|
19
|
+
meta name: "viewport", content: "width=device-width,initial-scale=1"
|
20
|
+
title { @title }
|
21
|
+
stylesheet_link_tag "application"
|
22
|
+
end
|
23
|
+
|
24
|
+
body do
|
25
|
+
main(&)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
<% end %>
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Phlex
|
4
|
+
module Generators
|
5
|
+
class PageGenerator < ::Rails::Generators::NamedBase
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
7
|
+
|
8
|
+
def create_view
|
9
|
+
template "page.rb.erb", File.join("app/views", class_path, "#{file_name}.rb")
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<% module_namespacing do -%>
|
2
|
+
module Views
|
3
|
+
class <%= class_name %> < Phlex::HTML
|
4
|
+
include ApplicationView
|
5
|
+
|
6
|
+
def template
|
7
|
+
render Layout.new(title: "<%= class_name.gsub("::", " ") %>") do
|
8
|
+
h1 { "👋 Hello World!" }
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
<% end %>
|