objective_elements 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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.
|