This section describes how to use the ::MarkdownRecord::ContentFragment
model to easily interact with your written markdown content from your application code.
Each file and directory in the content
directory that gets rendered as either HTML or JSON will have a content fragment JSON object created for it that represents that source file. These JSON objects get stored in the corresponding file with a _fragments
suffix.
In your application code, you can interact with content fragment JSON objects via the ::MarkdownRecord::ContentFragment
model. This model is a child class of ::MarkdownRecord::Base
and adds the following attributes:
meta<Hash>
concatenated<Boolean>
The meta
attribute contains a Hash
populated with any data you that you defined using the fragment
or directory_fragment
content DSL methods.
concatentated
will be auto-populated during rendering and will be true for fragments representing a directory, and false for those representing files.
You can query content fragments just like you query other MarkdownRecord models, but these queries will only return content fragments. Using filter values that are Hashes, however, will allow you to query and filter content fragments based on their meta
attributes.
Content fragments also have a few extra associations, which are:
ancestors
: the content fragments above the current fragment in the content structure.ancestors_from
: the content fragments above the current fragment in the content structure, starting with a content fragment or content fragment id that is passed in.parent
: the content fragment directly above the current fragment in the content structure.Each of the above associations use the file tree structure, meaning that they will only return content fragments representing directories.
The parent
method, however, can have its behavior overridden by setting a parent_id
field in the meta
hash of the content fragment to the id of another content fragment using the Content DSL.
For example, the file that this text is written in is at content/7_content_frags.md
, meaning that the parent of the directory level content fragment with id = "content/content_frags"
would normally be the directory level content fragment with id = "content"
.
In code, this would look like:
MarkdownRecord::ContentFragment.find("content/content_frags").parent
=> #<MarkdownRecord::ContentFragment concatenated: true, filename: "content", id: "content", meta: {"name"=>"Demo", ...}, subdirectory: "", type: "markdown_record/content_fragment">
But this file uses the Content DSL to define meta data for the content fragment corresponding to it, like so:
<!--directory_fragment { "name": "Content Fragments", "parent_id": "content/home" } -->
The parent_id
in the meta
hash overrides the default behavior, which changes what fragment is returned from parent
:
MarkdownRecord::ContentFragment.find("content/content_frags").parent
=> #<MarkdownRecord::ContentFragment concatenated: false, filename: "home", id: "content/home", meta: {"name"=>"Home", ...}, subdirectory: "content", type: "markdown_record/content_fragment">
The ability to override the natural parent
of a content fragment is useful for constructing a list or hierarchy of content that is not strictly based on file structure. The parents_from
method is useful in doing this, as it builds a hierarchy but respect any parent_id
of the content fragments it comes across instead of assuming the containing directory is the parent. This is useful for constructing breadcrumbs and navigation in your views.
Exampe:
MarkdownRecord::ContentFragment.find("content/sandbox/foo")
.parents_from("content/home")
.map(&:id)
=> ["content/home", "content/sandbox"]
As an alternative to parent_id
, you can use relative_parent_id
which does the same thing, but accepts an id that is relative to the current file's containing directory. For example, the previous exampel would use home
instead of content/home
to assign the same fragment as the parent if the current file was in content
.
MarkdownRecord::ContentFragment
has the following instance methods:
exists?
: returns true
or
false`depending on whether a JSON or HTML file corresponding to the content fragment can be found. This should always return
true` unless something has gone wrong with the rendering process.json_exists?
: returns true
if a corresponding JSON files can be found.html_exists?
: returns true
if a corresponding HTML files can be found.read_json
: reads the corresponding JSON file.read_html
: reads the corresponding HTML file.json_path
: returns the path to the corresponding JSON file.html_path
: returns the path to the corresponding HTML file.find_relative
: does the same thing as MarkdownRecord::ContentFragment.find
, but is an instance method and finds another content fragment based on a retative path/id provided.The above content was rendered from source files at: content/v_0_1/content_frags