Fix admin entity decoration
This commit is contained in:
56
slices/admin/decorators/bookmarks/decorator.rb
Normal file
56
slices/admin/decorators/bookmarks/decorator.rb
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# frozen_string_literal: false
|
||||||
|
|
||||||
|
# auto_register: false
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module Decorators
|
||||||
|
module Bookmarks
|
||||||
|
class Decorator < SimpleDelegator
|
||||||
|
def display_published_at
|
||||||
|
published_at.strftime("%e %B, %Y")
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_title
|
||||||
|
"🔖: #{name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def feed_content
|
||||||
|
content || ""
|
||||||
|
end
|
||||||
|
|
||||||
|
def permalink
|
||||||
|
"#{Hanami.app.settings.micropub_site_url}/bookmark/#{slug}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def machine_published_at
|
||||||
|
published_at.rfc2822
|
||||||
|
end
|
||||||
|
|
||||||
|
def syndicated?
|
||||||
|
!syndication_sources.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def template_type
|
||||||
|
:bookmark
|
||||||
|
end
|
||||||
|
|
||||||
|
def syndicated_to
|
||||||
|
syndication_sources.map do |source, url|
|
||||||
|
{
|
||||||
|
location: source,
|
||||||
|
url: url
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def youtube_embed
|
||||||
|
pattern = /watch[?]v=(\w*)/i
|
||||||
|
code = url.scan(pattern).flatten.first
|
||||||
|
if code
|
||||||
|
"<div class='video-container'><iframe width='100%' src='https://www.youtube.com/embed/#{code}' title='YouTube video player' frameborder='0' allow='accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share' allowfullscreen></iframe></div>"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
53
slices/admin/decorators/books/decorator.rb
Normal file
53
slices/admin/decorators/books/decorator.rb
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# frozen_string_literal: false
|
||||||
|
|
||||||
|
# auto_register: false
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module Decorators
|
||||||
|
module Books
|
||||||
|
class Decorator < SimpleDelegator
|
||||||
|
def display_published_at
|
||||||
|
published_at.strftime("%e %B, %Y")
|
||||||
|
end
|
||||||
|
|
||||||
|
def machine_published_at
|
||||||
|
published_at.rfc2822
|
||||||
|
end
|
||||||
|
|
||||||
|
def syndicated?
|
||||||
|
!syndication_sources.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def template_type
|
||||||
|
:book
|
||||||
|
end
|
||||||
|
|
||||||
|
def authors
|
||||||
|
book_author.split(";").join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
def status_colour
|
||||||
|
case book_status
|
||||||
|
when "read" || "finished"
|
||||||
|
"text-green-100 bg-green-500"
|
||||||
|
when "to-read"
|
||||||
|
"text-blue-100 bg-blue-500"
|
||||||
|
when "reading"
|
||||||
|
"text-orange-100 bg-orange-500"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def status_label
|
||||||
|
case book_status
|
||||||
|
when "read" || "finished"
|
||||||
|
"Read"
|
||||||
|
when "to-read"
|
||||||
|
"To read"
|
||||||
|
when "reading"
|
||||||
|
"Reading"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
21
slices/admin/decorators/movies/decorator.rb
Normal file
21
slices/admin/decorators/movies/decorator.rb
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# frozen_string_literal: false
|
||||||
|
|
||||||
|
# auto_register: false
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module Decorators
|
||||||
|
module Movies
|
||||||
|
class Decorator < SimpleDelegator
|
||||||
|
include Deps["clients.omdb"]
|
||||||
|
|
||||||
|
def poster
|
||||||
|
omdb_record&.poster
|
||||||
|
end
|
||||||
|
|
||||||
|
def omdb_record
|
||||||
|
@omdb_record ||= omdb.call(imdb_id: imdb_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
211
slices/admin/decorators/posts/decorator.rb
Normal file
211
slices/admin/decorators/posts/decorator.rb
Normal file
@@ -0,0 +1,211 @@
|
|||||||
|
# frozen_string_literal: false
|
||||||
|
|
||||||
|
# auto_register: false
|
||||||
|
|
||||||
|
require "rexml/parsers/pullparser"
|
||||||
|
require "sanitize"
|
||||||
|
require "nokogiri"
|
||||||
|
require "unicode/emoji"
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module Decorators
|
||||||
|
module Posts
|
||||||
|
class Decorator < SimpleDelegator
|
||||||
|
def syndicated?
|
||||||
|
!syndication_sources.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def syndicated_to
|
||||||
|
syndication_sources.map do |source, url|
|
||||||
|
{
|
||||||
|
location: source,
|
||||||
|
url: url
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def photos?
|
||||||
|
__getobj__.photos.count { |p| !p["value"].end_with?("mp4") } > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def photos
|
||||||
|
__getobj__.photos.select { |p| !p["value"].end_with?("mp4") }
|
||||||
|
end
|
||||||
|
|
||||||
|
def videos?
|
||||||
|
__getobj__.photos.count { |p| p["value"].end_with?("mp4") } > 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def videos
|
||||||
|
__getobj__.photos.select { |p| p["value"].end_with?("mp4") }
|
||||||
|
end
|
||||||
|
|
||||||
|
def key_image
|
||||||
|
if photos?
|
||||||
|
return photos.first["url"]
|
||||||
|
end
|
||||||
|
|
||||||
|
inline_images.first[1] if inline_images
|
||||||
|
end
|
||||||
|
|
||||||
|
def inline_images
|
||||||
|
doc = Nokogiri::HTML(content)
|
||||||
|
doc.at("//img")
|
||||||
|
end
|
||||||
|
|
||||||
|
def inline_image_sources
|
||||||
|
inline_images
|
||||||
|
&.select {|attr, _value| attr == "src"}
|
||||||
|
&.map {|img| img[1] } || []
|
||||||
|
end
|
||||||
|
|
||||||
|
def photo_sources
|
||||||
|
photos.map{|photo| photo["value"]}
|
||||||
|
end
|
||||||
|
|
||||||
|
def prefix_emoji
|
||||||
|
if name
|
||||||
|
nil
|
||||||
|
elsif photos? && content == ""
|
||||||
|
"📷"
|
||||||
|
elsif __getobj__.emoji
|
||||||
|
__getobj__.emoji
|
||||||
|
else
|
||||||
|
@prefix_emoji ||= if (match = content.match(Unicode::Emoji::REGEX))
|
||||||
|
match
|
||||||
|
else
|
||||||
|
"💬"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_title
|
||||||
|
title = name
|
||||||
|
"#{prefix_emoji} #{title}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def display_published_at
|
||||||
|
published_at.strftime("%e %B, %Y")
|
||||||
|
end
|
||||||
|
|
||||||
|
def machine_published_at
|
||||||
|
published_at.rfc2822
|
||||||
|
end
|
||||||
|
|
||||||
|
def feed_content
|
||||||
|
photos? ? "<div>#{photos.map { |p| "<img src='#{p["value"]}'/>" }.join("")} #{content}</div>" : content
|
||||||
|
end
|
||||||
|
|
||||||
|
def raw_content
|
||||||
|
res = Sanitize.fragment(content)
|
||||||
|
res.gsub(prefix_emoji[0], "") if prefix_emoji
|
||||||
|
end
|
||||||
|
|
||||||
|
def excerpt
|
||||||
|
name ? truncate_html(content, 240, true) : content
|
||||||
|
end
|
||||||
|
|
||||||
|
def permalink
|
||||||
|
"#{Hanami.app.settings.micropub_site_url}/post/#{slug}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def lat
|
||||||
|
geo[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def lon
|
||||||
|
geo[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
def small_map
|
||||||
|
"https://api.mapbox.com/styles/v1/dnitza/cleb2o734000k01pbifls5620/static/pin-s+555555(#{lon},#{lat})/#{lon},#{lat},14,0/200x100@2x?access_token=pk.eyJ1IjoiZG5pdHphIiwiYSI6ImNsZWIzOHFmazBkODIzdm9kZHgxdDF4ajQifQ.mSneE-1SKeju8AOz5gp4BQ"
|
||||||
|
end
|
||||||
|
|
||||||
|
def large_map
|
||||||
|
"https://api.mapbox.com/styles/v1/dnitza/cleb2o734000k01pbifls5620/static/pin-s+555555(#{lon},#{lat})/#{lon},#{lat},14,0/620x310@2x?access_token=pk.eyJ1IjoiZG5pdHphIiwiYSI6ImNsZWIzOHFmazBkODIzdm9kZHgxdDF4ajQifQ.mSneE-1SKeju8AOz5gp4BQ"
|
||||||
|
end
|
||||||
|
|
||||||
|
def template_type
|
||||||
|
:post
|
||||||
|
end
|
||||||
|
|
||||||
|
def posted_in
|
||||||
|
if name.nil?
|
||||||
|
:statuses
|
||||||
|
elsif post_type.to_sym == :book
|
||||||
|
:bookshelf
|
||||||
|
elsif location.nil?
|
||||||
|
:posts
|
||||||
|
else
|
||||||
|
:places
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def trips
|
||||||
|
__getobj__.trips
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_h
|
||||||
|
clean_content = CGI::unescapeHTML(content.gsub(/<\/?[^>]*>/, "")).strip
|
||||||
|
clean_content = clean_content.gsub(prefix_emoji[0], "") if prefix_emoji
|
||||||
|
{
|
||||||
|
id: slug,
|
||||||
|
emoji: prefix_emoji,
|
||||||
|
content: clean_content,
|
||||||
|
images: (inline_image_sources + photo_sources).compact,
|
||||||
|
published_at: display_published_at
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# e.g. geo:-37.75188,144.90417;u=35
|
||||||
|
def geo
|
||||||
|
loc = location.split(":")[1]
|
||||||
|
p = loc.split(";")[0]
|
||||||
|
|
||||||
|
p.split(",")
|
||||||
|
end
|
||||||
|
|
||||||
|
def truncate_html(content, len = 30, at_end = nil)
|
||||||
|
return content if content.to_s.length <= len
|
||||||
|
|
||||||
|
p = REXML::Parsers::PullParser.new(content)
|
||||||
|
tags = []
|
||||||
|
new_len = len
|
||||||
|
results = ""
|
||||||
|
while p.has_next? && new_len > 0
|
||||||
|
p_e = p.pull
|
||||||
|
case p_e.event_type
|
||||||
|
when :start_element
|
||||||
|
tags.push p_e[0]
|
||||||
|
results << "<#{tags.last}#{attrs_to_s(p_e[1])}>"
|
||||||
|
when :end_element
|
||||||
|
results << "</#{tags.pop}>"
|
||||||
|
when :text
|
||||||
|
results << p_e[0][0..new_len]
|
||||||
|
new_len -= p_e[0].length
|
||||||
|
else
|
||||||
|
results << "<!-- #{p_e.inspect} -->"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if at_end
|
||||||
|
results << "..."
|
||||||
|
end
|
||||||
|
tags.reverse_each do |tag|
|
||||||
|
results << "</#{tag}>"
|
||||||
|
end
|
||||||
|
results
|
||||||
|
end
|
||||||
|
|
||||||
|
def attrs_to_s(attrs)
|
||||||
|
if attrs.empty?
|
||||||
|
""
|
||||||
|
else
|
||||||
|
" " + attrs.to_a.map { |attr| %(#{attr[0]}="#{attr[1]}") }.join(" ")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
23
slices/admin/decorators/statuses/decorator.rb
Normal file
23
slices/admin/decorators/statuses/decorator.rb
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# frozen_string_literal: false
|
||||||
|
|
||||||
|
# auto_register: false
|
||||||
|
|
||||||
|
require "rexml/parsers/pullparser"
|
||||||
|
require "sanitize"
|
||||||
|
require "nokogiri"
|
||||||
|
|
||||||
|
module Admin
|
||||||
|
module Decorators
|
||||||
|
module Statuses
|
||||||
|
class Decorator < Main::Decorators::Posts::Decorator
|
||||||
|
def raw_content
|
||||||
|
res = Sanitize.fragment(content,
|
||||||
|
elements: ["img", "p"],
|
||||||
|
attributes: {"img" => ["alt", "src", "title"]})
|
||||||
|
|
||||||
|
res.gsub(prefix_emoji[0], "") if prefix_emoji
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@@ -2,14 +2,14 @@ div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:
|
|||||||
h1 Admin // Merge Tags
|
h1 Admin // Merge Tags
|
||||||
|
|
||||||
div class="max-w-prose mx-auto prose dark:prose-invert"
|
div class="max-w-prose mx-auto prose dark:prose-invert"
|
||||||
h3 Pick a tag to merge in to #{tag.label}
|
h3 Pick a tag to merge in to "#{post_tag.label}"
|
||||||
|
|
||||||
form action="/admin/tags/merge" method="POST"
|
form action="/admin/tags/merge" method="POST"
|
||||||
input type="hidden" name="target_id" value=tag.id
|
input type="hidden" name="target_id" value=post_tag.id
|
||||||
|
|
||||||
div class="mb-4"
|
div class="mb-4"
|
||||||
select class="text-gray-800" name="source_id"
|
select class="text-gray-800" name="source_id"
|
||||||
- tags.each do |source_tag|
|
- post_tags.each do |source_tag|
|
||||||
option value=source_tag.id
|
option value=source_tag.id
|
||||||
= source_tag.label
|
= source_tag.label
|
||||||
div class="mb-4"
|
div class="mb-4"
|
||||||
|
@@ -4,11 +4,11 @@ module Admin
|
|||||||
class New < Admin::View
|
class New < Admin::View
|
||||||
include Deps["repos.tag_repo"]
|
include Deps["repos.tag_repo"]
|
||||||
|
|
||||||
expose :tag do |id:|
|
expose :post_tag do |id:|
|
||||||
tag_repo.fetch(id)
|
tag_repo.fetch(id)
|
||||||
end
|
end
|
||||||
|
|
||||||
expose :tags do |id:|
|
expose :post_tags do |id:|
|
||||||
tag_repo.list.reject { |t| t.id.to_s == id.to_s }
|
tag_repo.list.reject { |t| t.id.to_s == id.to_s }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@@ -16,7 +16,7 @@ module Admin
|
|||||||
|
|
||||||
expose :posts do |trip|
|
expose :posts do |trip|
|
||||||
post_repo.created_between(trip.start_date, trip.end_date).map do |post|
|
post_repo.created_between(trip.start_date, trip.end_date).map do |post|
|
||||||
Adamantium::Decorators::Posts::Decorator.new(post)
|
Admin::Decorators::Posts::Decorator.new(post)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Reference in New Issue
Block a user