Last active
December 21, 2015 05:29
-
-
Save kentcdodds/6257506 to your computer and use it in GitHub Desktop.
InfiniteWPM default files
This file contains hidden or 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
//Temp |
This file contains hidden or 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
(function(){ | |
var ENTER_KEYCODE = 13; | |
var DEFAULT_CAL_LABELS = document.createElement("x-calendar").labels; | |
function cloneDataMap(data){ | |
return JSON.parse(JSON.stringify(data)); | |
} | |
// Date utils | |
/** isValidDateObj: (*) => Boolean | |
simply checks if the given parameter is a valid date object | |
**/ | |
function isValidDateObj(d) { | |
return (d instanceof Date) && !!(d.getTime) && !isNaN(d.getTime()); | |
} | |
function getYear(d) { | |
return d.getUTCFullYear(); | |
} | |
function getMonth(d) { | |
return d.getUTCMonth(); | |
} | |
function getDate(d) { | |
return d.getUTCDate(); | |
} | |
/** pad: (Number, Number) => String | |
Pads a number with preceding zeros to be padSize digits long | |
If given a number with more than padSize digits, truncates the leftmost | |
digits to get to a padSize length | |
**/ | |
function pad(n, padSize) { | |
var str = n.toString(); | |
var padZeros = (new Array(padSize)).join('0'); | |
return (padZeros + str).substr(-padSize); | |
} | |
/** iso: Date => String | |
returns the ISO format representation of a date ("YYYY-MM-DD") | |
**/ | |
function iso(d) { | |
return [pad(getYear(d), 4), | |
pad(getMonth(d)+1, 2), | |
pad(getDate(d), 2)].join('-'); | |
} | |
/** fromIso: String => Date/null | |
Given a string, attempts to parse out a date in YYYY-MM-DD format | |
If successful, returns the corresponding Date object, otherwise return null | |
**/ | |
var ISO_DATE_REGEX = /(\d{4})[^\d]?(\d{2})[^\d]?(\d{2})/; | |
function fromIso(s){ | |
if (isValidDateObj(s)) return s; | |
var d = ISO_DATE_REGEX.exec(s); | |
if (d) { | |
return new Date(d[1],d[2]-1,d[3]); | |
} | |
else{ | |
return null; | |
} | |
} | |
/** parseSingleDate: String => Date/null | |
attempts to parse out the given string as a Date | |
If successful, returns the corresponding Date object, otherwise return null | |
Valid input formats include any format with a YYYY-MM-DD format or | |
is parseable by Date.parse | |
**/ | |
function parseSingleDate(dateStr){ | |
if(isValidDateObj(dateStr)) return dateStr; | |
// cross-browser check for ISO format that is not | |
// supported by Date.parse without implicit time zone | |
var isoParsed = fromIso(dateStr); | |
if(isoParsed){ | |
return isoParsed; | |
} | |
else{ | |
var parsedMs = Date.parse(dateStr); | |
if(!isNaN(parsedMs)){ | |
return new Date(parsedMs); | |
} | |
return null; | |
} | |
} | |
/** _validateDatepicker: DOM element => Boolean | |
checks the value of the datepicker and toggles the datepicker's "invalid" | |
attribute depending on if the value is a valid parsable date string or not | |
also returns true if the date passes validation and false otherwise | |
**/ | |
function _validateDatepicker(datepicker){ | |
var input = (datepicker.polyfill) ? | |
datepicker.xtag.polyfillInput : datepicker.xtag.dateInput; | |
var inputDate = parseSingleDate(input.value); | |
if(inputDate) | |
{ | |
datepicker.removeAttribute("invalid"); | |
} | |
else{ | |
datepicker.setAttribute("invalid", true); | |
} | |
return !!inputDate; | |
} | |
/** _updateDatepicker: (DOM element, boolean) | |
based on the value of the datepicker's input elements, update the value | |
attribute/property of the datepicker itself | |
if sendParsed is true, we preparse the value before assigning to | |
value, otherwise, send the original value | |
- (ie: if this is true, update the text value of the inputs with the | |
parsed version as well) | |
**/ | |
function _updateDatepicker(datepicker, sendParsed){ | |
var input = (datepicker.polyfill) ? | |
datepicker.xtag.polyfillInput : | |
datepicker.xtag.dateInput; | |
var rawVal = input.value; | |
var parsedDate = parseSingleDate(rawVal); | |
datepicker.value = (sendParsed && parsedDate) ? parsedDate : rawVal; | |
} | |
/* pass this a callback function to execute while being observed; | |
* if the submit value of the datepicker is changed during the callback, | |
* fire the change event on the datepicker; | |
* if alsoWatchRawVal is true, will also trigger a change event if the | |
* .value changes, not just if the .submitValue changes */ | |
function _watchForChange(datepicker, callback, alsoWatchRawVal){ | |
var oldVal = datepicker.submitValue; | |
var oldRawVal = datepicker.value; | |
callback(); | |
var newVal = datepicker.submitValue; | |
var newRawVal = datepicker.value; | |
if(oldVal !== newVal || (alsoWatchRawVal && oldRawVal !== newRawVal)) | |
{ | |
xtag.fireEvent(datepicker, "change"); | |
} | |
} | |
function getPlaceholderText(datepicker){ | |
var labels = datepicker.xtag._labels; | |
return (new Array(5).join(labels.yearAbbr) + "-" + | |
new Array(3).join(labels.monthAbbr) + "-" + | |
new Array(3).join(labels.dayAbbr)); | |
} | |
xtag.register("x-datepicker", { | |
lifecycle: { | |
created: function(){ | |
this.innerHTML = ""; | |
var dateInput = document.createElement("input"); | |
dateInput.setAttribute("type", "date"); | |
xtag.addClass(dateInput, "x-datepicker-input"); | |
this.appendChild(dateInput); | |
this.xtag.dateInput = dateInput; | |
// datepicker unique labels | |
this.xtag._labels = { | |
yearAbbr: "Y", | |
monthAbbr: "M", | |
dayAbbr: "D" | |
}; | |
// calendar-specific labels | |
this.xtag._polyfillCalLabels = cloneDataMap(DEFAULT_CAL_LABELS); | |
this.xtag.polyfillInput = null; | |
this.xtag.polyfillUI = null; | |
// initialize polyfill with detected support | |
this.polyfill = (this.hasAttribute("polyfill") || | |
dateInput.type.toLowerCase() !== "date"); | |
} | |
}, | |
events: { | |
// handle calendar UI input | |
"datetoggleon:delegate(x-calendar)": function(e){ | |
var xCal = this; | |
var datepicker = e.currentTarget; | |
if((!e.detail) || (!e.detail.date)){ | |
return; | |
} | |
var selectedDate = parseSingleDate(e.detail.date); | |
_watchForChange(datepicker, function(){ | |
datepicker.value = (selectedDate) ? iso(selectedDate) : ""; | |
xtag.fireEvent(datepicker, "input"); | |
}); | |
}, | |
"datetoggleoff:delegate(x-calendar)": function(e){ | |
e.currentTarget.value = null; | |
}, | |
"focus": function(e){ | |
e.currentTarget.setAttribute("focused", true); | |
}, | |
"blur:delegate(.x-datepicker-input)": function(e){ | |
e.currentTarget.removeAttribute("focused"); | |
}, | |
"blur:delegate(.x-datepicker-polyfill-input)": function(e){ | |
var datepicker = e.currentTarget; | |
datepicker.removeAttribute("focused"); | |
// send parsed version to ensure that text of input matches | |
_watchForChange(datepicker, function(){ | |
_updateDatepicker(datepicker, true); | |
}, true); | |
}, | |
// force readonly state as soon as touch event is detected | |
// to prevent mobile keyboard from popping up from now on | |
"touchstart:delegate(.x-datepicker-polyfill-input)": function(e){ | |
this.setAttribute("readonly", true); | |
}, | |
"tapstart:delegate(x-calendar)": function(e){ | |
e.preventDefault(); // prevent blurring of polyfill input | |
}, | |
"keypress:delegate(.x-datepicker-polyfill-input)": function(e){ | |
var keyCode = e.keyCode; | |
var datepicker = e.currentTarget; | |
if(keyCode === ENTER_KEYCODE){ | |
// send parsed version to ensure that text of input matches | |
_watchForChange(datepicker, function(){ | |
_updateDatepicker(datepicker, true); | |
}, true); | |
} | |
}, | |
// handle UI changes to the native date input | |
"input:delegate(.x-datepicker-input)": function(e){ | |
var datepicker = e.currentTarget; | |
_watchForChange(datepicker, function(){ | |
// send parsed version to ensure that value of native | |
// input matches | |
_updateDatepicker(datepicker, true); | |
// redirect event target | |
e.stopPropagation(); | |
xtag.fireEvent(datepicker, "input"); | |
}); | |
}, | |
// handles UI changes to the polyfill input | |
"input:delegate(.x-datepicker-polyfill-input)": function(e){ | |
// _DONT_ send parsed verison when using polyfill in order to | |
// prevent the input from constantly overriding the user's | |
// text as they are typing | |
var datepicker = e.currentTarget; | |
_watchForChange(datepicker, function(){ | |
_updateDatepicker(datepicker, false); | |
// redirect event target | |
e.stopPropagation(); | |
xtag.fireEvent(datepicker, "input"); | |
}); | |
}, | |
// simply redirect change event target if native | |
"change:delegate(.x-datepicker-input)": function(e){ | |
e.stopPropagation(); | |
xtag.fireEvent(e.currentTarget, "change"); | |
}, | |
"change:delegate(.x-datepicker-polyfill-input)": function(e){ | |
// change event is different for text input, | |
// so prevent from bubbling | |
e.stopPropagation(); | |
// _DONT_ send parsed verison when using polyfill in order to | |
// prevent the input from constantly overriding the user's | |
// text as they are typing | |
var datepicker = e.currentTarget; | |
_watchForChange(datepicker, function(){ | |
_updateDatepicker(datepicker, false); | |
}); | |
} | |
}, | |
accessors: { | |
"name": { | |
attribute: {selector: ".x-datepicker-input"}, | |
set: function(newName){ | |
var dateInput = this.xtag.dateInput; | |
if(newName === null || newName === undefined){ | |
dateInput.removeAttribute("name"); | |
} | |
else{ | |
dateInput.setAttribute("name", newName); | |
} | |
} | |
}, | |
// returns the value that should be submitted to a form | |
// note: even if no name attribute is present, still return what | |
// should be submitted for cases of dynamic submission | |
"submitValue":{ | |
get: function(){ | |
return this.xtag.dateInput.value; | |
} | |
}, | |
// handles the currently displayed value of the datepicker | |
"value": { | |
attribute: { | |
skip: true | |
}, | |
get: function(){ | |
return (this.polyfill) ? this.xtag.polyfillInput.value : | |
this.xtag.dateInput.value; | |
}, | |
// if given null/undefined, deletes the value; | |
// always saves either the date in ISO-format or empty | |
// if the input date is invalid to the dateinput | |
// (this is what actually gets submitted); | |
// if given a value different than the user-input-box value, | |
// updates the input's value to the parsed ISO date, otherwise | |
// leaves it alone (this is what the user sees) | |
set: function(rawDateVal){ | |
var parsedDate = parseSingleDate(rawDateVal); | |
var isoStr = (parsedDate) ? iso(parsedDate) : null; | |
var dateInput = this.xtag.dateInput; | |
var polyfillInput = this.xtag.polyfillInput; | |
var polyfillUI = this.xtag.polyfillUI; | |
// if prompted to remove value | |
if(rawDateVal === null || rawDateVal === undefined){ | |
this.removeAttribute("value"); | |
dateInput.value = ""; | |
if(polyfillInput){ | |
polyfillInput.value = ""; | |
} | |
if(polyfillUI){ | |
polyfillUI.chosen = null; | |
// note that we don't reset calendar's view, | |
// we may want to choose where we left off | |
} | |
} | |
else{ | |
var finalVal = (isoStr) ? isoStr : rawDateVal; | |
// only override input's text value if given something | |
// different, in order to prevent having us override | |
// text as the user types | |
var attrVal; | |
if(polyfillInput){ | |
if(rawDateVal !== polyfillInput.value){ | |
polyfillInput.value = finalVal; | |
attrVal = finalVal; | |
} | |
// otherwise, match the value attribute to whats | |
// displayed | |
else{ | |
attrVal = rawDateVal; | |
} | |
} | |
else{ | |
attrVal = finalVal; | |
} | |
this.setAttribute("value", attrVal); | |
// make sure the date input (ie: what actually | |
// would submit in a form) either contains a valid date | |
// or is blanked; also make sure calendar displays | |
// a valid date | |
if(isoStr){ | |
dateInput.value = isoStr; | |
if(polyfillUI){ | |
polyfillUI.chosen = parsedDate; | |
polyfillUI.view = parsedDate; | |
} | |
} | |
else{ | |
dateInput.value = ""; | |
if(polyfillUI){ | |
polyfillUI.chosen = null; | |
} | |
// note that we don't reset calendar view, as we | |
// may want to choose from where we left off | |
} | |
} | |
// update the "invalid" class of the datepicker | |
_validateDatepicker(this); | |
} | |
}, | |
// handles whether to display as a polyfill or not | |
// note: in polyfill mode, we essentially keep the original | |
// input, but as a hidden input that receives parsed dates only. | |
// In order to allow user-input, we show a second text input | |
// (which is nameless to prevent form submission) that is tied to | |
// a calendar UI element | |
"polyfill": { | |
attribute: {boolean: true}, | |
set: function(isPolyfill){ | |
var dateInput = this.xtag.dateInput; | |
// turn on polyfill elements (creating them if they | |
// aren't initialized yet) | |
if(isPolyfill){ | |
// hide the "true" submitted input from UI view | |
dateInput.setAttribute("type", "hidden"); | |
dateInput.setAttribute("readonly", true); | |
// create the "fake" input to act as a middleman | |
// between user input and the parsed-date-only input | |
if(!this.xtag.polyfillInput){ | |
var polyfillInput = document.createElement("input"); | |
xtag.addClass(polyfillInput, | |
"x-datepicker-polyfill-input"); | |
polyfillInput.setAttribute("type", "text"); | |
polyfillInput.setAttribute("placeholder", | |
getPlaceholderText(this)); | |
polyfillInput.value = this.xtag.dateInput.value; | |
this.xtag.polyfillInput = polyfillInput; | |
this.appendChild(polyfillInput); | |
} | |
this.xtag.polyfillInput.removeAttribute("disabled"); | |
// creates the calendar UI element to associate with | |
// the datepicker | |
if(!this.xtag.polyfillUI){ | |
var polyfillUI=document.createElement("x-calendar"); | |
xtag.addClass(polyfillUI, | |
"x-datepicker-polyfill-ui"); | |
polyfillUI.chosen = this.value; | |
polyfillUI.view = this.xtag.dateInput.value; | |
polyfillUI.controls = true; | |
polyfillUI.labels = this.xtag._polyfillCalLabels; | |
this.xtag.polyfillUI = polyfillUI; | |
this.appendChild(polyfillUI); | |
} | |
} | |
// turn off polyfill elements (but don't remove them) | |
else{ | |
dateInput.setAttribute("type", "date"); | |
dateInput.removeAttribute("readonly"); | |
var polyInput = this.xtag.polyfillInput; | |
if(polyInput){ | |
polyInput.setAttribute("disabled", true); | |
} | |
} | |
} | |
}, | |
"labels": { | |
get: function(){ | |
// merge both the datepicker-only and calendar-only | |
// labels into a single dict | |
var allLabels = {}; | |
var datepickerLabels = this.xtag._labels; | |
var calendarLabels = this.xtag._polyfillCalLabels; | |
for(var key in datepickerLabels){ | |
allLabels[key] = datepickerLabels[key]; | |
} | |
for(var key in calendarLabels){ | |
allLabels[key] = calendarLabels[key]; | |
} | |
// prevent any aliases from slipping through | |
return cloneDataMap(allLabels); | |
}, | |
set: function(newLabelData){ | |
var calendar = this.xtag.polyfillUI; | |
var polyInput = this.xtag.polyfillInput; | |
// set calendar labels | |
if(calendar){ | |
calendar.labels = newLabelData; | |
this.xtag._polyfillCalLabels = calendar.labels; | |
} | |
else{ | |
var polyLabels = this.xtag._polyfillCalLabels; | |
for(var key in polyLabels){ | |
if(key in newLabelData){ | |
polyLabels[key] = newLabelData[key]; | |
} | |
} | |
} | |
// replace datepicker specific labels | |
var datepickerLabels = this.xtag._labels; | |
for(var key in datepickerLabels){ | |
if(key in newLabelData){ | |
datepickerLabels[key] = newLabelData[key]; | |
} | |
} | |
// rerender placeholder text | |
if(polyInput){ | |
polyInput.setAttribute("placeholder", | |
getPlaceholderText(this)); | |
} | |
} | |
} | |
} | |
}); | |
})(); |
This file contains hidden or 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
class ArticlesController < ContentController | |
before_filter :login_required, :only => [:preview] | |
before_filter :auto_discovery_feed, :only => [:show, :index] | |
before_filter :verify_config | |
layout :theme_layout, :except => [:comment_preview, :trackback] | |
cache_sweeper :blog_sweeper | |
caches_page :index, :read, :archives, :view_page, :redirect, :if => Proc.new {|c| | |
c.request.query_string == '' | |
} | |
helper :'admin/base' | |
def index | |
respond_to do |format| | |
format.html { @limit = this_blog.limit_article_display } | |
format.rss { @limit = this_blog.limit_rss_display } | |
format.atom { @limit = this_blog.limit_rss_display } | |
end | |
unless params[:year].blank? | |
@noindex = 1 | |
@articles = Article.published_at(params.values_at(:year, :month, :day)).page(params[:page]).per(@limit) | |
else | |
@noindex = 1 unless params[:page].blank? | |
@articles = Article.published.page(params[:page]).per(@limit) | |
end | |
@page_title = index_title | |
@description = index_description | |
@keywords = (this_blog.meta_keywords.empty?) ? "" : this_blog.meta_keywords | |
suffix = (params[:page].nil? and params[:year].nil?) ? "" : "/" | |
@canonical_url = url_for(:only_path => false, :controller => 'articles', :action => 'index', :page => params[:page], :year => params[:year], :month => params[:month], :day => params[:day]) + suffix | |
respond_to do |format| | |
format.html { render_paginated_index } | |
format.atom do | |
render_articles_feed('atom') | |
end | |
format.rss do | |
auto_discovery_feed(:only_path => false) | |
render_articles_feed('rss') | |
end | |
end | |
end | |
def search | |
@canonical_url = url_for(:only_path => false, :controller => 'articles', :action => 'search', :page => params[:page], :q => params[:q]) | |
@articles = this_blog.articles_matching(params[:q], :page => params[:page], :per_page => @limit) | |
return error(_("No posts found..."), :status => 200) if @articles.empty? | |
@page_title = this_blog.search_title_template.to_title(@articles, this_blog, params) | |
@description = this_blog.search_desc_template.to_title(@articles, this_blog, params) | |
respond_to do |format| | |
format.html { render 'search' } | |
format.rss { render "index_rss_feed", :layout => false } | |
format.atom { render "index_atom_feed", :layout => false } | |
end | |
end | |
def live_search | |
@search = params[:q] | |
@articles = Article.search(@search) | |
render :live_search, :layout => false | |
end | |
def preview | |
@article = Article.last_draft(params[:id]) | |
@canonical_url = "" | |
render 'read' | |
end | |
def check_password | |
return unless request.xhr? | |
@article = Article.find(params[:article][:id]) | |
if @article.password == params[:article][:password] | |
render :partial => 'articles/full_article_content', :locals => { :article => @article } | |
else | |
render :partial => 'articles/password_form', :locals => { :article => @article } | |
end | |
end | |
def redirect | |
from = split_from_path params[:from] | |
match_permalink_format from, this_blog.permalink_format | |
return show_article if @article | |
# Redirect old version with /:year/:month/:day/:title to new format, | |
# because it's changed | |
["%year%/%month%/%day%/%title%", "articles/%year%/%month%/%day%/%title%"].each do |part| | |
match_permalink_format from, part | |
return redirect_to @article.permalink_url, :status => 301 if @article | |
end | |
r = Redirect.find_by_from_path(from.join("/")) | |
return redirect_to r.full_to_path, :status => 301 if r | |
render "errors/404", :status => 404 | |
end | |
### Deprecated Actions ### | |
def archives | |
@articles = Article.find_published | |
@page_title = this_blog.archives_title_template.to_title(@articles, this_blog, params) | |
@keywords = (this_blog.meta_keywords.empty?) ? "" : this_blog.meta_keywords | |
@description = this_blog.archives_desc_template.to_title(@articles, this_blog, params) | |
@canonical_url = url_for(:only_path => false, :controller => 'articles', :action => 'archives') | |
end | |
def comment_preview | |
if (params[:comment][:body].blank? rescue true) | |
render :nothing => true | |
return | |
end | |
set_headers | |
@comment = Comment.new(params[:comment]) | |
@controller = self | |
end | |
def category | |
redirect_to categories_path, :status => 301 | |
end | |
def tag | |
redirect_to tags_path, :status => 301 | |
end | |
def view_page | |
if(@page = Page.find_by_name(Array(params[:name]).map { |c| c }.join("/"))) && @page.published? | |
@page_title = @page.title | |
@description = (this_blog.meta_description.empty?) ? "" : this_blog.meta_description | |
@keywords = (this_blog.meta_keywords.empty?) ? "" : this_blog.meta_keywords | |
@canonical_url = @page.permalink_url | |
else | |
render "errors/404", :status => 404 | |
end | |
end | |
# TODO: Move to TextfilterController? | |
def markup_help | |
render :text => TextFilter.find(params[:id]).commenthelp | |
end | |
private | |
def verify_config | |
if ! this_blog.configured? | |
redirect_to :controller => "setup", :action => "index" | |
elsif User.count == 0 | |
redirect_to :controller => "accounts", :action => "signup" | |
else | |
return true | |
end | |
end | |
# See an article We need define @article before | |
def show_article | |
@comment = Comment.new | |
@page_title = this_blog.article_title_template.to_title(@article, this_blog, params) | |
@description = this_blog.article_desc_template.to_title(@article, this_blog, params) | |
article_meta | |
auto_discovery_feed | |
respond_to do |format| | |
format.html { render "articles/#{@article.post_type}" } | |
format.atom { render_feedback_feed('atom') } | |
format.rss { render_feedback_feed('rss') } | |
format.xml { render_feedback_feed('atom') } | |
end | |
rescue ActiveRecord::RecordNotFound | |
error("Post not found...") | |
end | |
def article_meta | |
groupings = @article.categories + @article.tags | |
@keywords = groupings.map { |g| g.name }.join(", ") | |
@canonical_url = @article.permalink_url | |
end | |
def render_articles_feed format | |
if this_blog.feedburner_url.empty? or request.env["HTTP_USER_AGENT"] =~ /FeedBurner/i | |
render "index_#{format}_feed", :layout => false | |
else | |
redirect_to "http://feeds2.feedburner.com/#{this_blog.feedburner_url}" | |
end | |
end | |
def render_feedback_feed format | |
@feedback = @article.published_feedback | |
render "feedback_#{format}_feed", :layout => false | |
end | |
def set_headers | |
headers["Content-Type"] = "text/html; charset=utf-8" | |
end | |
def render_paginated_index(on_empty = _("No posts found...")) | |
return error(on_empty, :status => 200) if @articles.empty? | |
if this_blog.feedburner_url.empty? | |
auto_discovery_feed(:only_path => false) | |
else | |
@auto_discovery_url_rss = "http://feeds2.feedburner.com/#{this_blog.feedburner_url}" | |
@auto_discovery_url_atom = "http://feeds2.feedburner.com/#{this_blog.feedburner_url}" | |
end | |
render 'index' | |
end | |
def index_title | |
if params[:year] | |
return this_blog.archives_title_template.to_title(@articles, this_blog, params) | |
elsif params[:page] | |
return this_blog.paginated_title_template.to_title(@articles, this_blog, params) | |
else | |
this_blog.home_title_template.to_title(@articles, this_blog, params) | |
end | |
end | |
def index_description | |
if params[:year] | |
return this_blog.archives_desc_template.to_title(@articles, this_blog, params) | |
elsif params[:page] | |
return this_blog.paginated_desc_template.to_title(@articles, this_blog, params) | |
else | |
this_blog.home_desc_template.to_title(@articles, this_blog, params) | |
end | |
end | |
def time_delta(year, month = nil, day = nil) | |
from = Time.mktime(year, month || 1, day || 1) | |
to = from.next_year | |
to = from.next_month unless month.blank? | |
to = from + 1.day unless day.blank? | |
to = to - 1 # pull off 1 second so we don't overlap onto the next day | |
return from..to | |
end | |
def split_from_path path | |
parts = path.split '/' | |
parts.delete('') | |
if parts.last =~ /\.atom$/ | |
request.format = 'atom' | |
parts.last.gsub!(/\.atom$/, '') | |
elsif parts.last =~ /\.rss$/ | |
request.format = 'rss' | |
parts.last.gsub!(/\.rss$/, '') | |
end | |
parts | |
end | |
def match_permalink_format parts, format | |
specs = format.split('/') | |
specs.delete('') | |
return if parts.length != specs.length | |
article_params = {} | |
specs.zip(parts).each do |spec, item| | |
if spec =~ /(.*)%(.*)%(.*)/ | |
before_format = $1 | |
format_string = $2 | |
after_format = $3 | |
result = item.gsub(/^#{before_format}(.*)#{after_format}$/, '\1') | |
article_params[format_string.to_sym] = result | |
else | |
return unless spec == item | |
end | |
end | |
begin | |
@article = this_blog.requested_article(article_params) | |
rescue | |
#Not really good. | |
# TODO :Check in request_article type of DATA made in next step | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment