objective_elements 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +115 -72
- data/lib/objective_elements.rb +1 -0
- data/lib/objective_elements/double_tag.rb +1 -0
- data/lib/objective_elements/html_attributes.rb +4 -0
- data/lib/objective_elements/shelf_tag.rb +17 -0
- data/lib/objective_elements/version.rb +1 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cd77403a8910ff13f0b09d7d6d1a1e258b272f728d210f795d87e4df666309d3
|
4
|
+
data.tar.gz: b937e84cc9071b9f103cc8fa8980b2a3f68ce976c22e6baf79d2cd23c8b16bb6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e14e8f6c77cd762a26180d477ce028df2db91bf03309283dcdeb84c63cd0eb540af60f7c041b6c9d24d2a1647ccff47e5fab2037990f44bc4737a92168cd417c
|
7
|
+
data.tar.gz: 07712c2317042d016e37dee5b95e1d411c2788ab2b61399ff3adf790c9282ae73d66dbcaf7a87da1ed8116fd554c836257707f93a158b871f6c8d28a3a044405
|
data/README.md
CHANGED
@@ -1,23 +1,15 @@
|
|
1
1
|
# Objective Elements
|
2
2
|
|
3
|
-
This is a tiny gem that builds nicely formatted HTML using sane, readable Ruby. I use it for
|
4
|
-
plugins, but you can use it anywhere. It's ~100 lines, tested with
|
3
|
+
This is a tiny gem that builds nicely formatted HTML using sane, readable Ruby. I use it for Jekyll
|
4
|
+
plugins, but you can use it anywhere. It's ~100 lines, tested with RSpec, and has no dependencies.
|
5
5
|
|
6
6
|
It doesn't actually know any HTML, just how to format it.
|
7
7
|
|
8
8
|
This is meant to be less involved and more flexible than nokogiri's XML/HTML generator. There's no
|
9
|
-
DSL to learn
|
9
|
+
DSL to learn and no cleverness to wrap your mind around. Its specialty is taking fragmented,
|
10
10
|
disjointed information and condensing it into a string of properly formatted HTML. It's as agnostic
|
11
11
|
as possible on the input, while being extremely consistent with its output.
|
12
12
|
|
13
|
-
## How it works:
|
14
|
-
|
15
|
-
* Instantiate a `SingleTag` or `DoubleTag`
|
16
|
-
|
17
|
-
* Add attributes & content. Nest tags infinitely.
|
18
|
-
|
19
|
-
* Render it with `.to_s`
|
20
|
-
|
21
13
|
## Motivation:
|
22
14
|
|
23
15
|
Have you ever tried to build HTML with string concatenation and interpolation? It starts out simply
|
@@ -51,62 +43,49 @@ or this:
|
|
51
43
|
end
|
52
44
|
```
|
53
45
|
|
54
|
-
Which is why I sat down and wrote this gem. It's super simple, you probably could have written it
|
55
|
-
too, but hey! Now you don't have to. Here's a demo:
|
56
|
-
|
57
46
|
## Demo
|
58
47
|
|
59
48
|
```ruby
|
60
|
-
# gemfile:
|
61
|
-
gem 'objective_elements', '~>1.0.0'
|
62
|
-
|
63
|
-
# Anywhyere else:
|
64
|
-
require 'objective_elements'
|
65
|
-
|
66
49
|
p = DoubleTag.new 'p'
|
67
50
|
p.to_s
|
68
51
|
# <p>
|
69
52
|
# </p>
|
70
53
|
|
71
|
-
# Add attributes as a hash. keys can be strings or symbols, values can be arrays or strings:
|
72
54
|
p.attributes << { class: 'stumpy grumpy', 'id' => 'the-ugly-one' }
|
73
55
|
|
74
|
-
|
56
|
+
p.id
|
57
|
+
# the-ugly-one
|
58
|
+
|
75
59
|
p.attributes << 'class="slimy" data-awesomeness="11"'
|
76
60
|
|
77
|
-
|
78
|
-
|
61
|
+
|
62
|
+
# Ruby method names can't have dashes.
|
63
|
+
p.attributes['data-awesomeness']
|
79
64
|
# '11'
|
80
65
|
|
81
|
-
# Set them, too! (Note: This doesn't work for class or method)
|
82
66
|
p.id = 'killer'
|
83
67
|
|
84
|
-
|
85
|
-
p.add_content "Icky"
|
68
|
+
p << "Icky"
|
86
69
|
|
87
70
|
p.to_s
|
88
71
|
# <p class="stumpy grumpy slimy" id="killer" data-awesomeness="11">
|
89
72
|
# Icky
|
90
73
|
# </p>
|
91
74
|
|
92
|
-
# Want a oneliner?
|
93
75
|
p.oneline = true
|
94
76
|
p.to_s
|
95
77
|
# <p class="stumpy grumpy slimy" id="killer" data-awesomeness="11">Icky</p>
|
96
78
|
p.oneline = false
|
97
79
|
|
98
|
-
# Build a tag all at once:
|
99
80
|
p.add_content DoubleTag.new(
|
100
81
|
'a',
|
101
82
|
content: 'Link!',
|
102
|
-
attributes: {href: 'awesome-possum.com'},
|
83
|
+
attributes: { href: 'awesome-possum.com' },
|
103
84
|
oneline: true
|
104
85
|
)
|
105
86
|
|
106
|
-
# Add a parent tag:
|
107
87
|
div = p.add_parent DoubleTag.new 'div'
|
108
88
|
|
109
|
-
# Implicit string conversion means cool stuff like this works:
|
110
89
|
"#{div}"
|
111
90
|
# <div>
|
112
91
|
# <p class="stumpy grumpy slimy" id="killer" data-awesomeness="11">
|
@@ -117,26 +96,31 @@ div = p.add_parent DoubleTag.new 'div'
|
|
117
96
|
|
118
97
|
```
|
119
98
|
|
120
|
-
|
121
|
-
|
122
|
-
|
99
|
+
## Changes
|
100
|
+
|
101
|
+
### 1.1.0
|
102
|
+
Add `ShelfTag`, which is useful when you want to create siblings without a parent element.
|
103
|
+
|
104
|
+
### 1.0.0
|
105
|
+
Attributes syntax has changed pretty significantly. Find `.add_attributes` & replace `.attributes << `
|
106
|
+
will get you most of the way there, but you should read over the usage section again.
|
123
107
|
|
124
108
|
## Installation
|
125
109
|
|
126
110
|
```ruby
|
127
111
|
# Gemfile
|
128
112
|
|
129
|
-
gem 'objective_elements', '~> 0.
|
113
|
+
gem 'objective_elements', '~> 1.0.0'
|
130
114
|
```
|
131
115
|
|
132
116
|
```ruby
|
133
|
-
#
|
117
|
+
# Anywhere else:
|
134
118
|
|
135
119
|
require 'objective_elements'
|
136
120
|
```
|
121
|
+
|
137
122
|
## Terminology
|
138
123
|
|
139
|
-
So we're on the same page, here's the terminology I'm using:
|
140
124
|
```
|
141
125
|
<p class="stumpy">Hello</p>
|
142
126
|
|a| b | c | d |
|
@@ -150,75 +134,114 @@ So we're on the same page, here's the terminology I'm using:
|
|
150
134
|
|
151
135
|
## Usage
|
152
136
|
|
137
|
+
For Attribute & SingleTag examples, we'll use this image tag:
|
138
|
+
```ruby
|
139
|
+
|
140
|
+
img = SingleTag.new 'img', attributes: 'src="angry-baby.jpg"'
|
141
|
+
|
142
|
+
```
|
143
|
+
|
153
144
|
There are 2 classes you care about: `SingleTag` is the base class, and `DoubleTag` inherits from it.
|
154
145
|
A `SingleTag` is a self-closing tag, meaning it has no content and no closing tag. A `DoubleTag` is
|
155
146
|
the other kind.
|
156
147
|
|
157
148
|
### Attributes
|
158
149
|
Attributes are their own class, and can be accessed by the `.attributes` method on both single and
|
159
|
-
double tags. Important methods:
|
150
|
+
double tags. Important methods:
|
160
151
|
|
161
|
-
` << (attribute)`
|
152
|
+
` << (attribute)`
|
153
|
+
- Example: `p.attributes << 'alt="he does not look happy"'`
|
154
|
+
- Example: `p.attributes << { alt: "he does not look happy" }`
|
155
|
+
- Add new attributes, can accept a hash or a string. Hash keys will be converted
|
162
156
|
to symbols if they are not already, and values will be split on spaces into an array if they are not
|
163
157
|
already. Attributes can also be given as a string in the standard HTML syntax (`class="myclass"
|
164
158
|
id="my-id"`). **Every other method which adds attributes in some way, calls this method**. This
|
165
159
|
means that any time you are adding attributes, you can use any format which this method understands.
|
166
160
|
|
167
|
-
`.delete(attribute)`
|
161
|
+
`.delete(attribute)`
|
162
|
+
- Example: `img.attributes.delete 'src'`
|
163
|
+
- Example: `img.attributes.delete :src`
|
164
|
+
- Example: `img.attributes.delete [:src, 'alt']`
|
165
|
+
- Delete one or more attributes. Accepts a string, symbol, or an array of
|
168
166
|
strings and/or symbols.
|
169
167
|
|
170
|
-
`.replace(attribute)`
|
168
|
+
`.replace(attribute)`
|
169
|
+
- Example: `img.attributes.replace 'src="happy-baby.jpg"'`
|
170
|
+
- Replaces one or more attributes and values individually.
|
171
|
+
|
172
|
+
`.content[:attribute_name] = `
|
173
|
+
- Example: `img.attributes.content[:src] = 'dirty-baby.jpg'` < This just broke everything.
|
174
|
+
- Don't do it. Use `.replace`, `.(attribute name) = `, or `<<`
|
175
|
+
|
176
|
+
`.content[:attribute_name]`
|
177
|
+
- Example: `img.attributes[:src] # returns 'angry-baby.jpg`
|
178
|
+
- Retrieve the content for a given attribute, as an array of strings. Must be a symbol. You'll
|
179
|
+
- mostly need this when you don't know which attribute you need ahead of
|
180
|
+
time, or to access class and method attributes because you can't use the methods below:
|
181
|
+
|
182
|
+
**There is a shorthand for the next two methods. Keep reading.**
|
171
183
|
|
172
|
-
`.
|
173
|
-
|
174
|
-
|
184
|
+
`.(attribute_name)`
|
185
|
+
- Example: `img.attributes.src # 'angry-baby.jpg'`
|
186
|
+
- Convenience method/syntactic sugar: Returns the value of a given attribute name, as a
|
187
|
+
- space-separated string. This relies on method_missing, which means that any overlap with
|
188
|
+
already existing methods won't work.
|
189
|
+
- **You can't access `class` or `method` html attributes this way, because
|
190
|
+
basic objects in ruby already have those methods.**
|
191
|
+
- **Ruby methods can't have dashes in them.** This means `p.data-awesomeness` won't work.
|
175
192
|
|
176
|
-
`.
|
193
|
+
`.(attribute_name) = value`
|
194
|
+
- Example: `img.attributes.src = 'happy-baby.jpg'`
|
195
|
+
- Same as above. Similar to `.replace(attribute)`. Interestingly, `method = ` and `class = ` both
|
196
|
+
work (`.class` is defined on the basic object class, but `.class=` is not.). Still, you
|
197
|
+
probably shouldn't use them.
|
177
198
|
|
178
|
-
|
179
|
-
name, as a space-separated string. This relies on method_missing, which means that any overlap with
|
180
|
-
already existing methods won't work. **You can't access `class` or `method` html attributes this
|
181
|
-
way, because basic objects in ruby already have those methods.**
|
199
|
+
**Missing methods are forwarded from elements to their attributes, so you can do this:**
|
182
200
|
|
183
|
-
|
184
|
-
|
185
|
-
is not.). That said, you probably shouldn't use them because it will be confusing to understand
|
186
|
-
later.
|
201
|
+
- Example: `img.src # returns 'angry-baby.jpg'`
|
202
|
+
- Example: `img.src = 'grumpy-baby.jpg'`
|
187
203
|
|
188
204
|
### SingleTag Properties:
|
189
205
|
|
190
206
|
#### element
|
191
207
|
- String
|
192
208
|
- Mandatory
|
193
|
-
- Which type of tag
|
209
|
+
- Which type of tag, such as 'hr' or 'img'
|
210
|
+
|
194
211
|
#### attributes
|
195
212
|
- Instance of the class described above.
|
196
213
|
|
197
|
-
|
198
214
|
### SingleTag Methods (that you care about)
|
199
215
|
|
200
216
|
`SingleTag.new(element, attributes: nil)`
|
201
217
|
|
202
|
-
`.to_s`
|
218
|
+
`.to_s`
|
219
|
+
- Example: `img.to_s`
|
220
|
+
- The big one. Returns your HTML as a string, nondestructively.
|
203
221
|
|
204
|
-
`.add_parent(DoubleTag)`
|
222
|
+
`.add_parent(DoubleTag)`
|
223
|
+
- Example: `img.add_parent DoubleTag.new 'picture'`
|
224
|
+
- returns supplied DoubleTag, with self added as a child.
|
205
225
|
|
206
|
-
`.attributes`
|
226
|
+
`.attributes`
|
227
|
+
- Example: `img.attributes`
|
228
|
+
- attr_reader for HTML attributes. This is how you can access any attribute method
|
207
229
|
described above.
|
208
230
|
|
209
|
-
`.reset_attributes`
|
231
|
+
`.reset_attributes`
|
232
|
+
- Example: `img.reset_attributes`
|
233
|
+
- Removes all attributes.
|
210
234
|
|
211
|
-
`.attributes=(
|
235
|
+
`.attributes=(new)`
|
236
|
+
- Example: `img.attributes = 'src="grumpy-baby.jpg" id="muddy"'`
|
237
|
+
- Equivalent to `reset_attributes` and `.attributes << new`
|
212
238
|
|
213
239
|
`attr_reader :attributes`
|
214
240
|
`attr_accessor :element`
|
215
241
|
|
216
|
-
`.(attribute_name)` / `.(attribute_name) = ` - Forwarded to attributes object. Allows you to set or
|
217
|
-
retrieve the value of attributes other than `class` and `method`, without having to type
|
218
|
-
`.attributes` in front of it.
|
219
|
-
|
220
242
|
### DoubleTag Properties:
|
221
243
|
|
244
|
+
|
222
245
|
#### `DoubleTag` Inherits all of `SingleTag`'s properties and methods, and adds content and a
|
223
246
|
closing tag.
|
224
247
|
|
@@ -242,23 +265,43 @@ closing tag.
|
|
242
265
|
|
243
266
|
### DoubleTag Methods (that you care about)
|
244
267
|
|
245
|
-
|
246
|
-
content.
|
268
|
+
For DoubleTag Examples, we're working with a div tag:
|
247
269
|
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
270
|
+
```
|
271
|
+
div = DoubleTag.new 'div'
|
272
|
+
```
|
273
|
+
|
274
|
+
`DoubleTag.new(element, attributes: {}, oneline: false, content: [])`
|
275
|
+
- You can initialize it with content.
|
276
|
+
|
277
|
+
`add_content(anything)`
|
278
|
+
- Example: `div.add_content 'example text!'`
|
279
|
+
- Example: `div.add_content ['splits', 'across', 'lines']`
|
280
|
+
- Example: `div.add_content img # image tag from earlier`
|
281
|
+
- Smart enough to handle both arrays and not-arrays without getting dorked up. When given an array,
|
282
|
+
its elements will be appended to the content array. When given a single item, that item will be
|
283
|
+
inserted at the end of the array. (Remember each element in the content array gets at least one
|
284
|
+
line!)
|
252
285
|
|
253
286
|
`attr_accessor: content` - You can modify the content array directly if you like. If you're just
|
254
287
|
adding items, you should use `.add_content`
|
255
288
|
|
289
|
+
`oneline` - Example: `div.oneline = true`
|
290
|
+
|
256
291
|
`.to_a` - Mostly used internally, but if you want an array of strings, each element a line with
|
257
292
|
appropriate indentation applied, this is how you can get it.
|
258
293
|
|
294
|
+
### ShelfTags:
|
295
|
+
|
296
|
+
Shelf tags are like invisible double tags. Think of them like a bookshelf.
|
297
|
+
They're useful when you want to build siblings without a corresponding parent
|
298
|
+
tag.
|
299
|
+
|
300
|
+
Convert it into an actual tag with `.add_parent(DoubleTag)`
|
301
|
+
|
259
302
|
## Configuration
|
260
303
|
|
261
|
-
Indentation is defined by the `indent` method on the DoubleTag class, which is two
|
304
|
+
Indentation is defined by the `indent` method on the DoubleTag class, which is two escaped
|
262
305
|
spaces by default ("\ \ "). If you'd like to change it:
|
263
306
|
|
264
307
|
1. Make a new class, inherit from DoubleTag.
|
data/lib/objective_elements.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
# This is a nonexistent HTML tag, which holds content like a double tag but has
|
2
|
+
# no opening or closing tag. This allows us to group siblings without adding an
|
3
|
+
# extra parent to the markup.
|
4
|
+
class ShelfTag < DoubleTag
|
5
|
+
def initialize(content: nil, oneline: false)
|
6
|
+
self.oneline = oneline
|
7
|
+
self.content = content
|
8
|
+
end
|
9
|
+
|
10
|
+
def to_a
|
11
|
+
content.map { |c| build_content_line c }.flatten
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_parent(parent)
|
15
|
+
parent.add_content content
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: objective_elements
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Buchberger
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2019-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -84,6 +84,7 @@ files:
|
|
84
84
|
- lib/objective_elements.rb
|
85
85
|
- lib/objective_elements/double_tag.rb
|
86
86
|
- lib/objective_elements/html_attributes.rb
|
87
|
+
- lib/objective_elements/shelf_tag.rb
|
87
88
|
- lib/objective_elements/single_tag.rb
|
88
89
|
- lib/objective_elements/version.rb
|
89
90
|
- objective_elements.gemspec
|
@@ -106,8 +107,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
107
|
- !ruby/object:Gem::Version
|
107
108
|
version: '0'
|
108
109
|
requirements: []
|
109
|
-
|
110
|
-
rubygems_version: 2.7.3
|
110
|
+
rubygems_version: 3.0.2
|
111
111
|
signing_key:
|
112
112
|
specification_version: 4
|
113
113
|
summary: Build HTML without interpolating strings.
|