custom_tag 0.1.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +340 -0
- data/.standard.yml +4 -0
- data/CHANGELOG.md +12 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +73 -0
- data/README.md +84 -7
- data/Rakefile +5 -2
- data/custom_tag.gemspec +3 -3
- data/lib/custom_tag/base.rb +42 -0
- data/lib/custom_tag/middleware.rb +15 -0
- data/lib/custom_tag/railties.rb +9 -0
- data/lib/custom_tag/version.rb +1 -1
- data/lib/custom_tag.rb +14 -1
- metadata +24 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a68c2e4baf5565bf8e4dacaf83246217ee69e1e7ed17d906eabd7f68f9410832
|
4
|
+
data.tar.gz: 7c51503bb18ec0d03a8f1c89b02fc1c61cc683ff59ef67469b2d688f7ef4aa66
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f1d41257b2e1401a9aae3d03a47cdba10c710993c06e97e35d2d0f9417fc89f36083fcc8e74ccf0bd3194fed7be734d69ec993996765ecfbdb48c9627314bef
|
7
|
+
data.tar.gz: c9d43398388f799275dd4754146bda6ad5793d83e66c3fef85257753bc468c6e219329feaf7c55d34675c042b6ec913e9f4dbc8ac47cdb833a9b98e83dbadce8
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,340 @@
|
|
1
|
+
require:
|
2
|
+
- rubocop-performance
|
3
|
+
|
4
|
+
AllCops:
|
5
|
+
SuggestExtensions: false
|
6
|
+
NewCops: enable
|
7
|
+
Exclude:
|
8
|
+
- 'db/**/*'
|
9
|
+
- 'config/**/*'
|
10
|
+
- 'script/**/*'
|
11
|
+
- 'node_modules/**/*'
|
12
|
+
- 'doc/**/*'
|
13
|
+
- 'bin/**/*'
|
14
|
+
- 'Gemfile'
|
15
|
+
- 'Rakefile'
|
16
|
+
- 'app/views/sitemap/index.xml.builder'
|
17
|
+
- 'Guardfile'
|
18
|
+
- 'spec/**/*.rb'
|
19
|
+
- vendor/bundle/**/*
|
20
|
+
Performance:
|
21
|
+
Exclude:
|
22
|
+
- 'spec/**/*'
|
23
|
+
Style/FormatStringToken:
|
24
|
+
EnforcedStyle: unannotated
|
25
|
+
Style/FetchEnvVar:
|
26
|
+
Enabled: false
|
27
|
+
Style/StringChars:
|
28
|
+
Enabled: false
|
29
|
+
Naming/BlockForwarding:
|
30
|
+
EnforcedStyle: explicit
|
31
|
+
Metrics/ClassLength:
|
32
|
+
Enabled: false
|
33
|
+
Naming/MethodParameterName:
|
34
|
+
Enabled: false
|
35
|
+
Lint/SuppressedException:
|
36
|
+
Enabled: false
|
37
|
+
Metrics/ParameterLists:
|
38
|
+
Enabled: false
|
39
|
+
Metrics/BlockNesting:
|
40
|
+
Enabled: false
|
41
|
+
Metrics/BlockLength:
|
42
|
+
Enabled: false
|
43
|
+
Metrics/ModuleLength:
|
44
|
+
Enabled: false
|
45
|
+
Metrics/CyclomaticComplexity:
|
46
|
+
Enabled: false
|
47
|
+
Metrics/PerceivedComplexity:
|
48
|
+
Enabled: false
|
49
|
+
Metrics/MethodLength:
|
50
|
+
Enabled: false
|
51
|
+
Layout/HashAlignment:
|
52
|
+
Enabled: false
|
53
|
+
Layout/ArgumentAlignment:
|
54
|
+
Enabled: false
|
55
|
+
Layout/LineLength:
|
56
|
+
Enabled: false
|
57
|
+
Layout/SpaceAroundMethodCallOperator:
|
58
|
+
Enabled: true
|
59
|
+
Lint/RaiseException:
|
60
|
+
Enabled: true
|
61
|
+
Lint/StructNewOverride:
|
62
|
+
Enabled: true
|
63
|
+
Style/ExponentialNotation:
|
64
|
+
Enabled: true
|
65
|
+
Style/ClassVars:
|
66
|
+
Enabled: false
|
67
|
+
Style/HashEachMethods:
|
68
|
+
Enabled: true
|
69
|
+
Style/Documentation:
|
70
|
+
Enabled: false
|
71
|
+
Bundler/OrderedGems:
|
72
|
+
Enabled: false
|
73
|
+
Style/FrozenStringLiteralComment:
|
74
|
+
Enabled: false
|
75
|
+
Style/TrailingCommaInHashLiteral:
|
76
|
+
Enabled: false
|
77
|
+
Layout/SpaceBeforeSemicolon:
|
78
|
+
Enabled: false
|
79
|
+
Style/ClassAndModuleChildren:
|
80
|
+
Enabled: false
|
81
|
+
Metrics/AbcSize:
|
82
|
+
Enabled: false
|
83
|
+
Lint/RescueException:
|
84
|
+
Enabled: false
|
85
|
+
Layout/MultilineMethodCallIndentation:
|
86
|
+
Enabled: false
|
87
|
+
|
88
|
+
# Prefer &&/|| over and/or.
|
89
|
+
Style/AndOr:
|
90
|
+
Enabled: true
|
91
|
+
|
92
|
+
Style/FormatString:
|
93
|
+
EnforcedStyle: percent
|
94
|
+
|
95
|
+
# Align `when` with `case`.
|
96
|
+
Layout/CaseIndentation:
|
97
|
+
Enabled: false
|
98
|
+
|
99
|
+
Layout/ClosingHeredocIndentation:
|
100
|
+
Enabled: true
|
101
|
+
|
102
|
+
# Align comments with method definitions.
|
103
|
+
Layout/CommentIndentation:
|
104
|
+
Enabled: true
|
105
|
+
|
106
|
+
Layout/ElseAlignment:
|
107
|
+
Enabled: true
|
108
|
+
|
109
|
+
Style/RedundantRegexpEscape:
|
110
|
+
Enabled: false
|
111
|
+
|
112
|
+
Style/RaiseArgs:
|
113
|
+
EnforcedStyle: compact
|
114
|
+
|
115
|
+
# Align `end` with the matching keyword or starting expression except for
|
116
|
+
# assignments, where it should be aligned with the LHS.
|
117
|
+
Layout/EndAlignment:
|
118
|
+
Enabled: true
|
119
|
+
EnforcedStyleAlignWith: variable
|
120
|
+
AutoCorrect: true
|
121
|
+
|
122
|
+
Layout/EmptyLineAfterMagicComment:
|
123
|
+
Enabled: true
|
124
|
+
|
125
|
+
Layout/EmptyLinesAroundAccessModifier:
|
126
|
+
Enabled: false
|
127
|
+
|
128
|
+
Layout/EmptyLinesAroundBlockBody:
|
129
|
+
Enabled: true
|
130
|
+
|
131
|
+
# In a regular class definition, no empty lines around the body.
|
132
|
+
Layout/EmptyLinesAroundClassBody:
|
133
|
+
Enabled: true
|
134
|
+
|
135
|
+
# In a regular method definition, no empty lines around the body.
|
136
|
+
Layout/EmptyLinesAroundMethodBody:
|
137
|
+
Enabled: true
|
138
|
+
|
139
|
+
# In a regular module definition, no empty lines around the body.
|
140
|
+
Layout/EmptyLinesAroundModuleBody:
|
141
|
+
Enabled: true
|
142
|
+
|
143
|
+
# Use Ruby >= 1.9 syntax for hashes. Prefer { a: :b } over { :a => :b }.
|
144
|
+
Style/HashSyntax:
|
145
|
+
Enabled: true
|
146
|
+
EnforcedShorthandSyntax: never
|
147
|
+
|
148
|
+
Layout/FirstArgumentIndentation:
|
149
|
+
Enabled: true
|
150
|
+
|
151
|
+
Style/RescueModifier:
|
152
|
+
Enabled: false
|
153
|
+
|
154
|
+
# Method definitions after `private` or `protected` isolated calls need one
|
155
|
+
# extra level of indentation.
|
156
|
+
Layout/IndentationConsistency:
|
157
|
+
Enabled: false
|
158
|
+
|
159
|
+
# Two spaces, no tabs (for indentation).
|
160
|
+
Layout/IndentationWidth:
|
161
|
+
Enabled: true
|
162
|
+
|
163
|
+
Layout/LeadingCommentSpace:
|
164
|
+
Enabled: true
|
165
|
+
|
166
|
+
Layout/SpaceAfterColon:
|
167
|
+
Enabled: true
|
168
|
+
|
169
|
+
Layout/SpaceAfterComma:
|
170
|
+
Enabled: true
|
171
|
+
|
172
|
+
Layout/SpaceAfterSemicolon:
|
173
|
+
Enabled: true
|
174
|
+
|
175
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
176
|
+
Enabled: true
|
177
|
+
|
178
|
+
Layout/SpaceAroundKeyword:
|
179
|
+
Enabled: true
|
180
|
+
|
181
|
+
Layout/SpaceBeforeComma:
|
182
|
+
Enabled: true
|
183
|
+
|
184
|
+
Layout/SpaceBeforeComment:
|
185
|
+
Enabled: true
|
186
|
+
|
187
|
+
Layout/SpaceBeforeFirstArg:
|
188
|
+
Enabled: true
|
189
|
+
|
190
|
+
Style/DefWithParentheses:
|
191
|
+
Enabled: true
|
192
|
+
|
193
|
+
Style/MethodDefParentheses:
|
194
|
+
Enabled: true
|
195
|
+
|
196
|
+
Style/RedundantFreeze:
|
197
|
+
Enabled: true
|
198
|
+
|
199
|
+
# Use `foo {}` not `foo{}`.
|
200
|
+
Layout/SpaceBeforeBlockBraces:
|
201
|
+
Enabled: true
|
202
|
+
|
203
|
+
# Use `foo { bar }` not `foo {bar}`.
|
204
|
+
Layout/SpaceInsideBlockBraces:
|
205
|
+
Enabled: true
|
206
|
+
EnforcedStyleForEmptyBraces: space
|
207
|
+
|
208
|
+
# Use `{ a: 1 }` not `{a:1}`.
|
209
|
+
Layout/SpaceInsideHashLiteralBraces:
|
210
|
+
Enabled: true
|
211
|
+
|
212
|
+
Layout/SpaceInsideParens:
|
213
|
+
Enabled: true
|
214
|
+
|
215
|
+
# Check quotes usage according to lint rule below.
|
216
|
+
Style/StringLiterals:
|
217
|
+
Enabled: true
|
218
|
+
EnforcedStyle: double_quotes
|
219
|
+
SupportedStyles:
|
220
|
+
- single_quotes
|
221
|
+
- double_quotes
|
222
|
+
|
223
|
+
Style/StringLiteralsInInterpolation:
|
224
|
+
Enabled: false
|
225
|
+
|
226
|
+
Style/HashLikeCase:
|
227
|
+
Enabled: false
|
228
|
+
|
229
|
+
Style/IfUnlessModifier:
|
230
|
+
Enabled: false
|
231
|
+
|
232
|
+
# Detect hard tabs, no hard tabs.
|
233
|
+
Layout/IndentationStyle:
|
234
|
+
Enabled: true
|
235
|
+
|
236
|
+
# Empty lines should not have any spaces.
|
237
|
+
Layout/TrailingEmptyLines:
|
238
|
+
Enabled: true
|
239
|
+
|
240
|
+
# No trailing whitespace.
|
241
|
+
Layout/TrailingWhitespace:
|
242
|
+
Enabled: true
|
243
|
+
|
244
|
+
# Use quotes for string literals when they are enough.
|
245
|
+
Style/RedundantPercentQ:
|
246
|
+
Enabled: true
|
247
|
+
|
248
|
+
Lint/AmbiguousOperator:
|
249
|
+
Enabled: true
|
250
|
+
|
251
|
+
Lint/AmbiguousRegexpLiteral:
|
252
|
+
Enabled: true
|
253
|
+
|
254
|
+
Lint/ErbNewArguments:
|
255
|
+
Enabled: true
|
256
|
+
|
257
|
+
Lint/ParenthesesAsGroupedExpression:
|
258
|
+
Enabled: false
|
259
|
+
|
260
|
+
# Use my_method(my_arg) not my_method( my_arg ) or my_method my_arg.
|
261
|
+
Lint/RequireParentheses:
|
262
|
+
Enabled: true
|
263
|
+
|
264
|
+
Lint/ShadowingOuterLocalVariable:
|
265
|
+
Enabled: true
|
266
|
+
|
267
|
+
Lint/RedundantStringCoercion:
|
268
|
+
Enabled: true
|
269
|
+
|
270
|
+
Lint/UriEscapeUnescape:
|
271
|
+
Enabled: true
|
272
|
+
|
273
|
+
Lint/UselessAssignment:
|
274
|
+
Enabled: true
|
275
|
+
|
276
|
+
Lint/DeprecatedClassMethods:
|
277
|
+
Enabled: true
|
278
|
+
|
279
|
+
Style/GuardClause:
|
280
|
+
Enabled: false
|
281
|
+
|
282
|
+
Style/ParenthesesAroundCondition:
|
283
|
+
Enabled: true
|
284
|
+
|
285
|
+
Style/HashTransformKeys:
|
286
|
+
Enabled: true
|
287
|
+
|
288
|
+
Style/HashTransformValues:
|
289
|
+
Enabled: true
|
290
|
+
|
291
|
+
Style/RedundantBegin:
|
292
|
+
Enabled: true
|
293
|
+
|
294
|
+
Style/RedundantReturn:
|
295
|
+
Enabled: true
|
296
|
+
AllowMultipleReturnValues: true
|
297
|
+
|
298
|
+
Style/Semicolon:
|
299
|
+
Enabled: true
|
300
|
+
AllowAsExpressionSeparator: true
|
301
|
+
|
302
|
+
# Prefer Foo.method over Foo::method
|
303
|
+
Style/ColonMethodCall:
|
304
|
+
Enabled: true
|
305
|
+
|
306
|
+
Style/TrivialAccessors:
|
307
|
+
Enabled: true
|
308
|
+
|
309
|
+
Style/BarePercentLiterals:
|
310
|
+
Enabled: false
|
311
|
+
|
312
|
+
Performance/FlatMap:
|
313
|
+
Enabled: true
|
314
|
+
|
315
|
+
Performance/RedundantMerge:
|
316
|
+
Enabled: true
|
317
|
+
|
318
|
+
Performance/StartWith:
|
319
|
+
Enabled: true
|
320
|
+
|
321
|
+
Performance/EndWith:
|
322
|
+
Enabled: true
|
323
|
+
|
324
|
+
Performance/RegexpMatch:
|
325
|
+
Enabled: true
|
326
|
+
|
327
|
+
Performance/ReverseEach:
|
328
|
+
Enabled: true
|
329
|
+
|
330
|
+
Performance/UnfreezeString:
|
331
|
+
Enabled: true
|
332
|
+
|
333
|
+
Style/IfInsideElse:
|
334
|
+
Enabled: false
|
335
|
+
|
336
|
+
Style/RegexpLiteral:
|
337
|
+
Enabled: false
|
338
|
+
|
339
|
+
Style/ParallelAssignment:
|
340
|
+
Enabled: false
|
data/.standard.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1 +1,13 @@
|
|
1
1
|
# CHANGELOG for CustomTag
|
2
|
+
|
3
|
+
## 0.3.0 - 16 August 2023
|
4
|
+
|
5
|
+
Configured Railtie to correctly use Rack middleware.
|
6
|
+
|
7
|
+
## 0.2.0 - 9 July 2023
|
8
|
+
|
9
|
+
Rack middleware implemented and documentation written.
|
10
|
+
|
11
|
+
## 0.1.0 - 3 July 2023
|
12
|
+
|
13
|
+
Basics of this gem working, need to implement the Rack middleware, but the core replacement code is working.
|
data/Gemfile
CHANGED
data/Gemfile.lock
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
custom_tag (0.2.0)
|
5
|
+
nokogiri
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
ast (2.4.2)
|
11
|
+
diff-lcs (1.5.0)
|
12
|
+
json (2.6.3)
|
13
|
+
nokogiri (1.15.2-arm64-darwin)
|
14
|
+
racc (~> 1.4)
|
15
|
+
nokogiri (1.15.2-x86_64-linux)
|
16
|
+
racc (~> 1.4)
|
17
|
+
parallel (1.23.0)
|
18
|
+
parser (3.2.2.1)
|
19
|
+
ast (~> 2.4.1)
|
20
|
+
racc (1.6.2)
|
21
|
+
rack (3.0.8)
|
22
|
+
rainbow (3.1.1)
|
23
|
+
rake (13.0.6)
|
24
|
+
regexp_parser (2.8.0)
|
25
|
+
rexml (3.2.5)
|
26
|
+
rspec (3.12.0)
|
27
|
+
rspec-core (~> 3.12.0)
|
28
|
+
rspec-expectations (~> 3.12.0)
|
29
|
+
rspec-mocks (~> 3.12.0)
|
30
|
+
rspec-core (3.12.2)
|
31
|
+
rspec-support (~> 3.12.0)
|
32
|
+
rspec-expectations (3.12.3)
|
33
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
34
|
+
rspec-support (~> 3.12.0)
|
35
|
+
rspec-mocks (3.12.5)
|
36
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
37
|
+
rspec-support (~> 3.12.0)
|
38
|
+
rspec-support (3.12.0)
|
39
|
+
rubocop (1.52.0)
|
40
|
+
json (~> 2.3)
|
41
|
+
parallel (~> 1.10)
|
42
|
+
parser (>= 3.2.0.0)
|
43
|
+
rainbow (>= 2.2.2, < 4.0)
|
44
|
+
regexp_parser (>= 1.8, < 3.0)
|
45
|
+
rexml (>= 3.2.5, < 4.0)
|
46
|
+
rubocop-ast (>= 1.28.0, < 2.0)
|
47
|
+
ruby-progressbar (~> 1.7)
|
48
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
49
|
+
rubocop-ast (1.29.0)
|
50
|
+
parser (>= 3.2.1.0)
|
51
|
+
rubocop-performance (1.18.0)
|
52
|
+
rubocop (>= 1.7.0, < 2.0)
|
53
|
+
rubocop-ast (>= 0.4.0)
|
54
|
+
rubocop-rake (0.6.0)
|
55
|
+
rubocop (~> 1.0)
|
56
|
+
ruby-progressbar (1.13.0)
|
57
|
+
unicode-display_width (2.4.2)
|
58
|
+
|
59
|
+
PLATFORMS
|
60
|
+
arm64-darwin-22
|
61
|
+
x86_64-linux
|
62
|
+
|
63
|
+
DEPENDENCIES
|
64
|
+
custom_tag!
|
65
|
+
rack
|
66
|
+
rake (~> 13.0)
|
67
|
+
rspec (~> 3.0)
|
68
|
+
rubocop
|
69
|
+
rubocop-performance
|
70
|
+
rubocop-rake
|
71
|
+
|
72
|
+
BUNDLED WITH
|
73
|
+
2.4.6
|
data/README.md
CHANGED
@@ -1,6 +1,83 @@
|
|
1
1
|
# CustomTag
|
2
2
|
|
3
|
-
> CustomTag allows you to use custom HTML tags in your Rails project and have them be replaced with standard HTML tags and attributes.
|
3
|
+
> CustomTag allows you to use custom HTML tags in your Rails project and have them be replaced with standard HTML tags and attributes. Brought on by jealousy of extracting TailwindCSS classes to simple components in frontend frameworks.
|
4
|
+
|
5
|
+
## Usage
|
6
|
+
|
7
|
+
This gem allows you write custom HTML tags in your HTML output and have them replaced with other tags. For example you could do the following:
|
8
|
+
|
9
|
+
```html
|
10
|
+
<my-card>
|
11
|
+
<h3>Your name here</h3>
|
12
|
+
<div>Job title</div>
|
13
|
+
</my-card>
|
14
|
+
```
|
15
|
+
|
16
|
+
And it can be replaced with:
|
17
|
+
|
18
|
+
```html
|
19
|
+
<div class="p-4 bg-white border border-gray-200 shadow-lg">
|
20
|
+
<h3>Your name here</h3>
|
21
|
+
<div>Job title</div>
|
22
|
+
</div>
|
23
|
+
```
|
24
|
+
|
25
|
+
This keeps your TailwindCSS classes from being repeated all over your codebase, while not using `@apply` (<https://tailwindcss.com/docs/reusing-styles>). It's a middleground between full template systems like [Phlex](https://github.com/phlex-ruby/phlex) and [ViewComponent](https://viewcomponent.org) and just having lists of classes everywhere.
|
26
|
+
|
27
|
+
### Defining your tags
|
28
|
+
|
29
|
+
To define your tags is nice and easy. Have one or more classes that are loaded early (maybe in `config/initializers` in Rails, or directly required if you're using Sinatra or some other lightweight framework) that define the tags you're creating, and how to replace the matching content with HTML. For example, to define a class that performs a single replacement, you could do:
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
class MyCard < CustomTag::Base
|
33
|
+
register :my_card, self
|
34
|
+
|
35
|
+
def self.build(_, attrs, content)
|
36
|
+
attrs["class"] = "p-4 bg-white border border-gray-200 shadow-lg #{attrs["class"]}".strip
|
37
|
+
super("div", attrs, content)
|
38
|
+
# The super will simply build an HTML tag from the details given
|
39
|
+
end
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
You can call the `register` method with any of `under_scored`, `hyphen-ated` or `CamelCased` tags names and it will automatically convert between them to accept any one of them as the same thing.
|
44
|
+
|
45
|
+
If you wish you can have multiple tags defined in a single class and use the first parameters of `build` to distinguish between them:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
class ApplicationCustomTags < CustomTag::Base
|
49
|
+
register :my_card, self
|
50
|
+
|
51
|
+
def self.build(tag_name, attrs, content)
|
52
|
+
case tag_name
|
53
|
+
when "my_card"
|
54
|
+
my_card(attrs, content)
|
55
|
+
when "..."
|
56
|
+
# ...
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.my_card(attrs,content)
|
61
|
+
attrs["class"] = "p-4 bg-white border border-gray-200 shadow-lg #{attrs["class"]}".strip
|
62
|
+
"<div #{attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")}>#{content}</div>"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
### Middleware
|
68
|
+
|
69
|
+
If you're using Rails, the CustomTag Middleware will be automatically registered for you as the last middleware to be called. If you want to use it yourself in a non-Rails app, you can use it like this:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
require 'sinatra'
|
73
|
+
require 'custom_tag'
|
74
|
+
|
75
|
+
use CustomTag::Middleware
|
76
|
+
|
77
|
+
get '/hello' do
|
78
|
+
'<some HTML here... />'
|
79
|
+
end
|
80
|
+
```
|
4
81
|
|
5
82
|
## Installation
|
6
83
|
|
@@ -8,19 +85,19 @@ Install the gem and add to the application's Gemfile by executing:
|
|
8
85
|
|
9
86
|
bundle add custom_tag
|
10
87
|
|
88
|
+
Or adding `gem "custom_tag"` to your `Gemfile` and running `bundle install`.
|
89
|
+
|
11
90
|
If bundler is not being used to manage dependencies, install the gem by executing:
|
12
91
|
|
13
92
|
gem install custom_tag
|
14
93
|
|
15
|
-
## Usage
|
16
|
-
|
17
|
-
TODO: Write usage instructions here
|
18
|
-
|
19
94
|
## Development
|
20
95
|
|
21
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
96
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bundle exec rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
97
|
+
|
98
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
22
99
|
|
23
|
-
To
|
100
|
+
To release a new version, update the version number in `version.rb`, edit the `CHANGELOG.md` file to explain the new release 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).
|
24
101
|
|
25
102
|
## Contributing
|
26
103
|
|
data/Rakefile
CHANGED
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
require "rspec/core/rake_task"
|
5
|
+
require "rubocop/rake_task"
|
5
6
|
|
6
7
|
RSpec::Core::RakeTask.new(:spec)
|
7
8
|
|
8
|
-
|
9
|
+
task default: %i[spec rubocop]
|
9
10
|
|
10
|
-
|
11
|
+
RuboCop::RakeTask.new do |task|
|
12
|
+
task.requires << 'rubocop-rake'
|
13
|
+
end
|
data/custom_tag.gemspec
CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
spec.summary = "CustomTag allows you to use custom HTML tags in your Rails project and have them be replaced with standard HTML tags and attributes"
|
12
12
|
spec.description = "Jealous of custom <tags> in JS frameworks and want them in your Rails apps? CustomTag allows you to use custom HTML tags in your Rails project and have them be replaced with standard HTML tags and attributes."
|
13
13
|
spec.homepage = "https://github.com/andyjeffries/customtag"
|
14
|
-
spec.required_ruby_version = ">= 2.
|
14
|
+
spec.required_ruby_version = ">= 2.7.0"
|
15
15
|
|
16
16
|
# spec.metadata["allowed_push_host"] = "TODO: Set to your gem server 'https://example.com'"
|
17
17
|
|
@@ -30,9 +30,9 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ["lib"]
|
32
32
|
|
33
|
-
|
34
|
-
# spec.add_dependency "example-gem", "~> 1.0"
|
33
|
+
spec.add_dependency "nokogiri"
|
35
34
|
|
36
35
|
# For more information and examples about making a new gem, check out our
|
37
36
|
# guide at: https://bundler.io/guides/creating_gem.html
|
37
|
+
spec.metadata["rubygems_mfa_required"] = "true"
|
38
38
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module CustomTag
|
2
|
+
class Base
|
3
|
+
@@tags = {}
|
4
|
+
|
5
|
+
def self.register(tag_name, klass)
|
6
|
+
@@tags[tag_name.to_s] = klass
|
7
|
+
@@tags[tag_name.to_s.gsub(/([A-Z])/) { |m| "_#{m.downcase}" }] = klass
|
8
|
+
@@tags[tag_name.to_s.gsub(/([A-Z])/) { |m| "-#{m.downcase}" }] = klass
|
9
|
+
@@tags[tag_name.to_s.tr("_", "-").downcase] = klass
|
10
|
+
@@tags[tag_name.to_s.gsub(/_([a-z])/) { |m| m[1].upcase }] = klass
|
11
|
+
@@tags[tag_name.to_s.tr("-", "_").downcase] = klass
|
12
|
+
@@tags[tag_name.to_s.gsub(/-([a-z])/) { |m| m[1].upcase }] = klass
|
13
|
+
@@tags[tag_name.to_s.delete("-").downcase] = klass
|
14
|
+
@@tags[tag_name.to_s.delete("_").downcase] = klass
|
15
|
+
@@tags[tag_name.to_s.downcase] = klass
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.tags
|
19
|
+
@@tags
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.replace(tag_name, attrs, content)
|
23
|
+
ret = if @@tags[tag_name]
|
24
|
+
@@tags[tag_name].build(tag_name, attrs, content)
|
25
|
+
else
|
26
|
+
build(tag_name, attrs, content)
|
27
|
+
end
|
28
|
+
|
29
|
+
doc = Nokogiri::XML.fragment(ret)
|
30
|
+
doc.search("*").each do |element|
|
31
|
+
if CustomTag::Base.tags[element.name]
|
32
|
+
element.replace(CustomTag::Base.replace(element.name, element.attributes, element.content))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
doc.to_html.strip
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.build(tag_name, attrs, content)
|
39
|
+
"<#{tag_name} #{attrs.map { |k, v| "#{k}=\"#{v}\"" }.join(" ")}>#{content}</#{tag_name}>"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module CustomTag
|
2
|
+
class Middleware
|
3
|
+
def initialize(app)
|
4
|
+
@app = app
|
5
|
+
end
|
6
|
+
|
7
|
+
def call(env)
|
8
|
+
code, headers, response = @app.call(env)
|
9
|
+
|
10
|
+
response[0] = CustomTag.parse_and_replace(response[0]) if headers["Content-Type"]&.include?("text/html")
|
11
|
+
|
12
|
+
[code, headers, response]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
data/lib/custom_tag/version.rb
CHANGED
data/lib/custom_tag.rb
CHANGED
@@ -1,8 +1,21 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "nokogiri"
|
3
4
|
require_relative "custom_tag/version"
|
5
|
+
require_relative "custom_tag/base"
|
6
|
+
require_relative "custom_tag/middleware"
|
7
|
+
require_relative "custom_tag/railties"
|
4
8
|
|
5
9
|
module CustomTag
|
6
10
|
class Error < StandardError; end
|
7
|
-
|
11
|
+
|
12
|
+
def self.parse_and_replace(content)
|
13
|
+
doc = Nokogiri::HTML.parse(content)
|
14
|
+
doc.search("*").each do |element|
|
15
|
+
if CustomTag::Base.tags[element.name]
|
16
|
+
element.replace(CustomTag::Base.replace(element.name, element.attributes, element.children.to_html))
|
17
|
+
end
|
18
|
+
end
|
19
|
+
doc.to_html(save_with: 0)
|
20
|
+
end
|
8
21
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: custom_tag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andy Jeffries
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
12
|
-
dependencies:
|
11
|
+
date: 2023-08-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: nokogiri
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: Jealous of custom <tags> in JS frameworks and want them in your Rails
|
14
28
|
apps? CustomTag allows you to use custom HTML tags in your Rails project and have
|
15
29
|
them be replaced with standard HTML tags and attributes.
|
@@ -20,13 +34,18 @@ extensions: []
|
|
20
34
|
extra_rdoc_files: []
|
21
35
|
files:
|
22
36
|
- ".rspec"
|
37
|
+
- ".rubocop.yml"
|
23
38
|
- ".standard.yml"
|
24
39
|
- CHANGELOG.md
|
25
40
|
- Gemfile
|
41
|
+
- Gemfile.lock
|
26
42
|
- README.md
|
27
43
|
- Rakefile
|
28
44
|
- custom_tag.gemspec
|
29
45
|
- lib/custom_tag.rb
|
46
|
+
- lib/custom_tag/base.rb
|
47
|
+
- lib/custom_tag/middleware.rb
|
48
|
+
- lib/custom_tag/railties.rb
|
30
49
|
- lib/custom_tag/version.rb
|
31
50
|
- sig/custom_tag.rbs
|
32
51
|
homepage: https://github.com/andyjeffries/customtag
|
@@ -35,6 +54,7 @@ metadata:
|
|
35
54
|
homepage_uri: https://github.com/andyjeffries/customtag
|
36
55
|
source_code_uri: https://github.com/andyjeffries/customtag
|
37
56
|
changelog_uri: https://github.com/andyjeffries/customtag/blob/master/CHANGELOG.md
|
57
|
+
rubygems_mfa_required: 'true'
|
38
58
|
post_install_message:
|
39
59
|
rdoc_options: []
|
40
60
|
require_paths:
|
@@ -43,7 +63,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
43
63
|
requirements:
|
44
64
|
- - ">="
|
45
65
|
- !ruby/object:Gem::Version
|
46
|
-
version: 2.
|
66
|
+
version: 2.7.0
|
47
67
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
48
68
|
requirements:
|
49
69
|
- - ">="
|