Created
August 28, 2012 16:46
-
-
Save saturnflyer/3500369 to your computer and use it in GitHub Desktop.
Radiant custom tag ideas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is from a production application of mine | |
def ExpertTag(tag) | |
tag.is_a?(ExpertTag) ? tag : ExpertTag.new(tag) | |
end | |
class ExpertTag | |
def initialize(radius_tag) | |
@radius_tag = radius_tag | |
end | |
def expand | |
@radius_tag.expand | |
end | |
def image | |
HtmlElement.new('img', {:src => profile_image, :self_closing => true }.merge(attrs)).to_s | |
end | |
def link | |
element = HtmlElement.new('a', attrs.merge('href' => path)) | |
element.open do |el| | |
if double? | |
el.write expand | |
else | |
el.write image | |
end | |
end | |
element.to_s | |
end | |
def path | |
'/experts/' + expert.permalink | |
end | |
def name | |
expert.name | |
end | |
def expertise | |
expert.expertise | |
end | |
def credentials | |
expert.credentials | |
end | |
private | |
def attrs | |
@radius_tag.attr | |
end | |
def double? | |
@radius_tag.double? | |
end | |
def profile_image | |
expert.profile_image | |
end | |
def expert | |
@expert ||= @radius_tag.locals.expert || Expert.last(:order => 'rand()') | |
end | |
end | |
# And an example of using this | |
desc %{ Scope the expert of the featured question. } | |
tag 'featured_question:expert' do |tag| | |
ExpertTag(tag).expand | |
end | |
desc %{ Output an image for the featured question's expert. } | |
tag 'featured_question:expert:image' do |tag| | |
ExpertTag(tag).image | |
end | |
desc %{ Output the name of the featured question's expert. } | |
tag 'featured_question:expert:name' do |tag| | |
ExpertTag(tag).name | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Current massive, ugly definition for the r:content tag: | |
tag 'content' do |tag| | |
page = tag.locals.page | |
part_name = tag_part_name(tag) | |
# Prevent simple and deep recursive rendering of the same page part | |
rendering_parts = (tag.locals.rendering_parts ||= Hash.new {|h,k| h[k] = []}) | |
if rendering_parts[page.id].include?(part_name) | |
raise TagError.new(%{Recursion error: already rendering the `#{part_name}' part.}) | |
else | |
rendering_parts[page.id] << part_name | |
end | |
inherit = boolean_attr_or_error(tag,'inherit',false) | |
part_page = page | |
if inherit | |
while (part_page.part(part_name).nil? and (not part_page.parent.nil?)) do | |
part_page = part_page.parent | |
end | |
end | |
contextual = boolean_attr_or_error(tag,'contextual', true) | |
part = part_page.part(part_name) | |
tag.locals.page = part_page unless contextual | |
result = tag.globals.page.render_snippet(part) unless part.nil? | |
rendering_parts[page.id].delete(part_name) | |
result | |
end | |
# Reading that makes so little sense. That is a massive procedure that can be clarified. | |
# class Page | |
# # this makes sense: | |
# tag_with Radiant::CustomTags::Content | |
# # but this feels like over-engineering: | |
# tag_with Radiant::CustomTags::IfContent | |
# end | |
module Radiant | |
module CustomTags | |
class RadiantTag | |
class << self | |
def description(text) | |
@description = text | |
end | |
def attribute(name, options={}) | |
@attributes ||= {} | |
@attributes[name] = options | |
end | |
def attributes | |
@attributes | |
end | |
end | |
def initialize(context) | |
@context = context | |
end | |
def local_scope | |
# tag.locals from a typical tag | |
end | |
end | |
class Content < RadiantTag | |
description %{Renders the main content of a page.} | |
attribute 'part', :default => 'body', | |
:description => %{Use this attribute to select a specific | |
page part. By default it is set to 'body'.} | |
attribute 'inherit', :options => :boolean, | |
:default => false, | |
:description => %{Use this attribute to specify that if a page does not have a content | |
part by that name that the tag should render the parent's content part.} | |
attribute 'contextual', :options => :boolean, | |
:default => true, | |
:description => %{Use this attribute to force a part inherited from a parent | |
part to be evaluated in the context of the child page.} | |
def call | |
# # Prevent simple and deep recursive rendering of the same page part | |
restrict_recursion and track_current_part | |
part_page = page | |
if inherit? | |
part_page = page_with_part(part_name) | |
end | |
local_scope.page = part_page unless contextual? | |
part = part_page.part(part_name) | |
@result = render_part(part) | |
untrack_current_part | |
self | |
end | |
def to_s | |
@result | |
end | |
alias :expand :to_s | |
def page | |
local_scope.page | |
end | |
def part_name | |
arguments['part'] || 'body' | |
end | |
def rendering_parts | |
@rendering_parts ||= (local_scope.rendering_parts ||= Hash.new {|h,k| h[k] = []}) | |
end | |
def render_part(part) | |
part.nil? ? '' : global_scope.page.render_snippet(part) | |
end | |
def inherit? | |
boolean_attr_or_error('inherit',false) | |
end | |
def page_with_part(part_name, rendering_page = page) | |
return rendering_page if rendering_page.has_part?(part_name) | |
if rendering_page.parent.nil? | |
rendering_page | |
else | |
page_with_part(part_name, rendering_page.parent) | |
end | |
end | |
def contextual? | |
boolean_attr_or_error('contextual', true) | |
end | |
private | |
def track_current_part | |
rendering_parts[page.id] << part_name | |
end | |
def untrack_current_part | |
rendering_parts[page.id].delete(part_name) | |
end | |
def rendering_current_part? | |
rendering_parts[page.id].include?(part_name) | |
end | |
def restrict_recursion | |
if rendering_current_part? | |
raise tag_error(%{Recursion error: already rendering the `#{part_name}' part.}) | |
end | |
true | |
end | |
def tag_error(message) | |
RadiantTag::TagError.new(message) | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment