Add initial template, based on Elijah Miller's fancy site
http://jqr.github.com/
This commit is contained in:
parent
52feb477fb
commit
ac1865612a
|
@ -0,0 +1,99 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
|
<title>
|
||||||
|
{% if page.title %}
|
||||||
|
{{ page.title }} //
|
||||||
|
{% endif %}
|
||||||
|
R. Tyler Croy
|
||||||
|
</title>
|
||||||
|
<meta name="author" content="Elijah Miller" />
|
||||||
|
{% if page.summary %}
|
||||||
|
<meta namne="description" content="{{ page.summary }}" />
|
||||||
|
{% endif %}
|
||||||
|
<link href="http://feeds.feedburner.com/UnethicalBlogger" rel="alternate" title="unethical blogger" type="application/atom+xml" />
|
||||||
|
|
||||||
|
<link rel="stylesheet" href="/stylesheets/syntax.css" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="/stylesheets/default.css" type="text/css" />
|
||||||
|
|
||||||
|
{% for css in page.css %}
|
||||||
|
<link rel="stylesheet" href="{{ css }}" type="text/css" />
|
||||||
|
{% endfor %}
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="site">
|
||||||
|
<a id="subscribe" href="http://feeds.feedburner.com/UnethicalBlogger"><img src="/images/rss.png" alt="Subscribe to RSS Feed" /></a>
|
||||||
|
|
||||||
|
<div id="search_area" style="display: none">
|
||||||
|
<label for="search" style="display: none">Search</label>
|
||||||
|
<img src="http://www.famfamfam.com/lab/icons/silk/icons/cancel.png" alt="X"/>
|
||||||
|
<input id="search" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1><a href="/">R. Tyler Croy</a></h1>
|
||||||
|
|
||||||
|
<div class="clear"></div>
|
||||||
|
|
||||||
|
<div id="sidebar" class="vcard">
|
||||||
|
<h3>Me</h3>
|
||||||
|
<dl id="contact">
|
||||||
|
<dt>Name</dt>
|
||||||
|
<dd><a class="fn url" href="/">R. Tyler Croy</a> / <span class="nickname">agentdero</span></dd>
|
||||||
|
|
||||||
|
<dt>Email</dt>
|
||||||
|
<dd class="email"><a href="mailto:tyler@linux.com">tyler@linux.com</a></dd>
|
||||||
|
|
||||||
|
<dt>Company</dt>
|
||||||
|
<dd class="org"><a href="http://www.mylookout.com/">Lookout, Inc.</a></dd>
|
||||||
|
</dl>
|
||||||
|
<h3>And then some</h3>
|
||||||
|
<ul id="profiles">
|
||||||
|
<li><a href="http://identi.ca/agentdero">Identi.ca</a></li>
|
||||||
|
|
||||||
|
<li><a href="http://twitter.com/agentdero">Twitter</a></li>
|
||||||
|
|
||||||
|
<li><a href="http://github.com/rtyler">GitHub</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="adr">
|
||||||
|
<span class="locality">Berkeley</span>
|
||||||
|
<span class="region">CA</span>
|
||||||
|
<span class="postal-code"></span>
|
||||||
|
<span class="country-name">USA</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6/prototype.js"></script>
|
||||||
|
|
||||||
|
<div id="content">
|
||||||
|
{{ content }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="clear"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% for js in page.javascript %}
|
||||||
|
<script type="text/javascript" src="{{ js }}"></script>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
//<![CDATA[
|
||||||
|
(function() {
|
||||||
|
var links = document.getElementsByTagName('a');
|
||||||
|
var query = '?';
|
||||||
|
for(var i = 0; i < links.length; i++) {
|
||||||
|
if(links[i].href.indexOf('#disqus_thread') >= 0) {
|
||||||
|
query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.write('<script type="text/javascript" src="http://disqus.com/forums/unethicalblogger/get_num_replies.js' + query + '"></' + 'script>');
|
||||||
|
})();
|
||||||
|
//]]>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,20 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
---
|
||||||
|
|
||||||
|
<div id="post">
|
||||||
|
<h2>{{ page.title }}</h2>
|
||||||
|
{{ content }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="related">
|
||||||
|
<h3>Related Posts</h3>
|
||||||
|
<ul class="posts">
|
||||||
|
{% for post in site.related_posts limit:3 %}
|
||||||
|
<li><span>{{ post.date | date_to_string }}</span> » <a href="{{ post.url }}">{{ post.title }}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="disqus_thread"></div><script type="text/javascript" src="http://disqus.com/forums/jqr/embed.js"></script><noscript><a href="http://jqr.disqus.com/?url=ref">View comments.</a></noscript>
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||||
|
<meta http-equiv="refresh" content="0;url={{ page.refresh_to_post_id }}.html" />
|
||||||
|
</head>
|
||||||
|
</html>
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
layout: nil
|
||||||
|
---
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
||||||
|
|
||||||
|
<title>unethical blogger</title>
|
||||||
|
<link href="http://unethicalblogger.com/atom.xml" rel="self"/>
|
||||||
|
<link href="http://unethicalblogger.com/"/>
|
||||||
|
<updated>{{ site.time | date_to_xmlschema }}</updated>
|
||||||
|
<id>http://unethicalblogger.com/</id>
|
||||||
|
<author>
|
||||||
|
<name>R. Tyler Croy</name>
|
||||||
|
<email>tyler@linux.com</email>
|
||||||
|
</author>
|
||||||
|
|
||||||
|
{% for post in site.posts %}
|
||||||
|
<entry>
|
||||||
|
<title>{{ post.title }}</title>
|
||||||
|
<link href="http://unethicalblogger.com{{ post.url }}"/>
|
||||||
|
<updated>{{ post.date | date_to_xmlschema }}</updated>
|
||||||
|
<id>http://unethicalblogger.com{{ post.id }}</id>
|
||||||
|
<content type="html">{{ post.content | xml_escape }}</content>
|
||||||
|
</entry>
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
</feed>
|
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
|
@ -0,0 +1,57 @@
|
||||||
|
---
|
||||||
|
layout: default
|
||||||
|
javascript:
|
||||||
|
- /javascripts/json_search.0.9.0.js
|
||||||
|
- /javascripts/home.js
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
<div id="search_results_area">
|
||||||
|
<h2>Posts <span id="result_count"></span></h2>
|
||||||
|
<ul id="search_results" class="posts">
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="home">
|
||||||
|
<h2>Posts</h2>
|
||||||
|
<ul class="posts">
|
||||||
|
{% for post in site.posts %}
|
||||||
|
<li>
|
||||||
|
<a href="{{ post.url }}">{{ post.title }}</a>
|
||||||
|
<p>{{ post.summary }}</p>
|
||||||
|
</li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<h2>Tweets</h2>
|
||||||
|
<div id="tweets">
|
||||||
|
Loading...
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<script type="text/javascript" charset="utf-8">
|
||||||
|
var posts = [
|
||||||
|
{% for post in site.posts %}
|
||||||
|
{
|
||||||
|
title: unescape('{{ post.title | strip_html | cgi_escape }}').gsub(/\+/, ' '),
|
||||||
|
summary: unescape('{{ post.summary | strip_html | cgi_escape }}').gsub(/\+/, ' '),
|
||||||
|
content: unescape('{{ post.content | strip_html | cgi_escape }}').gsub(/\+/, ' '),
|
||||||
|
url: unescape('{{ post.url | strip_html | cgi_escape }}').gsub(/\+/, ' '),
|
||||||
|
},
|
||||||
|
{% endfor %}
|
||||||
|
0];
|
||||||
|
|
||||||
|
posts.pop();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript" src="/javascripts/twitter-1.11.2.js"></script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
getTwitters('tweets', {
|
||||||
|
id: 'agentdero',
|
||||||
|
count: 5,
|
||||||
|
enableLinks: true,
|
||||||
|
clearContents: true,
|
||||||
|
template: '%text%'
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</div>
|
|
@ -0,0 +1,70 @@
|
||||||
|
document.observe("dom:loaded", function() {
|
||||||
|
var search_field = $('search');
|
||||||
|
var search_label = $$('#search_area label').first();
|
||||||
|
var clear_search = $$('#search_area img').first();
|
||||||
|
var tweets = $('tweets');
|
||||||
|
var body = $$('body').first();
|
||||||
|
var json_search = new JSONSearch({
|
||||||
|
fields: {
|
||||||
|
title: 'infix',
|
||||||
|
summary: 'word_prefix',
|
||||||
|
content: 'word_prefix'
|
||||||
|
},
|
||||||
|
ranks: {
|
||||||
|
title: 3,
|
||||||
|
summary: 2,
|
||||||
|
content: 1
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var search = function(e) {
|
||||||
|
if (e && e.keyCode == 27) {
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
var query = search_field.value;
|
||||||
|
var results;
|
||||||
|
if (query.blank()) {
|
||||||
|
results = posts;
|
||||||
|
} else {
|
||||||
|
results = json_search.getResults(query, posts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!query.blank()) {
|
||||||
|
body.addClassName('searching');
|
||||||
|
search_label.hide();
|
||||||
|
} else {
|
||||||
|
body.removeClassName('searching');
|
||||||
|
}
|
||||||
|
$('result_count').update('(' + results.length + ')');
|
||||||
|
|
||||||
|
$('search_results').update(results.collect(function(post) {
|
||||||
|
return('<li><a href="' + post.url + '">' + post.title + '</a><p>' + post.summary + '</p></li>');
|
||||||
|
}).join(''));
|
||||||
|
};
|
||||||
|
|
||||||
|
if (search_field.value.blank()) {
|
||||||
|
search_label.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
search_field.observe('keyup', search);
|
||||||
|
|
||||||
|
search_field.observe('focus', function(e) {
|
||||||
|
search_label.hide();
|
||||||
|
});
|
||||||
|
|
||||||
|
search_field.observe('blur', function(e) {
|
||||||
|
if (search_field.value.blank()) {
|
||||||
|
search_label.show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var clear = function() {
|
||||||
|
search_field.value = '';
|
||||||
|
search_label.show();
|
||||||
|
search();
|
||||||
|
search_field.blur();
|
||||||
|
}
|
||||||
|
clear_search.observe('click', clear);
|
||||||
|
search();
|
||||||
|
});
|
||||||
|
$('search_area').show();
|
|
@ -0,0 +1,182 @@
|
||||||
|
var JSONSearch = function(options) {
|
||||||
|
|
||||||
|
this.default_options = {
|
||||||
|
fields: {},
|
||||||
|
ranks: {},
|
||||||
|
limit: null,
|
||||||
|
offset: 0,
|
||||||
|
case_sensitive: false
|
||||||
|
};
|
||||||
|
|
||||||
|
this.patterns = {
|
||||||
|
infix: '.*$token.*',
|
||||||
|
prefix: '^$token.*',
|
||||||
|
exact: '^$token$',
|
||||||
|
word: '\\b$token\\b',
|
||||||
|
word_prefix: '\\b$token.*'
|
||||||
|
};
|
||||||
|
|
||||||
|
this.query_string = '';
|
||||||
|
this.query_function = "1&&function(object) { var hits = 0, ranks_array = []; #{query_string} if (hits > 0) { return [(ranks_array.sort()[ranks_array.length - 1] || 0), hits, object]; } }";
|
||||||
|
|
||||||
|
this.initialize(options);
|
||||||
|
};
|
||||||
|
|
||||||
|
JSONSearch.InstanceMethods = {
|
||||||
|
initialize: function(options) {
|
||||||
|
this.options = {};
|
||||||
|
for(var property in this.default_options) {
|
||||||
|
this.options[property] = this.default_options[property]
|
||||||
|
};
|
||||||
|
for(var property in options) {
|
||||||
|
this.options[property] = options[property];
|
||||||
|
}
|
||||||
|
this.setAttributes(options);
|
||||||
|
this.buildMatcherTemplates();
|
||||||
|
this.buildQueryString();
|
||||||
|
},
|
||||||
|
|
||||||
|
setAttributes: function() {
|
||||||
|
var args = ['fields', 'limit', 'offset', 'case_sensitive'];
|
||||||
|
for(var i = 0; i < args.length; i++) {
|
||||||
|
this[args[i]] = this.options[args[i]];
|
||||||
|
};
|
||||||
|
this.ranks = this.getRanks();
|
||||||
|
this.fields_ordered_by_rank = this.fieldsOrderedByRank();
|
||||||
|
},
|
||||||
|
|
||||||
|
buildMatcherTemplates: function() {
|
||||||
|
for(var property in this.patterns) {
|
||||||
|
this[property + '_matcher'] = 'if(/' + this.patterns[property] + '/#{regex_options}.test(object["#{name}"])){hits++;ranks_array.push(ranks["#{name}"]);}';
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
getRanks: function(object) {
|
||||||
|
var ranks = {};
|
||||||
|
for(var property in this.fields) {
|
||||||
|
ranks[property] = (this.options.ranks && this.options.ranks[property] || 0);
|
||||||
|
};
|
||||||
|
return ranks;
|
||||||
|
},
|
||||||
|
|
||||||
|
// TODO if ranks are all 0 might just use the format order if supplied
|
||||||
|
fieldsOrderedByRank: function() {
|
||||||
|
var fields_ordered_by_rank = [];
|
||||||
|
for(var property in this.ranks){
|
||||||
|
fields_ordered_by_rank.push([this.ranks['property'], property]);
|
||||||
|
};
|
||||||
|
fields_ordered_by_rank = fields_ordered_by_rank.sort().reverse();
|
||||||
|
for(var i = 0; i < fields_ordered_by_rank.length; i++) {
|
||||||
|
fields_ordered_by_rank[i] = fields_ordered_by_rank[i][1];
|
||||||
|
}
|
||||||
|
return fields_ordered_by_rank;
|
||||||
|
},
|
||||||
|
|
||||||
|
buildQueryString: function() {
|
||||||
|
var query_string_array = [], field;
|
||||||
|
for(var i = 0; i < this.fields_ordered_by_rank.length; i++) {
|
||||||
|
field = this.fields_ordered_by_rank[i];
|
||||||
|
query_string_array.push(this.buildMatcher(field, this.fields[field]));
|
||||||
|
}
|
||||||
|
this.query_string = query_string_array.join('');
|
||||||
|
},
|
||||||
|
|
||||||
|
buildMatcher: function(name, pattern) {
|
||||||
|
return this.subMatcher(this[pattern + '_matcher'], { name: name, regex_options: this.getRegexOptions() });
|
||||||
|
},
|
||||||
|
|
||||||
|
subMatcher: function(matcher, object) {
|
||||||
|
var subbed_matcher = matcher;
|
||||||
|
for(var property in object) {
|
||||||
|
subbed_matcher = subbed_matcher.replace('#{' + property + '}', object[property], 'g')
|
||||||
|
}
|
||||||
|
return subbed_matcher;
|
||||||
|
},
|
||||||
|
|
||||||
|
subQueryString: function(token) {
|
||||||
|
return this.query_string.replace(/\$token/g, this.regexEscape(token));
|
||||||
|
},
|
||||||
|
|
||||||
|
subQueryFunction: function(object) {
|
||||||
|
var subbed_query_function;
|
||||||
|
for(var property in object) {
|
||||||
|
subbed_query_function = this.query_function.replace('#{' + property + '}', object[property], 'g')
|
||||||
|
}
|
||||||
|
return subbed_query_function;
|
||||||
|
},
|
||||||
|
|
||||||
|
//TODO add an options object to pass limit/offset.
|
||||||
|
getResults: function(token, object) {
|
||||||
|
object = this.evalJSON(object);
|
||||||
|
if (!(object instanceof Array)) {
|
||||||
|
object = [object];
|
||||||
|
}
|
||||||
|
var results, subbed_query_string = this.subQueryString(token);
|
||||||
|
results = this.getFilteredResults(subbed_query_string, object);
|
||||||
|
results = this.sortResults(results);
|
||||||
|
results = this.limitResults(results);
|
||||||
|
return this.cleanResults(results);
|
||||||
|
},
|
||||||
|
|
||||||
|
getFilteredResults: function(query_string, array) {
|
||||||
|
var results = [], ranks = this.ranks, result, len = (array.length), query_string = (query_string || '');
|
||||||
|
var query_function = eval(this.subQueryFunction({ query_string: query_string }));
|
||||||
|
|
||||||
|
for(var i = 0; i < len; ++i) {
|
||||||
|
if(result = query_function(array[i])) {
|
||||||
|
results.push(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
},
|
||||||
|
|
||||||
|
sortResults: function(results) {
|
||||||
|
return results.sort().reverse();
|
||||||
|
},
|
||||||
|
|
||||||
|
limitResults: function(results) {
|
||||||
|
if (this.limit) {
|
||||||
|
return results.slice(this.offset, (this.limit + this.offset));
|
||||||
|
} else if (this.offset > 0) {
|
||||||
|
return results.slice(this.offset, (results.length));
|
||||||
|
} else {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
cleanResults: function(results) {
|
||||||
|
var clean_results = []; len = (results.length);
|
||||||
|
for(var i = 0; i < len; ++i) {
|
||||||
|
clean_results.push(results[i][2]);
|
||||||
|
}
|
||||||
|
return clean_results;
|
||||||
|
},
|
||||||
|
|
||||||
|
evalJSON: function(json) {
|
||||||
|
if (typeof json == 'string') {
|
||||||
|
try {
|
||||||
|
json = eval('(' + json + ')');
|
||||||
|
} catch(e) {
|
||||||
|
throw new SyntaxError('Badly formed JSON string');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return json;
|
||||||
|
},
|
||||||
|
|
||||||
|
getRegex: function(token, pattern) {
|
||||||
|
return new RegExp(this.patterns[pattern].replace(/\$token/, this.regexEscape(token)), this.getRegexOptions());
|
||||||
|
},
|
||||||
|
|
||||||
|
getRegexOptions: function() {
|
||||||
|
return (this.case_sensitive && '' || 'i');
|
||||||
|
},
|
||||||
|
|
||||||
|
regexEscape: function(string) {
|
||||||
|
return String(string).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var property in JSONSearch.InstanceMethods) {
|
||||||
|
JSONSearch.prototype[property] = JSONSearch.InstanceMethods[property]
|
||||||
|
}
|
||||||
|
delete JSONSearch.InstanceMethods;
|
|
@ -0,0 +1,307 @@
|
||||||
|
/**
|
||||||
|
* remy sharp / http://remysharp.com
|
||||||
|
* http://remysharp.com/2007/05/18/add-twitter-to-your-blog-step-by-step/
|
||||||
|
*
|
||||||
|
* @params
|
||||||
|
* cssIdOfContainer: e.g. twitters
|
||||||
|
* options:
|
||||||
|
* {
|
||||||
|
* id: {String} username,
|
||||||
|
* count: {Int} 1-20, defaults to 1 - max limit 20
|
||||||
|
* prefix: {String} '%name% said', defaults to blank
|
||||||
|
* clearContents: {Boolean} true, removes contents of element specified in cssIdOfContainer, defaults to true
|
||||||
|
* ignoreReplies: {Boolean}, skips over tweets starting with '@', defaults to false
|
||||||
|
* template: {String} HTML template to use for LI element (see URL above for examples), defaults to predefined template
|
||||||
|
* enableLinks: {Boolean} linkifies text, defaults to true,
|
||||||
|
* timeout: {Int} How long before triggering onTimeout, defaults to 10 seconds if onTimeout is set
|
||||||
|
* onTimeoutCancel: {Boolean} Completely cancel twitter call if timedout, defaults to false
|
||||||
|
* onTimeout: {Function} Function to run when the timeout occurs. Function is bound to element specified with
|
||||||
|
* cssIdOfContainer (i.e. 'this' keyword)
|
||||||
|
*
|
||||||
|
* CURRENTLY DISABLED DUE TO CHANGE IN TWITTER API:
|
||||||
|
* withFriends: {Boolean} includes friend's status
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @license MIT (MIT-LICENSE.txt)
|
||||||
|
* @version 1.11 - Added timeout functionality, and removed withFriends while Twitter works out API changes
|
||||||
|
* @date $Date: 2008-10-16 18:49:40 +0100 (Thu, 16 Oct 2008) $
|
||||||
|
*/
|
||||||
|
|
||||||
|
// to protect variables from resetting if included more than once
|
||||||
|
if (typeof renderTwitters != 'function') (function () {
|
||||||
|
/** Private variables */
|
||||||
|
var browser = (function() {
|
||||||
|
var b = navigator.userAgent.toLowerCase();
|
||||||
|
|
||||||
|
// Figure out what browser is being used
|
||||||
|
return {
|
||||||
|
safari: /webkit/.test(b),
|
||||||
|
opera: /opera/.test(b),
|
||||||
|
msie: /msie/.test(b) && !(/opera/).test(b),
|
||||||
|
mozilla: /mozilla/.test(b) && !(/(compatible|webkit)/).test(b)
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
var guid = 0;
|
||||||
|
var readyList = [];
|
||||||
|
var isReady = false;
|
||||||
|
|
||||||
|
/** Global functions */
|
||||||
|
|
||||||
|
// to create a public function within our private scope, we attach the
|
||||||
|
// the function to the window object
|
||||||
|
window.renderTwitters = function (obj, options) {
|
||||||
|
// private shortcuts
|
||||||
|
function node(e) {
|
||||||
|
return document.createElement(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
function text(t) {
|
||||||
|
return document.createTextNode(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
var target = document.getElementById(options.twitterTarget);
|
||||||
|
var data = null;
|
||||||
|
var ul = node('ul'), li, statusSpan, timeSpan, i, max = obj.length > options.count ? options.count : obj.length;
|
||||||
|
|
||||||
|
for (i = 0; i < max && obj[i]; i++) {
|
||||||
|
data = getTwitterData(obj[i]);
|
||||||
|
|
||||||
|
if (options.ignoreReplies && obj[i].text.substr(0, 1) == '@') {
|
||||||
|
max++;
|
||||||
|
continue; // skip
|
||||||
|
}
|
||||||
|
|
||||||
|
li = node('li');
|
||||||
|
|
||||||
|
if (options.template) {
|
||||||
|
li.innerHTML = options.template.replace(/%([a-z_\-\.]*)%/ig, function (m, l) {
|
||||||
|
var r = data[l] + "" || "";
|
||||||
|
if (l == 'text' && options.enableLinks) r = linkify(r);
|
||||||
|
return r;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
statusSpan = node('span');
|
||||||
|
statusSpan.className = 'twitterStatus';
|
||||||
|
timeSpan = node('span');
|
||||||
|
timeSpan.className = 'twitterTime';
|
||||||
|
statusSpan.innerHTML = obj[i].text; // forces the entities to be converted correctly
|
||||||
|
|
||||||
|
if (options.enableLinks == true) {
|
||||||
|
statusSpan.innerHTML = linkify(statusSpan.innerHTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
timeSpan.innerHTML = relative_time(obj[i].created_at);
|
||||||
|
|
||||||
|
if (options.prefix) {
|
||||||
|
var s = node('span');
|
||||||
|
s.className = 'twitterPrefix';
|
||||||
|
s.innerHTML = options.prefix.replace(/%(.*?)%/g, function (m, l) {
|
||||||
|
return obj[i].user[l];
|
||||||
|
});
|
||||||
|
li.appendChild(s);
|
||||||
|
li.appendChild(text(' ')); // spacer :-(
|
||||||
|
}
|
||||||
|
|
||||||
|
li.appendChild(statusSpan);
|
||||||
|
li.appendChild(text(' '));
|
||||||
|
li.appendChild(timeSpan);
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.appendChild(li);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.clearContents) {
|
||||||
|
while (target.firstChild) {
|
||||||
|
target.removeChild(target.firstChild);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
target.appendChild(ul);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.getTwitters = function (target, id, count, options) {
|
||||||
|
guid++;
|
||||||
|
|
||||||
|
|
||||||
|
if (typeof id == 'object') {
|
||||||
|
options = id;
|
||||||
|
id = options.id;
|
||||||
|
count = options.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// defaulting options
|
||||||
|
if (!count) count = 1;
|
||||||
|
|
||||||
|
if (options) {
|
||||||
|
options.count = count;
|
||||||
|
} else {
|
||||||
|
options = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!options.timeout && typeof options.onTimeout == 'function') {
|
||||||
|
options.timeout = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof options.clearContents == 'undefined') {
|
||||||
|
options.clearContents = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hack to disable withFriends, twitter changed their API so this requires auth
|
||||||
|
// http://getsatisfaction.com/twitter/topics/friends_timeline_api_call_suddenly_requires_auth
|
||||||
|
if (options.withFriends) options.withFriends = false;
|
||||||
|
|
||||||
|
// need to make these global since we can't pass in to the twitter callback
|
||||||
|
options['twitterTarget'] = target;
|
||||||
|
|
||||||
|
// default enable links
|
||||||
|
if (typeof options.enableLinks == 'undefined') options.enableLinks = true;
|
||||||
|
|
||||||
|
// this looks scary, but it actually allows us to have more than one twitter
|
||||||
|
// status on the page, which in the case of my example blog - I do!
|
||||||
|
window['twitterCallback' + guid] = function (obj) {
|
||||||
|
if (options.timeout) {
|
||||||
|
clearTimeout(window['twitterTimeout' + guid]);
|
||||||
|
}
|
||||||
|
renderTwitters(obj, options);
|
||||||
|
};
|
||||||
|
|
||||||
|
// check out the mad currying!
|
||||||
|
ready((function(options, guid) {
|
||||||
|
return function () {
|
||||||
|
// if the element isn't on the DOM, don't bother
|
||||||
|
if (!document.getElementById(options.twitterTarget)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var url = 'http://www.twitter.com/statuses/' + (options.withFriends ? 'friends_timeline' : 'user_timeline') + '/' + id + '.json?callback=twitterCallback' + guid + '&count=20';
|
||||||
|
|
||||||
|
if (options.timeout) {
|
||||||
|
window['twitterTimeout' + guid] = setTimeout(function () {
|
||||||
|
// cancel callback
|
||||||
|
if (options.onTimeoutCancel) window['twitterCallback' + guid] = function () {};
|
||||||
|
options.onTimeout.call(document.getElementById(options.twitterTarget));
|
||||||
|
}, options.timeout * 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
var script = document.createElement('script');
|
||||||
|
script.setAttribute('src', url);
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(script);
|
||||||
|
};
|
||||||
|
})(options, guid));
|
||||||
|
};
|
||||||
|
|
||||||
|
// GO!
|
||||||
|
DOMReady();
|
||||||
|
|
||||||
|
|
||||||
|
/** Private functions */
|
||||||
|
|
||||||
|
function getTwitterData(orig) {
|
||||||
|
var data = orig, i;
|
||||||
|
for (i in orig.user) {
|
||||||
|
data['user_' + i] = orig.user[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
data.time = relative_time(orig.created_at);
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
function ready(callback) {
|
||||||
|
if (!isReady) {
|
||||||
|
readyList.push(callback);
|
||||||
|
} else {
|
||||||
|
callback.call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function fireReady() {
|
||||||
|
isReady = true;
|
||||||
|
var fn;
|
||||||
|
while (fn = readyList.shift()) {
|
||||||
|
fn.call();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ready and browser adapted from John Resig's jQuery library (http://jquery.com)
|
||||||
|
function DOMReady() {
|
||||||
|
if ( browser.mozilla || browser.opera ) {
|
||||||
|
document.addEventListener( "DOMContentLoaded", fireReady, false );
|
||||||
|
} else if ( browser.msie ) {
|
||||||
|
// If IE is used, use the excellent hack by Matthias Miller
|
||||||
|
// http://www.outofhanwell.com/blog/index.php?title=the_window_onload_problem_revisited
|
||||||
|
|
||||||
|
// Only works if you document.write() it
|
||||||
|
document.write("<scr" + "ipt id=__ie_init defer=true src=//:><\/script>");
|
||||||
|
|
||||||
|
// Use the defer script hack
|
||||||
|
var script = document.getElementById("__ie_init");
|
||||||
|
|
||||||
|
// script does not exist if jQuery is loaded dynamically
|
||||||
|
if (script) {
|
||||||
|
script.onreadystatechange = function() {
|
||||||
|
if ( this.readyState != "complete" ) return;
|
||||||
|
this.parentNode.removeChild( this );
|
||||||
|
fireReady.call();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear from memory
|
||||||
|
script = null;
|
||||||
|
|
||||||
|
// If Safari is used
|
||||||
|
} else if ( browser.safari ) {
|
||||||
|
// Continually check to see if the document.readyState is valid
|
||||||
|
var safariTimer = setInterval(function () {
|
||||||
|
// loaded and complete are both valid states
|
||||||
|
if ( document.readyState == "loaded" ||
|
||||||
|
document.readyState == "complete" ) {
|
||||||
|
|
||||||
|
// If either one are found, remove the timer
|
||||||
|
clearInterval( safariTimer );
|
||||||
|
safariTimer = null;
|
||||||
|
// and execute any waiting functions
|
||||||
|
fireReady.call();
|
||||||
|
}
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function relative_time(time_value) {
|
||||||
|
var values = time_value.split(" ");
|
||||||
|
time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
|
||||||
|
var parsed_date = Date.parse(time_value);
|
||||||
|
var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
|
||||||
|
var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
|
||||||
|
delta = delta + (relative_to.getTimezoneOffset() * 60);
|
||||||
|
|
||||||
|
var r = '';
|
||||||
|
if (delta < 60) {
|
||||||
|
r = 'less than a minute ago';
|
||||||
|
} else if(delta < 120) {
|
||||||
|
r = 'about a minute ago';
|
||||||
|
} else if(delta < (45*60)) {
|
||||||
|
r = (parseInt(delta / 60)).toString() + ' minutes ago';
|
||||||
|
} else if(delta < (2*90*60)) { // 2* because sometimes read 1 hours ago
|
||||||
|
r = 'about an hour ago';
|
||||||
|
} else if(delta < (24*60*60)) {
|
||||||
|
r = 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
|
||||||
|
} else if(delta < (48*60*60)) {
|
||||||
|
r = '1 day ago';
|
||||||
|
} else {
|
||||||
|
r = (parseInt(delta / 86400)).toString() + ' days ago';
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
function linkify(s) {
|
||||||
|
return s.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/g, function(m) {
|
||||||
|
return m.link(m);
|
||||||
|
}).replace(/@[\S]+/g, function(m) {
|
||||||
|
return '<a href="http://twitter.com/' + m.substr(1) + '">' + m + '</a>';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})();
|
|
@ -0,0 +1,172 @@
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
line-height: 130%;
|
||||||
|
font-size: 100%;
|
||||||
|
color: #222;
|
||||||
|
background: #fff;
|
||||||
|
font-family: "Helvetica Neue", Arial, Helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover, a:active, #sidebar a:active, #sidebar a:hover, #content a {
|
||||||
|
color: #b40 !important;
|
||||||
|
}
|
||||||
|
#site {
|
||||||
|
width: 850px;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subscribe {
|
||||||
|
float: right;
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
margin: 0;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 a, h1 a:link, h1 a:visited {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
|
||||||
|
#slogan {
|
||||||
|
margin: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar {
|
||||||
|
width: 180px;
|
||||||
|
padding: 10px 20px 20px 20px;
|
||||||
|
border-left: 5px solid #eee;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
#sidebar a, #sidebar a:link #sidebar a:visited {
|
||||||
|
color: #222;
|
||||||
|
}
|
||||||
|
#sidebar dl, #sidebar ul {
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
#sidebar dl#contact dt {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#sidebar dl#contact dd {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#sidebar ul {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
#sidebar a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
#sidebar .adr, #sidebar .tel {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
width: 600px;
|
||||||
|
padding: 0 20px 20px 20px;
|
||||||
|
}
|
||||||
|
#content ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#content li {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h3 {
|
||||||
|
margin: 0 0 10px 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.highlight pre {
|
||||||
|
background: #eee;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
padding: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.update {
|
||||||
|
border: 1px solid #fc6;
|
||||||
|
background: #fe8;
|
||||||
|
padding: 15px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
#post {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#disqus_thread {
|
||||||
|
margin-bottom: 130px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#related {
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.posts p {
|
||||||
|
margin: 5px 0 25px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rss_only {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search_area {
|
||||||
|
width: 80px;
|
||||||
|
float: right;
|
||||||
|
margin: 19px 50px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
#search {
|
||||||
|
font-size: 17px;
|
||||||
|
font-family: inherit;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
color: #666;
|
||||||
|
-moz-border-radius: 30px;
|
||||||
|
-webkit-border-radius: 13px;
|
||||||
|
padding: 3px 27px 3px 27px;
|
||||||
|
background: url(http://www.famfamfam.com/lab/icons/silk/icons/magnifier.png) 7px 6px no-repeat ;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
#search:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search_area label {
|
||||||
|
font-size: 17px;
|
||||||
|
position: absolute;
|
||||||
|
top: 4px;
|
||||||
|
left: 29px;
|
||||||
|
color: #ccc;
|
||||||
|
cursor: text;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search_area img {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.searching #search_area img {
|
||||||
|
position: absolute;
|
||||||
|
left: 113px;
|
||||||
|
top: 7px;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#search_results_area {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.searching #search_results_area {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.searching #home {
|
||||||
|
display: none;
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/* From http://github.com/mojombo/tpw/raw/master/css/syntax.css */
|
||||||
|
|
||||||
|
.highlight { background: #ffffff; }
|
||||||
|
.highlight .c { color: #999988; font-style: italic } /* Comment */
|
||||||
|
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
|
||||||
|
.highlight .k { font-weight: bold } /* Keyword */
|
||||||
|
.highlight .o { font-weight: bold } /* Operator */
|
||||||
|
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
|
||||||
|
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
|
||||||
|
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
|
||||||
|
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
|
||||||
|
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
|
||||||
|
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
|
||||||
|
.highlight .ge { font-style: italic } /* Generic.Emph */
|
||||||
|
.highlight .gr { color: #aa0000 } /* Generic.Error */
|
||||||
|
.highlight .gh { color: #999999 } /* Generic.Heading */
|
||||||
|
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||||
|
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
|
||||||
|
.highlight .go { color: #888888 } /* Generic.Output */
|
||||||
|
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
||||||
|
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||||
|
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
|
||||||
|
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
|
||||||
|
.highlight .kc { font-weight: bold } /* Keyword.Constant */
|
||||||
|
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
|
||||||
|
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
|
||||||
|
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
|
||||||
|
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
|
||||||
|
.highlight .m { color: #009999 } /* Literal.Number */
|
||||||
|
.highlight .s { color: #d14 } /* Literal.String */
|
||||||
|
.highlight .na { color: #008080 } /* Name.Attribute */
|
||||||
|
.highlight .nb { color: #0086B3 } /* Name.Builtin */
|
||||||
|
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
|
||||||
|
.highlight .no { color: #008080 } /* Name.Constant */
|
||||||
|
.highlight .ni { color: #800080 } /* Name.Entity */
|
||||||
|
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
|
||||||
|
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
|
||||||
|
.highlight .nn { color: #555555 } /* Name.Namespace */
|
||||||
|
.highlight .nt { color: #000080 } /* Name.Tag */
|
||||||
|
.highlight .nv { color: #008080 } /* Name.Variable */
|
||||||
|
.highlight .ow { font-weight: bold } /* Operator.Word */
|
||||||
|
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
|
||||||
|
.highlight .mf { color: #009999 } /* Literal.Number.Float */
|
||||||
|
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
|
||||||
|
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
|
||||||
|
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
|
||||||
|
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
|
||||||
|
.highlight .sc { color: #d14 } /* Literal.String.Char */
|
||||||
|
.highlight .sd { color: #d14 } /* Literal.String.Doc */
|
||||||
|
.highlight .s2 { color: #d14 } /* Literal.String.Double */
|
||||||
|
.highlight .se { color: #d14 } /* Literal.String.Escape */
|
||||||
|
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
|
||||||
|
.highlight .si { color: #d14 } /* Literal.String.Interpol */
|
||||||
|
.highlight .sx { color: #d14 } /* Literal.String.Other */
|
||||||
|
.highlight .sr { color: #009926 } /* Literal.String.Regex */
|
||||||
|
.highlight .s1 { color: #d14 } /* Literal.String.Single */
|
||||||
|
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
|
||||||
|
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
|
||||||
|
.highlight .vc { color: #008080 } /* Name.Variable.Class */
|
||||||
|
.highlight .vg { color: #008080 } /* Name.Variable.Global */
|
||||||
|
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
|
||||||
|
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
|
Loading…
Reference in New Issue