]> gitweb.mndrdr.org Git - arelpe.git/commitdiff
Better handling of empty slugs particularly when set via API
authorAidan Cornelius-Bell <[email protected]>
Thu, 9 Jan 2025 03:46:25 +0000 (14:16 +1030)
committerAidan Cornelius-Bell <[email protected]>
Thu, 9 Jan 2025 03:46:25 +0000 (14:16 +1030)
app/assets/stylesheets/application.css
app/models/post.rb
app/views/pubview/post.html.erb

index 5ec205efb85722d8de523516de845c66ba609df9..3b75d9a35a9ce8a18ea614d83af2de80ac455bd8 100644 (file)
@@ -742,6 +742,10 @@ ul .post-item a:visited {
     .button {
         margin-bottom: 4px;
     }
+
+    .button-bottomless {
+        margin-bottom: -8px;
+    }
 }
 
 /* Margin Notes/Footnotes */
index c763de59dcff3e28be30db62839aedd45386a7e6..b76a935405affc90ac0f143e0b8fe3e117620727 100644 (file)
@@ -3,26 +3,28 @@ class Post < ApplicationRecord
 
   validates :post_type, presence: true, inclusion: { in: %w[dispatch bookmark] }
   validates :title, presence: true
-  validates :slug, presence: true, uniqueness: true, if: :dispatch?
+  validates :slug, uniqueness: true, allow_nil: true
   validates :published_at, presence: true, if: :dispatch?
   validates :content, presence: true, if: :dispatch?
   validates :url, presence: true, if: :bookmark?
 
   before_validation :set_slug, if: :new_record?
   before_validation :set_title_from_url, if: -> { bookmark? && title.blank? }
+  after_create :ensure_slug_present
+  after_update :ensure_slug_present
 
   scope :dispatches, -> { where(post_type: 'dispatch') }
   scope :bookmarks, -> { where(post_type: 'bookmark') }
 
   def self.get_posts_and_bookmarks_with_pagination(page, per_page, filter)
     posts = case filter
-            when 'posts'
+    when 'posts'
               dispatches
-            when 'bookmarks'
+    when 'bookmarks'
               bookmarks
-            else
+    else
               all
-            end
+    end
 
     posts.order(published_at: :desc).page(page).per(per_page)
   end
@@ -56,30 +58,40 @@ class Post < ApplicationRecord
     tags.split(/\s*(?:,|\s+and)\s*/).map { |tag| "<code>#{tag.strip}</code>" }.join(', ') + '.'
   end
 
-  def generate_excerpt(max_length = 1040, take = 10)
+  def generate_excerpt(max_length = 210)
     return "" if content.blank?
 
     stripped_content = ActionController::Base.helpers.strip_tags(content)
-    excerpt = stripped_content.split('.') if stripped_content.split('.')
-    excerpt = excerpt.take(take)
-    excerpt = excerpt.join('.')
+    excerpt = stripped_content.split('.').first || stripped_content[0...max_length]
     excerpt = excerpt[0...max_length] if excerpt.length > max_length
     excerpt.gsub!("Dear friends,", "")
+    excerpt.gsub!(/\s+/, ' ')
     excerpt.strip
   end
 
   private
 
   def set_slug
-    self.slug = title.present? ? title.parameterize : nil
+    return if slug.present?
+
+    if title.present?
+      self.slug = title.parameterize
+    elsif bookmark?
+      # For bookmarks without a title, create a slug based on the URL's domain
+      uri = URI.parse(url)
+      domain_slug = uri.host.gsub(/^www\./, '').parameterize
+      timestamp = Time.current.strftime('%Y%m%d%H%M%S')
+      self.slug = "#{domain_slug}-#{timestamp}"
+    end
+  rescue URI::InvalidURIError
+    # If URL parsing fails, fall back to UUID
+    self.slug = "bookmark-#{SecureRandom.uuid}"
   end
 
   def set_published_at
     self.published_at ||= Time.current
   end
 
-  private
-
   def set_title_from_url
     return unless bookmark? && url.present? && title.blank?
 
@@ -94,4 +106,26 @@ class Post < ApplicationRecord
       self.title = "Bookmark"
     end
   end
+
+  def ensure_slug_present
+    return if slug.present?
+
+    # Generate a fallback slug if none exists
+    fallback_slug = if title.present?
+      base_slug = title.parameterize
+      slug = base_slug
+      counter = 1
+      # Ensure uniqueness
+      while Post.where.not(id: id).exists?(slug: slug)
+        slug = "#{base_slug}-#{counter}"
+        counter += 1
+      end
+      slug
+    else
+      "bookmark-#{SecureRandom.uuid}"
+    end
+
+    # Use update_column to skip validations and callbacks
+    update_column(:slug, fallback_slug)
+  end
 end
index d338a1dc6e3e315f784d369dcd1b4a220d9ff6a3..67a37db0474a404f45755450ae98299ce8a7b0e4 100644 (file)
        <p ><% if [email protected]_dispatch?%>About a <%= @reading_time %> minute read, p<% else %>P<% end %>osted <%= @post.published_at.strftime('%B %d, %Y') %> and tagged <%= raw @post.format_tags %></p>
   </div>
   <% else %>
-  <h1 style="margin-bottom: -.8em">Bookmark comment permalink:</h1>
-  <h3><%= @post.title %></h3>
+<h3 class="post_siteheading">Aidan Cornelius-Bellโ€™s mind reader:</h3>
+<h1 class="post_title"><%= @post.title %></h1>
   <div class="bookmark-buttons">
     <%= link_to "๐Ÿ‘ View linked content", @post.url, class: "button button-bottomless", target: "_BLANK" %>
     <%= link_to "๐Ÿ—ž More from mind reader", "#{root_path}", class: "button button-bottomless" %>
   </div>
   <div class="postmeta">
-       <p>Originally bookmarked on mind reader on <%= @post.published_at.strftime('%B %d, %Y') %>.</p>
+       <p>A link to third party content first shared on mind reader on <%= @post.published_at.strftime('%B %d, %Y') %>.</p>
   </div>
   <% end %>
 </div>
     <% end %>
        <%= raw @rendered_content %>
 
- <%= render partial: "layouts/post_navigation" %>
-  <hr class="foot_separator">
+ <% if @post.post_type != "bookmark" %>
+     <%= render partial: "layouts/post_navigation" %>
+    <hr class="foot_separator">
+ <% end %>
   </div>
 </div>