class Decidim::ContentParsers::ParagraphParser

A parser that searches mentions of Paragraphs in content.

This parser accepts two ways for linking Paragraphs.

For example ‘~1234`, but no `~ 1234`.

Also fills a ‘Metadata#linked_paragraphs` attribute.

@see BaseParser Examples of how to use a content parser

Constants

ID_REGEX

Matches a mentioned Paragraph ID (~(d)+ expression)

Metadata

Class used as a container for metadata

@!attribute linked_paragraphs

@return [Array] an array of Decidim::EnhancedTextwork::Paragraph mentioned in content
URL_REGEX
URL_REGEX_CONTENT
URL_REGEX_END_CHAR
URL_REGEX_SCHEME

Matches a URL

Attributes

metadata[R]

(see BaseParser#metadata)

Public Class Methods

new(content, context) click to toggle source
Calls superclass method
# File lib/decidim/content_parsers/paragraph_parser.rb, line 30
def initialize(content, context)
  super
  @metadata = Metadata.new([])
end

Public Instance Methods

rewrite() click to toggle source

Replaces found mentions matching an existing Paragraph with a global id for that Paragraph. Other mentions found that doesn’t match an existing Paragraph are returned as they are.

@return [String] the content with the valid mentions replaced by a global id.

# File lib/decidim/content_parsers/paragraph_parser.rb, line 40
def rewrite
  rewrited_content = parse_for_urls(content)
  parse_for_ids(rewrited_content)
end

Private Instance Methods

find_paragraph_by_id(id) click to toggle source
# File lib/decidim/content_parsers/paragraph_parser.rb, line 90
def find_paragraph_by_id(id)
  if id.present?
    spaces = Decidim.participatory_space_manifests.flat_map do |manifest|
      manifest.participatory_spaces.call(context[:current_organization]).public_spaces
    end
    components = Component.where(participatory_space: spaces).published
    Decidim::EnhancedTextwork::Paragraph.where(component: components).find_by(id: id)
  end
end
paragraph_from_id_match(match) click to toggle source
# File lib/decidim/content_parsers/paragraph_parser.rb, line 85
def paragraph_from_id_match(match)
  paragraph_id = match
  find_paragraph_by_id(paragraph_id)
end
paragraph_from_url_match(match) click to toggle source
# File lib/decidim/content_parsers/paragraph_parser.rb, line 74
def paragraph_from_url_match(match)
  uri = URI.parse(match)
  return if uri.path.blank?

  paragraph_id = uri.path.split("/").last
  find_paragraph_by_id(paragraph_id)
rescue URI::InvalidURIError
  Rails.logger.error("#{e.message}=>#{e.backtrace}")
  nil
end
parse_for_ids(content) click to toggle source
# File lib/decidim/content_parsers/paragraph_parser.rb, line 62
def parse_for_ids(content)
  content.gsub(ID_REGEX) do |match|
    paragraph = paragraph_from_id_match(Regexp.last_match(1))
    if paragraph
      @metadata.linked_paragraphs << paragraph.id
      paragraph.to_global_id
    else
      match
    end
  end
end
parse_for_urls(content) click to toggle source
# File lib/decidim/content_parsers/paragraph_parser.rb, line 50
def parse_for_urls(content)
  content.gsub(URL_REGEX) do |match|
    paragraph = paragraph_from_url_match(match)
    if paragraph
      @metadata.linked_paragraphs << paragraph.id
      paragraph.to_global_id
    else
      match
    end
  end
end