class Strelka::CMS::Page
An abstraction of a page with markup. This class provides rendering and introspection facilities for page files on disk. A page file is a plain file with a .page extension that contains some content to be rendered for the docs site, and is of the form:
--- | - YAML document separator title: My Brilliant Document | - An optional YAML header, see filters: | - apilinks | - links | - syntax | - editorial | - textile | | --- | - Document separator h1. My Brilliant Document | - Document contents which will | will be transformed by the This is a document with some stuff in | configured filters. it. It rules you. Like my teeth. | |
Constants
- DEFAULT_OPTIONS
The default page options.
- PAGE_WITH_YAML_HEADER
Pattern to match a source page with a YAML header
Attributes
The page's catalog (if it was loaded via one)
The page's content
The Time the page object was instantiated
The Array of filter names that will be applied to the rendered output, in the order they will be applied.
Any additional options in the header
The path to the page (if loaded from a file, nil otherwise)
The path to the Inversion template to wrap the page content in
The page title given in the page config
Public Class Methods
Read page source from the file at the given path
and return a new Page
object.
# File lib/strelka/cms/page.rb, line 63 def self::load( path, catalog=nil ) page = File.open( path, 'r', encoding: 'utf-8' ) do |io| self.read( io, catalog ) end page.path = path return page end
Create a new Page
with the specified content
and options
.
# File lib/strelka/cms/page.rb, line 105 def initialize( content, catalog=nil, options={} ) # If there's no catalog, the options might be in its place if catalog.is_a?( Hash ) options = catalog catalog = nil end @content = content @catalog = catalog options = DEFAULT_OPTIONS.merge( options ) @tags = options.delete( 'tags' ) || options.delete( 'keywords' ) @title = options.delete( 'title' ) @filters = options.delete( 'filters' ) @template = options.delete( 'template' ) @options = options @created = Time.now @article = nil @path = nil end
Parse the given source
and return a new Page
object.
# File lib/strelka/cms/page.rb, line 83 def self::parse( source, catalog=nil ) options = nil if source =~ PAGE_WITH_YAML_HEADER self.log.debug "Parsing page with YAML header..." options = YAML.load( $1 ) source = $2 self.log.debug " YAML header options: %p" % [ options ] else self.log.debug "Parsing page with no header." options = {} end return new( source, catalog, options ) end
Read page source from the given io
and return a new Page
object.
# File lib/strelka/cms/page.rb, line 75 def self::read( io, catalog=nil ) source = io.read self.log.debug "Read %d bytes from %p" % [ source.length, io ] page = self.parse( source, catalog ) end
Public Instance Methods
Apply the filters corresponding to the given filter_names
and return the modified content
.
# File lib/strelka/cms/page.rb, line 183 def apply_filters( content ) filters = self.filter_objects self.log.debug "Applying %d filters to %d bytes of content: %p" % [ filters.length, content.length, content[0,100] ] return filters.inject( self.content.dup ) do |filtered_content, filter| begin filter.process( filtered_content, self ) rescue => err self.log.error "%s while applying the %s filter: %s" % [ err.class.name, filter.class.factory_type, err.message ] self.log.debug " " + err.backtrace.join("\n ") filtered_content end end end
Return the page's filters as instances of Strelka::CMS::PageFilter
.
# File lib/strelka/cms/page.rb, line 202 def filter_objects return self.filters.map do |filter_name| filter_name.untaint Strelka::CMS::PageFilter.create( filter_name ) end end
Return the contents of the first heading from the rendered page.
# File lib/strelka/cms/page.rb, line 211 def first_heading self.log.debug "Fetching page title from rendered page" doc = Nokogiri::HTML( self.to_s ) if heading = doc.css( 'h1,h2,h3' ).first self.log.debug " got first heading: %s" % [ heading ] return heading.content else self.log.debug " couldn't find a heading." return nil end end
Extract a Hash of fields to be indexed from the page and return it.
# File lib/strelka/cms/page.rb, line 253 def index_fields return { :title => self.title, :first_heading => self.first_heading, :tags => self.tags.join( ', ' ), :content => self.stripped_content, :modified => self.modified, :created => self.created, } end
Return a human-readable representation of the receiving object.
# File lib/strelka/cms/page.rb, line 305 def inspect return %|#<%s:%#0x %p %p [%s] {filters: %s}>| % [ self.class.name, self.object_id / 2, self.path, self.title, self.tags.join(', '), self.filters.join('+'), ] end
Return the Time the page was last modified. This is derived from its 'date' header if it has one, or its mtime if it was loaded from a file, or its created
date if neither of those are available.
# File lib/strelka/cms/page.rb, line 268 def modified if headerdate = self.options['date'] headerdate = headerdate.to_time if headerdate.respond_to?( :to_time ) headerdate = Time.parse( headerdate ) unless headerdate.is_a?( Time ) return headerdate elsif self.path return self.path.mtime else return self.created end end
Set the path to the page.
# File lib/strelka/cms/page.rb, line 160 def path=( newpath ) @path = Pathname( newpath ) end
Return the page's HTML path.
# File lib/strelka/cms/page.rb, line 175 def relative_html_path pagepath = self.relative_path or return nil return pagepath.to_s.sub(/\.page$/, '.html') end
Return the page's path relative to its catalog.
# File lib/strelka/cms/page.rb, line 166 def relative_path catalog = self.catalog or return nil path = self.path or return nil return path.relative_path_from( catalog.basedir ) end
Return the page rendered as HTML after applying filters and wrapping it in its configured template if it has one.
# File lib/strelka/cms/page.rb, line 226 def render( * ) if path = self.template self.log.debug "Wrapping %p in template at %p" % [ self, path ] tmpl = Inversion::Template.load( path ) tmpl.page = self return tmpl else return self.to_s end end
Return the page content with tags stripped.
# File lib/strelka/cms/page.rb, line 247 def stripped_content return self.content.gsub( /<.*?>/, '' ) end
Return a summary of the page.
# File lib/strelka/cms/page.rb, line 283 def summary summary = self.article.summarize( sentences: 1 ).first return summary[:sentence].strip end
Return an Array of topics for the page.
# File lib/strelka/cms/page.rb, line 290 def summary_topics return self.article.topics end
Render the page content, filtering it with its configured filters. Note that this does not wrap it in its template.
# File lib/strelka/cms/page.rb, line 240 def to_s return self.apply_filters( self.content ) end
Protected Instance Methods
Derive a summary and topics from the stripped contents of the page. This populates summary
and summary_topics
.
# File lib/strelka/cms/page.rb, line 323 def article @article ||= OTS.parse( self.stripped_content ) return @article end