Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/add data attr to tag api #31

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 42 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ In your *Gemfile*:
```ruby
gem 'metamagic'
```

Then run `bundle install`.

Examples
Expand Down Expand Up @@ -217,7 +217,7 @@ For custom meta tags, you can use it like this:
meta my_custom_name: "My custom value"
%>
```

This will generate the following:

```html
Expand Down Expand Up @@ -404,6 +404,46 @@ custom key_one: "My first key",
%>
```

### Adding data attributes to tags

All tag types can add data attributes.

```erb
<%
meta title: "My Title",
description: {
value: "content",
data: { "attr-name" => "data attr value" }
}
%>
```

This will render the following:

```html
<title>My Title</title>
<meta name="description" content="content" data-attr-name="data attr value" />
```

Multiple data attributes can be specified:

```erb
<%
meta title: "My Title",
description: {
value: "content",
data: { "attr-name-1" => "one", "attr-name-2" => "two" }
}
%>
```

This will render the following:

```html
<title>My Title</title>
<meta name="description" content="content" data-attr-1="one" data-attr-2="two" />
```

Requirements
------------

Expand Down
3 changes: 2 additions & 1 deletion lib/metamagic.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
%w{
version
value
tag
tags/meta_tag
tags/title_tag
Expand All @@ -12,4 +13,4 @@
view_helper
}.each { |f| require "metamagic/#{f}" }

ActionView::Base.send :include, Metamagic::ViewHelper
ActionView::Base.send :include, Metamagic::ViewHelper
4 changes: 2 additions & 2 deletions lib/metamagic/renderer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,12 @@ def transform_hash(hash, path = "")
hash.each_with_object({}) do |(k, v), ret|
key = path + k.to_s

if v.is_a?(Hash)
if v.is_a?(Hash) && !v.key?(:value)
ret.merge! transform_hash(v, "#{key}:")
else
ret[key] = v
end
end
end
end
end
end
6 changes: 4 additions & 2 deletions lib/metamagic/tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def interpolated_values
else
raise "Unknown template type #{template.class}."
end
end.flatten.compact.uniq.map { |value| ERB::Util.html_escape(value) }
end.flatten.compact.uniq.map do |value|
Metamagic::Value.create_escaped(value)
end
end

def ==(other)
Expand All @@ -53,4 +55,4 @@ def method_missing(method, *args, &block)
context.send(method, *args, &block)
end
end
end
end
17 changes: 15 additions & 2 deletions lib/metamagic/tags/custom_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,20 @@ def remove_prefix?
end

def to_html
instance_exec key, interpolated_values, &render_proc
if render_proc.arity == 2
instance_exec(
key,
interpolated_values.map(&:value),
&render_proc
)
else
instance_exec(
key,
interpolated_values.map(&:value),
interpolated_values.first.data,
&render_proc
)
end
end
end
end
end
15 changes: 13 additions & 2 deletions lib/metamagic/tags/link_tag.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
module Metamagic
class LinkTag < Tag
def to_html
interpolated_values.map { |value| tag(:link, rel: key, href: value) }.join("\n").html_safe.presence
interpolated_values.map do |value|
options = {
rel: key,
href: value.value,
data: value.data
}.compact

tag(:link, **options)
end
.join("\n")
.html_safe
.presence
end
end
end
end
11 changes: 9 additions & 2 deletions lib/metamagic/tags/meta_tag.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@ module Metamagic
class MetaTag < Tag
def to_html
return if interpolated_values.empty?
tag(:meta, name: key, content: interpolated_values.join(", ").html_safe)

options = {
name: key,
content: interpolated_values.map(&:value).join(", ").html_safe,
data: interpolated_values.first.data
}.compact

tag(:meta, **options)
end

def sort_order
Expand All @@ -13,4 +20,4 @@ def remove_prefix?
false
end
end
end
end
15 changes: 13 additions & 2 deletions lib/metamagic/tags/property_tag.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
module Metamagic
class PropertyTag < Tag
def to_html
interpolated_values.map { |value| tag(:meta, property: key, content: value) }.join("\n").html_safe.presence
interpolated_values.map do |value|
options = {
property: key,
content: value.value,
data: value.data
}.compact

tag(:meta, **options)
end
.join("\n")
.html_safe
.presence
end

def sort_order
3
end
end
end
end
6 changes: 4 additions & 2 deletions lib/metamagic/tags/title_tag.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
module Metamagic
class TitleTag < Tag
def to_html
content_tag(:title, interpolated_values.join(separator).html_safe) if interpolated_values.any?
values = interpolated_values.map(&:value).join(separator).html_safe

content_tag(:title, values) if values.length > 0
end

def sort_order
1
end
end
end
end
46 changes: 46 additions & 0 deletions lib/metamagic/value.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
module Metamagic
class Value
def self.create_escaped(value)
value.is_a?(Hash) ? ValueHash.new(value) : ValueString.new(value)
end

def escape(string)
ERB::Util.html_escape(string)
end
end

class ValueString < Value
attr_reader :value
def initialize(value)
@value = escape(value)
end

def data
nil
end
end

class ValueHash < Value
attr_reader :value_hash
def initialize(value_hash)
@value_hash = value_hash
@value_hash[:value] = if value.is_a?(Array)
value.map { |v| escape(v) }
else
escape(value)
end

if @value_hash.key?(:data)
@value_hash[:data] = data.map { |k, v| [escape(k), escape(v)] }.to_h
end
end

def value
value_hash[:value]
end

def data
value_hash[:data]
end
end
end
2 changes: 1 addition & 1 deletion test/custom_tag_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ class CustomTagTest < ActionView::TestCase
assert_equal %{<title>Test Title</title>\n<custom_tag one="custom:first" two="This is the first" />\n<custom_tag one="custom:second" two="This is the second" />},
metamagic
end
end
end
112 changes: 112 additions & 0 deletions test/data_attribute_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
require 'test_helper'

class DataAttributeTest < ActionView::TestCase
include Metamagic::ViewHelper

test "title" do
meta title: {
value: "Test Title",
data: { "test-attr" => "title" }
}

assert_equal_segment %{<title data-test-attr="title">Test Title</title>},
metamagic
end

test "title with multiple data attrs" do
meta title: {
value: "Test Title",
data: { "test-attr-1" => "one", "test-attr-2" => "two" }
}

assert_equal_segment %{<title data-test-1="one" data-test-2="two">Test Title</title>},
metamagic
end

test "title with data attr api and no data attribute specified" do
meta title: { value: "Test Title" }

assert_equal_segment %{<title>Test Title</title>},
metamagic
end

test "link rel with data attr" do
meta rel: {
author: {
value: "http://test.com/author.html",
data: { "test-attr" => "test" }
}
}
rel publisher: {
value: "http://test.com/publisher.html",
data: { "test-attr" => "test" }
}

assert_equal_segment %{<link href="http://test.com/author.html" rel="author" data-test-attr="test"/>\n<link href="http://test.com/publisher.html" rel="publisher" data-test-attr="test"/>},
metamagic
end

test "twitter tag with data attribute" do
meta title: "Test Title",
twitter: {
card: {
value: :summary,
data: { "test-attr" => "test" }
}
}
twitter site: {
value: "@flickr",
data: { "test-attr" => "test" }
}

assert_equal_segment %{<title>Test Title</title>\n<meta content="summary" name="twitter:card" data-test-attr="test" />\n<meta content="@flickr" name="twitter:site" data-test-attr="test" />},
metamagic
end

test "meta tags with data attr" do
meta keywords: {
value: %w{one two three},
data: { "test-attr" => "test" }
},
description: {
value: "My description",
data: { "test-attr" => "test" }
}

assert_equal_segment %{<meta content="one, two, three" name="keywords" data-test-attr="test" />\n<meta content="My description" name="description" data-test-attr="test" />},
metamagic
end

test "open graph tags with data attr" do
meta og: {
image: {
url: {
value: "http://test.com/image.jpg",
data: { "test-attr" => "test" }
}
}
}

assert_equal_segment %{<meta content="http://test.com/image.jpg" property="og:image:url" data-test-attr="test" />},
metamagic
end

test "custom tags with data attr" do
Metamagic::Renderer.register_tag_type :custom, ->(key, value, data) { tag(:custom_tag, one: key, two: value, data: data) }

meta title: "Test Title",
custom: {
first: {
value: "This is the first",
data: { "test-attr" => "test" }
},
second: {
value: "This is the second",
data: { "test-attr" => "test" }
}
}

assert_equal %{<title>Test Title</title>\n<custom_tag one="custom:first" two="This is the first" data-test-attr="test" />\n<custom_tag one="custom:second" two="This is the second" data-test-attr="test" />},
metamagic
end
end
Loading