jekyll-webmention_io 3.3.7 → 4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 92d94de0add9cc4571ce7b0f312cce727c3b387e645101f8c190e025c58be261
4
- data.tar.gz: 8dbd9f8960c7c5c427c861fc08bc368a901e04b51267219fc1030b81b33b25e7
3
+ metadata.gz: cc9d31a7e443e2a0b12a6d4b5ce65fff675e8302113f751eff6b5bbde3d090e3
4
+ data.tar.gz: 3c57fc8d14d3345def7d2bd432745fbcd9551d9931adc7ea870d7ae7ed638f6f
5
5
  SHA512:
6
- metadata.gz: 676aa2fd229c06d44f077f3eb7fb7f52deec8bad2f082b101fffb6379b66f35e90a1fcfe31d06539f4baeb77f6a5f7712aa5319d09c463fe5d2cf2c02e34974d
7
- data.tar.gz: f73660974098440e3b658183dd9a9a10817d8fc010db197766e80678d43e4e295341adef6e057eee33c5acc5b06b1f3ce38f1bd1cbbad776199c64a95129147f
6
+ metadata.gz: a650de9ca6309c29e09f5f9533ac5ca62dddec88f8dca8302efb9aee4254fb7445c86f68f4bc06f070189e6cf47f04efcaa6942e9cdd523536e2bc319b70c531
7
+ data.tar.gz: afd4a141acc8cb97e78e27f0bfcac62f4d8d3d355a4362b7ef94789ba3e5710023f3813bb04a7a9d6de27af0e84167524440d88181aaceb3d18469362deae115
@@ -189,7 +189,7 @@
189
189
  incoming[plural_type].push( webmention );
190
190
  }
191
191
 
192
- // If theres a generic, add it there too
192
+ // If there's a generic, add it there too
193
193
  if ( incoming.webmentions )
194
194
  {
195
195
  incoming.webmentions.push( webmention );
@@ -528,4 +528,4 @@
528
528
  collectExistingWebmentions();
529
529
  identifyWebmentionCollections();
530
530
 
531
- }(this, this.document));
531
+ }(this, this.document));
@@ -1,7 +1,7 @@
1
1
  // @ts-check
2
2
  /**
3
3
  * WebMentions.io JS
4
- * A re-tooling of Aaron Pareckis recommended JS for using the WebMention.io API
4
+ * A re-tooling of Aaron Parecki's recommended JS for using the WebMention.io API
5
5
  *
6
6
  * Updates Webmentions on a static site immediately when the page is loaded and
7
7
  * in real-time (using WebSockets) as the user engages with the page.
@@ -31,4 +31,4 @@
31
31
  return k;
32
32
  };
33
33
 
34
- }(this,this.document));
34
+ }(this,this.document));
@@ -26,18 +26,17 @@ module Jekyll
26
26
  WebmentionIO.log "msg", "Getting ready to send webmentions (this may take a while)."
27
27
 
28
28
  count = 0
29
+ max_attempts = WebmentionIO.max_attempts()
29
30
  cached_outgoing = WebmentionIO.get_cache_file_path "outgoing"
30
31
  if File.exist?(cached_outgoing)
31
32
  outgoing = WebmentionIO.load_yaml(cached_outgoing)
32
33
  outgoing.each do |source, targets|
33
34
  targets.each do |target, response|
34
35
  # skip ones we’ve handled
35
- next unless response == false
36
+ next unless response == false or response.instance_of? Integer
36
37
 
37
- # convert protocol-less links
38
- if target.index("//").zero?
39
- target = "http:#{target}"
40
- end
38
+ # skip protocol-less links, we'll need to revisit this again later
39
+ next if target.index("//").zero?
41
40
 
42
41
  # produce an escaped version of the target (in case of special
43
42
  # characters, etc).
@@ -46,6 +45,17 @@ module Jekyll
46
45
  # skip bad URLs
47
46
  next unless WebmentionIO.uri_ok?(escaped)
48
47
 
48
+ # give up if we've attempted this too many times
49
+ response = (response || 0) + 1
50
+
51
+ if ! max_attempts.nil? and response > max_attempts
52
+ outgoing[source][target] = ""
53
+ WebmentionIO.log "msg", "Giving up sending from #{source} to #{target}."
54
+ next
55
+ else
56
+ outgoing[source][target] = response
57
+ end
58
+
49
59
  # get the endpoint
50
60
  endpoint = WebmentionIO.get_webmention_endpoint(escaped)
51
61
  next unless endpoint
@@ -64,9 +74,7 @@ module Jekyll
64
74
  count += 1
65
75
  end
66
76
  end
67
- if count.positive?
68
- WebmentionIO.dump_yaml(cached_outgoing, outgoing)
69
- end
77
+ WebmentionIO.dump_yaml(cached_outgoing, outgoing)
70
78
  WebmentionIO.log "msg", "#{count} webmentions sent."
71
79
  end # file exists (outgoing)
72
80
  end # def process
@@ -18,7 +18,6 @@ module Jekyll
18
18
  end
19
19
  end
20
20
 
21
- using StringInflection
22
21
  class CompileJS < Generator
23
22
  safe true
24
23
  priority :low
@@ -61,7 +60,7 @@ module Jekyll
61
60
  def add_webmention_types
62
61
  js_types = []
63
62
  WebmentionIO.types.each do |type|
64
- js_types.push "'#{type}': '#{type.to_singular}'"
63
+ js_types.push "'#{type}': '#{ActiveSupport::Inflector.singularize(type)}'"
65
64
  end
66
65
  types_js = <<-EOF
67
66
  ;(function(window,JekyllWebmentionIO){
@@ -8,6 +8,8 @@
8
8
  # This generator caches sites you mention so they can be mentioned
9
9
  #
10
10
 
11
+ require "jsonpath"
12
+
11
13
  module Jekyll
12
14
  module WebmentionIO
13
15
  class QueueWebmentions < Generator
@@ -17,6 +19,7 @@ module Jekyll
17
19
  def generate(site)
18
20
  @site = site
19
21
  @site_url = site.config["url"].to_s
22
+ @syndication = site.config.dig("webmentions", "syndication")
20
23
 
21
24
  if @site.config['serving']
22
25
  Jekyll::WebmentionIO.log "msg", "Webmentions lookups are not run when running `jekyll serve`."
@@ -31,52 +34,193 @@ module Jekyll
31
34
  return
32
35
  end
33
36
 
34
- if @site.config.dig("webmentions", "pause_lookups")
35
- WebmentionIO.log "info", "Webmention lookups are currently paused."
36
- return
37
- end
37
+ compile_jsonpath_expressions() if ! @syndication.nil?
38
38
 
39
- WebmentionIO.log "msg", "Beginning to gather webmentions you’ve made. This may take a while."
39
+ WebmentionIO.log "msg", "Collecting webmentions you’ve made. This may take a while."
40
40
 
41
41
  upgrade_outgoing_webmention_cache
42
42
 
43
- posts = WebmentionIO.gather_documents(@site)
44
-
43
+ posts = WebmentionIO.gather_documents(@site).select { |p| ! p.data["draft"] }
45
44
  gather_webmentions(posts)
46
45
  end
47
46
 
48
47
  private
49
48
 
49
+ def compile_jsonpath_expressions()
50
+ @syndication.each do | target, config |
51
+ next if ! config.key? "response_mapping"
52
+
53
+ mapping = config["response_mapping"]
54
+
55
+ mapping.clone.each do | key, pattern |
56
+ begin
57
+ mapping[key] = JsonPath.new(pattern)
58
+ rescue StandardError => e
59
+ WebmentionIO.log "error", "Ignoring invalid JsonPath expression #{pattern}: #{e}"
60
+
61
+ mapping.delete(key)
62
+ end
63
+ end
64
+ end
65
+ end
66
+
67
+ def combine_values(a, b)
68
+ return case [ a.instance_of?(Array), b.instance_of?(Array) ]
69
+ when [ false, false ]
70
+ [ a, b ]
71
+ when [ false, true ]
72
+ [ a ] + b
73
+ when [ true, false ]
74
+ a << b
75
+ when [ true, true ]
76
+ a + b
77
+ end
78
+ end
79
+
80
+ def process_syndication(post, target, response)
81
+ # If this is a syndication target, and we have a response,
82
+ # and the syndication entry contains a response mapping, then
83
+ # go through that map and store the selected values into
84
+ # the page front matter.
85
+
86
+ response = JSON.generate(response)
87
+
88
+ target["response_mapping"].each do |key, pattern|
89
+ result = pattern.on(response)
90
+
91
+ if ! result
92
+ WebmentionIO.log "msg", "The path #{skey} doesn't exist in the response from #{target['endpoint']} for #{uri}"
93
+ next
94
+ elsif result.length == 1
95
+ result = result.first
96
+ end
97
+
98
+ if post.data[key].nil?
99
+ post.data[key] = result
100
+ else
101
+ post.data[key] = combine_values(post.data[key], result)
102
+ end
103
+ end
104
+ end
105
+
106
+ def get_collection_for_post(post)
107
+ @site.collections.each do |name, collection|
108
+ next if name == "posts"
109
+
110
+ return collection if collection.docs.include? post
111
+ end
112
+
113
+ return nil
114
+ end
115
+
116
+ def get_syndication_target(uri)
117
+ return nil if @syndication.nil?
118
+
119
+ @syndication.values.detect { |t| t["endpoint"] == uri }
120
+ end
121
+
50
122
  def gather_webmentions(posts)
51
123
  webmentions = WebmentionIO.read_cached_webmentions "outgoing"
52
124
 
53
125
  posts.each do |post|
54
- uri = File.join(@site_url, post.url)
126
+ # Collect potential outgoing webmentions in this post.
55
127
  mentions = get_mentioned_uris(post)
56
- if webmentions.key? uri
57
- mentions.each do |mentioned_uri, response|
58
- unless webmentions[uri].key? mentioned_uri
59
- webmentions[uri][mentioned_uri] = response
128
+
129
+ mentions.each do |mentioned_uri, response|
130
+ # If this webmention was a product of a syndication instruction,
131
+ # this goes back into the configuration and pulls that syndication
132
+ # target config out.
133
+ #
134
+ # If this is just a normal webmention, this will return nil.
135
+ target = get_syndication_target(mentioned_uri)
136
+
137
+ fulluri = File.join(@site_url, post.url)
138
+ shorturi = post.data["shorturl"] || fulluri
139
+
140
+ # Old cached responses might use either the full or short URIs so
141
+ # we need to check for both.
142
+ cached_response =
143
+ webmentions.dig(shorturi, mentioned_uri) ||
144
+ webmentions.dig(fulluri, mentioned_uri)
145
+
146
+ if cached_response.nil?
147
+ if ! target.nil?
148
+ uri = target["shorturl"] ? shorturi : fulluri
149
+
150
+ if target.key? "fragment"
151
+ uri += "#" + target["fragment"]
152
+ end
153
+ else
154
+ uri = fulluri
60
155
  end
156
+
157
+ webmentions[uri] ||= {}
158
+ webmentions[uri][mentioned_uri] = response
159
+ elsif ! target.nil? and target.key? "response_mapping"
160
+ process_syndication(post, target, cached_response)
61
161
  end
62
- else
63
- webmentions[uri] = mentions
64
162
  end
65
163
  end
66
164
 
67
- WebmentionIO.cache_webmentions "outgoing", webmentions
165
+ # This check is moved down here because we still need the steps
166
+ # above to populate frontmatter during the site build, even
167
+ # if we're not going to modify the webmention cache.
168
+
169
+ if @site.config.dig("webmentions", "pause_lookups")
170
+ WebmentionIO.log "info", "Webmention lookups are currently paused."
171
+ return
172
+ else
173
+ WebmentionIO.cache_webmentions "outgoing", webmentions
174
+ end
68
175
  end
69
176
 
70
177
  def get_mentioned_uris(post)
178
+ collection = get_collection_for_post(post)
179
+
71
180
  uris = {}
181
+ parser = URI::Parser.new
182
+
183
+ syndication_targets = []
184
+ syndication_targets += post.data["syndicate_to"] || []
185
+
186
+ if ! collection.nil?
187
+ syndication_targets += collection.metadata["syndicate_to"] || []
188
+ end
189
+
190
+ syndication_targets.each do |endpoint|
191
+ if @syndication.key? endpoint
192
+ uris[@syndication[endpoint]["endpoint"]] = false
193
+ else
194
+ WebmentionIO.log "msg", "Found reference to syndication endpoint \"#{endpoint}\" without matching entry in configuration."
195
+ end
196
+ end
197
+
72
198
  if post.data["in_reply_to"]
73
199
  uris[post.data["in_reply_to"]] = false
74
200
  end
201
+
202
+ if post.data["bookmark_of"]
203
+ uris[post.data["bookmark_of"]] = false
204
+ end
205
+
75
206
  post.content.scan(/(?:https?:)?\/\/[^\s)#\[\]{}<>%|\^"']+/) do |match|
76
- unless uris.key? match
77
- uris[match] = false
207
+ begin
208
+ # We do this as a poor man's way to validate the URI. We do most
209
+ # of the work with the regex scan above, then attempt a parse as
210
+ # the last test in case a bad URI fell through the cracks.
211
+ #
212
+ # Of course, better would be to fix the regex, but consider this
213
+ # belt-and-suspenders...
214
+ parser.parse(parser.escape(match))
215
+
216
+ unless uris.key? match
217
+ uris[match] = false
218
+ end
219
+ rescue => e
220
+ WebmentionIO.log "msg", "Encountered unexpected malformed URI '#{match}' in #{post.path}, skipping..."
78
221
  end
79
222
  end
223
+
80
224
  return uris
81
225
  end
82
226
 
@@ -18,7 +18,7 @@ module Jekyll
18
18
  self.template = "count"
19
19
  end
20
20
 
21
- def set_data(data, types)
21
+ def set_data(data, types, html_proofer_ignore)
22
22
  @data = { "count" => data.length, "types" => types }
23
23
  end
24
24
  end
@@ -11,7 +11,6 @@ require "htmlbeautifier"
11
11
 
12
12
  module Jekyll
13
13
  module WebmentionIO
14
- using StringInflection
15
14
  class WebmentionTag < Liquid::Tag
16
15
  def initialize(tag_name, text, tokens)
17
16
  super
@@ -40,8 +39,8 @@ module Jekyll
40
39
  WebmentionIO.log "info", "#{template.capitalize} template:\n\n#{@template}\n\n"
41
40
  end
42
41
 
43
- def set_data(data, types)
44
- @data = { "webmentions" => data, "types" => types }
42
+ def set_data(data, types, html_proofer_ignore)
43
+ @data = { "webmentions" => data, "types" => types, "html_proofer_ignore" => html_proofer_ignore }
45
44
  end
46
45
 
47
46
  def extract_type(type, webmentions)
@@ -50,7 +49,7 @@ module Jekyll
50
49
  if !WebmentionIO.types.include? type
51
50
  WebmentionIO.log "warn", "#{type} are not extractable"
52
51
  else
53
- type = type.to_singular
52
+ type = ActiveSupport::Inflector.singularize(type)
54
53
  WebmentionIO.log "info", "Searching #{webmentions.length} webmentions for type==#{type}"
55
54
  if webmentions.is_a? Hash
56
55
  webmentions = webmentions.values
@@ -63,14 +62,23 @@ module Jekyll
63
62
  end
64
63
 
65
64
  def render(context)
65
+ # Initialize an empty set of webmentions (we'll populate later if
66
+ # there actually are any).
67
+ webmentions = []
68
+
69
+ # Capture the types in case JS needs them
70
+ types = []
71
+
72
+ # Retrieve the html_proofer_ignore config setting so we can pass
73
+ # it into the templates.
74
+ site = context.registers[:site]
75
+ html_proofer_ignore = site.config.dig("webmentions", "html_proofer_ignore") || "none"
76
+
66
77
  # Get the URI
67
78
  args = @text.split(/\s+/).map(&:strip)
68
79
  uri = args.shift
69
80
  uri = lookup(context, uri)
70
81
 
71
- # capture the types in case JS needs them
72
- types = []
73
-
74
82
  if @cached_webmentions.key? uri
75
83
  all_webmentions = @cached_webmentions[uri].clone
76
84
  WebmentionIO.log "info", "#{all_webmentions.length} total webmentions for #{uri}"
@@ -94,9 +102,9 @@ module Jekyll
94
102
  end
95
103
 
96
104
  webmentions = sort_webmentions(webmentions)
97
- set_data(webmentions, types)
98
105
  end
99
106
 
107
+ set_data(webmentions, types, html_proofer_ignore)
100
108
  render_into_template(context.registers)
101
109
  end
102
110
 
@@ -12,9 +12,9 @@ module Jekyll
12
12
  # Superclass for Webmention types:
13
13
  # [ bookmarks | likes | links | posts | replies | reposts | rsvps ]
14
14
  class WebmentionTypeTag < WebmentionTag
15
- def set_data(data, _types)
15
+ def set_data(data, _types, html_proofer_ignore)
16
16
  webmentions = extract_type @template_name, data
17
- @data = { "webmentions" => webmentions.values }
17
+ @data = { "webmentions" => webmentions.values, "html_proofer_ignore" => html_proofer_ignore }
18
18
  end
19
19
  end
20
20
  end
@@ -1,26 +1,65 @@
1
- <div class="webmentions webmentions--bookmarks">
1
+ {%- if html_proofer_ignore == "all" -%}
2
+ {%- assign html_proofer_attr = " data-proofer-ignore" -%}
3
+ {%- endif -%}
4
+ <div class="webmentions webmentions--bookmarks"{{ html_proofer_attr }}>
2
5
  {% if webmentions.size > 0 %}
3
6
  <ol class="webmentions__list">
4
7
  {% for webmention in webmentions %}
5
- <li id="webmention-{{ webmention.id }}" class="webmentions__item webmention webmention--{{ webmention.type }}">
6
- <div class="webmention__content p-content">
7
- {{ webmention.content }}
8
- </div>
9
- <div class="webmention__meta">
8
+ <li id="webmention-{{ webmention.id }}" class="webmention webmentions__item webmention--{{ webmention.type }}">
9
+ <article class="h-cite
10
+ {% unless webmention.author %}webmention--no-author{% endunless %}
11
+ {% unless webmention.author.photo %}webmention--no-photo{% endunless %}
12
+ ">
10
13
  {% if webmention.author %}
11
- <a class="webmention__author h-card u-url" href="{{ webmention.author.url }}" rel="nofollow">{{ webmention.author.name }}</a>
14
+ <div class="webmention__author p-author h-card">
15
+ {% capture author_id %}
16
+ {% if webmention.author.photo %}
17
+ <img
18
+ class="webmention__author__photo u-photo"
19
+ src="{{ webmention.author.photo }}"
20
+ alt=""
21
+ {% if webmention.author.name %}
22
+ title="{{ webmention.author.name }}"
23
+ {% endif %}
24
+ >
25
+ {% endif %}
26
+
27
+ {% if webmention.author.name %}
28
+ <span class="webmention__author__name p-name">{{ webmention.author.name }}</span>
29
+ {% endif %}
30
+ {% endcapture %}
31
+
32
+ {% if webmention.author.url %}
33
+ <a class="u-url" href="{{ webmention.author.url }}" rel="nofollow">{{ author_id }}</a>
34
+ {% else %}
35
+ {{ author_id }}
36
+ {% endif %}
37
+ </div>
12
38
  {% endif %}
13
- {% if webmention.pubdate and webmention.url %}on{% endif %}
14
- {% if webmention.pubdate %}
15
- <a class="webmention__source u-url" href="{{ webmention.url }}" rel="nofollow">
16
- <time class="webmention__pubdate dt-published" datetime="{{ webmention.pubdate | date: '%FT%T%:z' }}">{{ webmention.pubdate | date: '%d %B %Y' }}</time>
17
- </a>
18
- {% endif %}
19
- </div>
39
+
40
+ <div class="webmention__content p-content">
41
+ {% if webmention.content %}
42
+ {{ webmention.content }}
43
+ {% else %}
44
+ {{ webmention.title }}
45
+ {% endif %}
46
+ </div>
47
+
48
+ <div class="webmention__meta">
49
+ {% if webmention.pubdate %}
50
+ <time class="webmention__pubdate dt-published"
51
+ datetime="{{ webmention.pubdate | date: '%FT%T%:z' }}">{{ webmention.pubdate | date: '%d %B %Y' }}</time>
52
+ {% endif %}
53
+ {% if webmention.pubdate and webmention.uri %}|{% endif %}
54
+ {% if webmention.uri %}
55
+ <a class="webmention__source u-url" href="{{ webmention.uri }}" rel="nofollow">Permalink</a>
56
+ {% endif %}
57
+ </div>
58
+ </article>
20
59
  </li>
21
60
  {% endfor %}
22
61
  </ol>
23
62
  {% else %}
24
63
  <p class="webmentions__not-found">No bookmarks were found.</p>
25
64
  {% endif %}
26
- </div>
65
+ </div>
@@ -1,17 +1,46 @@
1
- <div class="webmentions webmentions--likes">
1
+ {%- if html_proofer_ignore == "all" -%}
2
+ {%- assign html_proofer_attr = " data-proofer-ignore" -%}
3
+ {%- endif -%}
4
+ <div class="webmentions webmentions--likes"{{ html_proofer_attr }}>
2
5
  {% if webmentions.size > 0 %}
3
6
  <ol class="webmentions__list">
4
7
  {% for webmention in webmentions %}
5
- <li id="webmention-{{ webmention.id }}" class="webmentions__item webmention webmention--{{ webmention.type }}">
6
- <div class="webmention__author p-author h-card">
7
- <a class="u-url" href="{{ webmention.author.url }}" rel="nofollow">
8
- <img class="webmention__author__photo u-photo" src="{{ webmention.author.photo }}" alt="" title="{{ webmention.author.name }}">
9
- </a>
10
- </div>
8
+ <li id="webmention-{{ webmention.id }}" class="webmention webmentions__item webmention--{{ webmention.type }}">
9
+ <article class="h-cite
10
+ {% unless webmention.author %}webmention--no-author{% endunless %}
11
+ {% unless webmention.author.photo %}webmention--no-photo{% endunless %}
12
+ ">
13
+ {% if webmention.author %}
14
+ <div class="webmention__author p-author h-card">
15
+ {% capture author_id %}
16
+ {% if webmention.author.photo %}
17
+ <img
18
+ class="webmention__author__photo u-photo"
19
+ src="{{ webmention.author.photo }}"
20
+ alt=""
21
+ {% if webmention.author.name %}
22
+ title="{{ webmention.author.name }}"
23
+ {% endif %}
24
+ >
25
+ {% endif %}
26
+
27
+ {% if webmention.author.name %}
28
+ <span class="webmention__author__name p-name">{{ webmention.author.name }}</span>
29
+ {% endif %}
30
+ {% endcapture %}
31
+
32
+ {% if webmention.author.url %}
33
+ <a class="u-url" href="{{ webmention.author.url }}" rel="nofollow">{{ author_id }}</a>
34
+ {% else %}
35
+ {{ author_id }}
36
+ {% endif %}
37
+ </div>
38
+ {% endif %}
39
+ </article>
11
40
  </li>
12
41
  {% endfor %}
13
42
  </ol>
14
43
  {% else %}
15
- <p class="webmentions__not-found">No likes were found.</p>
44
+ <p class="webmentions__not-found">No likes have been sent yet!</p>
16
45
  {% endif %}
17
- </div>
46
+ </div>
@@ -1,26 +1,65 @@
1
- <div class="webmentions webmentions--links">
1
+ {%- if html_proofer_ignore == "all" -%}
2
+ {%- assign html_proofer_attr = " data-proofer-ignore" -%}
3
+ {%- endif -%}
4
+ <div class="webmentions webmentions--links"{{ html_proofer_attr }}>
2
5
  {% if webmentions.size > 0 %}
3
6
  <ol class="webmentions__list">
4
7
  {% for webmention in webmentions %}
5
- <li id="webmention-{{ webmention.id }}" class="webmentions__item webmention webmention--{{ webmention.type }}">
6
- <div class="webmention__content p-content">
7
- {{ webmention.content }}
8
- </div>
9
- <div class="webmention__meta">
8
+ <li id="webmention-{{ webmention.id }}" class="webmention webmentions__item webmention--{{ webmention.type }}">
9
+ <article class="h-cite
10
+ {% unless webmention.author %}webmention--no-author{% endunless %}
11
+ {% unless webmention.author.photo %}webmention--no-photo{% endunless %}
12
+ ">
10
13
  {% if webmention.author %}
11
- <a class="webmention__author h-card u-url" href="{{ webmention.author.url }}" rel="nofollow">{{ webmention.author.name }}</a>
14
+ <div class="webmention__author p-author h-card">
15
+ {% capture author_id %}
16
+ {% if webmention.author.photo %}
17
+ <img
18
+ class="webmention__author__photo u-photo"
19
+ src="{{ webmention.author.photo }}"
20
+ alt=""
21
+ {% if webmention.author.name %}
22
+ title="{{ webmention.author.name }}"
23
+ {% endif %}
24
+ >
25
+ {% endif %}
26
+
27
+ {% if webmention.author.name %}
28
+ <span class="webmention__author__name p-name">{{ webmention.author.name }}</span>
29
+ {% endif %}
30
+ {% endcapture %}
31
+
32
+ {% if webmention.author.url %}
33
+ <a class="u-url" href="{{ webmention.author.url }}" rel="nofollow">{{ author_id }}</a>
34
+ {% else %}
35
+ {{ author_id }}
36
+ {% endif %}
37
+ </div>
12
38
  {% endif %}
13
- {% if webmention.pubdate and webmention.url %}on{% endif %}
14
- {% if webmention.pubdate %}
15
- <a class="webmention__source u-url" href="{{ webmention.url }}" rel="nofollow">
16
- <time class="webmention__pubdate dt-published" datetime="{{ webmention.pubdate | date: '%FT%T%:z' }}">{{ webmention.pubdate | date: '%d %B %Y' }}</time>
17
- </a>
18
- {% endif %}
19
- </div>
39
+
40
+ <div class="webmention__content p-content">
41
+ {% if webmention.content %}
42
+ {{ webmention.content }}
43
+ {% else %}
44
+ {{ webmention.title }}
45
+ {% endif %}
46
+ </div>
47
+
48
+ <div class="webmention__meta">
49
+ {% if webmention.pubdate %}
50
+ <time class="webmention__pubdate dt-published"
51
+ datetime="{{ webmention.pubdate | date: '%FT%T%:z' }}">{{ webmention.pubdate | date: '%d %B %Y' }}</time>
52
+ {% endif %}
53
+ {% if webmention.pubdate and webmention.uri %}|{% endif %}
54
+ {% if webmention.uri %}
55
+ <a class="webmention__source u-url" href="{{ webmention.uri }}" rel="nofollow">Permalink</a>
56
+ {% endif %}
57
+ </div>
58
+ </article>
20
59
  </li>
21
60
  {% endfor %}
22
61
  </ol>
23
62
  {% else %}
24
63
  <p class="webmentions__not-found">No links were found.</p>
25
64
  {% endif %}
26
- </div>
65
+ </div>