This commit is contained in:
Jonathan Rudenberg 2012-08-22 11:15:21 -04:00
parent decb9d8430
commit c0ca040c2c
19 changed files with 366 additions and 237 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
tmp tmp
output output
crash.log

23
Rules
View file

@ -31,12 +31,12 @@ route '/sitemap/', rep: 'gzip' do
'/sitemap.xml.gz' '/sitemap.xml.gz'
end end
compile '/posts/feed/' do compile '/blog/feed/' do
filter :erb filter :erb
end end
route '/posts/feed/' do route '/blog/feed/' do
'/posts.xml' '/blog.xml'
end end
compile %r{^/(google|robots|assets|favicon)} do compile %r{^/(google|robots|assets|favicon)} do
@ -47,11 +47,22 @@ compile '*' do
when 'slim' when 'slim'
filter :slim filter :slim
when 'md' when 'md'
filter :redcarpet, renderer: MarkdownHTML, options: { fenced_code_blocks: true } filter :redcarpet, renderer: MarkdownHTML, options: {
fenced_code_blocks: true,
no_intra_emphasis: true,
autolink: true,
tables: true,
strikethrough: true,
lax_html_blocks: true,
space_after_headers: true,
superscript: true
}
end end
case item.identifier case item.identifier
when %r{^/posts/} when %r{/_}
layout 'none'
when %r{^/blog/.+}
layout 'post' layout 'post'
else else
layout 'default' layout 'default'
@ -65,6 +76,8 @@ route '/' do
end end
route '*' do route '*' do
next nil if item.identifier.split('/')[-1][0,1] == '_' # partial
if item.binary? if item.binary?
# Write item with identifier /foo/ to /foo.ext # Write item with identifier /foo/ to /foo.ext
item.identifier.chop + '.' + item[:extension] item.identifier.chop + '.' + item[:extension]

View file

@ -1,7 +1,7 @@
# A list of file extensions that nanoc will consider to be textual rather than # A list of file extensions that nanoc will consider to be textual rather than
# binary. If an item with an extension not in this list is found, the file # binary. If an item with an extension not in this list is found, the file
# will be considered as binary. # will be considered as binary.
text_extensions: [ 'coffee', 'css', 'erb', 'haml', 'handlebars', 'hb', 'htm', 'html', 'js', 'less', 'markdown', 'md', 'ms', 'mustache', 'php', 'rb', 'sass', 'scss', 'txt', 'xhtml', 'xml' ] text_extensions: [ 'coffee', 'css', 'erb', 'haml', 'handlebars', 'hb', 'htm', 'html', 'js', 'less', 'markdown', 'md', 'ms', 'mustache', 'php', 'rb', 'sass', 'scss', 'txt', 'xhtml', 'xml', 'slim' ]
# The path to the directory where all generated files will be written to. This # The path to the directory where all generated files will be written to. This
# can be an absolute path starting with a slash, but it can also be path # can be an absolute path starting with a slash, but it can also be path
@ -78,6 +78,9 @@ watcher:
google_analytics_id: UA-34258323-1 google_analytics_id: UA-34258323-1
base_url: http://tent.io base_url: http://tent.io
title: Tent
author_name: Tent
author_uri: http://tent.io
# Configure the robots.txt file for this site. # Configure the robots.txt file for this site.
# Setting 'default' to true-ish will use sensible defaults. If you # Setting 'default' to true-ish will use sensible defaults. If you

205
content/_faq.md Normal file
View file

@ -0,0 +1,205 @@
### What is Tent?
Tent is a protocol for distributed social networking. Tent users share data with
apps and each other. Tent supports extensible data types for future expanded
functionality. Anyone can host their own Tent server, or write a server or app
that uses the Tent protocol. Users can take their content and relationships with
them when they move servers.
Tent is for sharing with others and seeing what others have shared. Because you
control your own Tent server, it is also a good place to store things you don't
want to share with others, a sort of personal data vault. It can also be used as
a secure site login replacement so you don't need passwords when accessing other
sites on the web.
### How does Tent work?
Check out this page for a full description
### What does Tent do?
When you create new content, Tent sends it to the followers you choose. It also
listens for and stores new messages and content from the people and
organizations you follow. Every user on Tent also has a profile that stores
basic information about the user.
### How do I use Tent?
First you need a Tent server. A Tent server sends new content to your followers
and listens for new content from people you follow. It stores all this content
safely so it's available for you to view later. You view and create content with
apps. Apps connect to your server to post new content you've created and ask for
content from people you follow. You can limit apps so they can't see all your
content. If you have private photos or messages, you might want only a few apps
to see them.
You can download and run Tent server on your own hardware or get started with
a hosted provider who runs the server for you. You could also write your own
server and apps from scratch.
### Can I switch Tent servers?
Absolutely! And you can take your relationships-- your followers with you. If
a service provider changes its terms, shuts down, gets bought, discontinues
a product, no problem-- you can take your data and relationships with you and
set up somewhere else-- on your own server or at another provider.
### Can I get my data out of Tent?
Of course! There are two easy ways: with an app or another Tent server. Just
authorize a Tent app or a new Tent server to view the content and it will
transfer over automatically.
### Why is Tent distributed?
Distributed services are resilient. If one part breaks or is turned off the
other parts continue to operate normally. This is why the whole internet doesn't
shut down when one site or server is having problems. Important services should
be decentralized, offering users a choice of providers and developers the
opportunity to innovate. The Internet itself, and the most important services on
it, like the World Wide Web and Email, are all distributed systems based on open
protocols. Just like Tent. Most existing social sites could be reimplemented
based on Tent.
Companies and products don't last forever. if a company changes its terms, shuts
down, gets bought, discontinues a product, no problem-- you can take your data
and services with you and set up somewhere else-- on your own server or at
another company. Distributed protocol-based service have another big advantage:
users on a network separated from the internet can still use them. Some
countries and Internet Service Providers block access to services and content
outside the country. Totalitarian regimes have blocked social networks, but
distributed services inside the country, like that nation's Web still operate.
Tent can be run inside
The social web is too important to leave in the hands of any one company or
government. The services on which the world depends need to be distributed. With
Tent, now the world can depend on social.
### What does Tent do that existing social networks don't?
You can take your relationships--the users you follow and the users who follow
you--and your content with you. Tent also lets you control your data, decide who
can see it, and how they can use it. Tent is distributed and an open protocol,
so if you don't like an app or service you can write your own, or change
providers.
You do not have to advertise your tent server to anyone. You can also run a Tent
server as a TOR hidden service, making it even harder for someone to silence
your voice online or track you down. Tent respects pseudonyms, handles, and your
right to anonymity. Since you control your Tent server, you also choose your
name, which can be anything you want.
Even more features are coming in the next version of Tent
### What's wrong with other social services?
Centralized Social Service Providers (CSSPs) limit what you can share and who
you can share with. They only allow Because their products are centralized and
maintained by a company, users are left in the cold when the company changes its
products or shuts down. There's nothing wrong with a company offering users
social services. But users shouldn't be limited by those companies. Imagine if
you could only email other customers of your Internet Service Provider.
Unfortunately Centralized Social Service Providers have done just that. You can
only communicate directly with other users of their closed network.
If you don't like a bank you can withdraw your money and deposit it somewhere
else, including your own home. You could even start a new bank where you and
your friends felt safe. You can still pay your bills and maintain your financial
relationships, just tell them about your new account. We aren't talking about
money. Your data is far more valuable-- your family and friends' photos,
locations, and private communications. You should be able to store them
somewhere you trust, move them when you want, control who can and can't see
them.
### What's wrong with a federated social web?
Federated services add a few capabilities to Centralized Social Service
Providers' products. Generally users can broadcast a stream of public events to
other services in the Federation. Because private messages (and many other
important features) are beyond the scope of most federation protocols, users can
not send private messages to users of other Social Service Providers. Since
these features are not standardized, Social Service Providers must implement
proprietary features. This locks users into a specific Social Service Provider,
and causes fragmentation which prevents interoperability. Diaspora* and OStatus
were first steps in moving away from Centralized Social Service Providers, but
stopped short of decentralization. Any long-term solution will require
decentralization as a core design feature.
### What is a protocol?
A protocol defines how to do something in a standard way. Our daily lives are
filled with protocols. If you want to enter someone's home, knock or ring the
doorbell first. If you attach a stamp to a letter and address it properly, the
post office will mail it for you. You don't have to have a conversation with the
letter carrier each time.
### Why doesn't Tent use my favorite protocol?
The architects of Tent investigated existing protocols for the distributed
social web. Each of them lacked critical features
### Does Tent have ads?
Tent is a protocol like email or the World Wide Web. Anyone can run their own
tent server (which would be ad-free) or host a tent server for others. Just like
email, some providers show ads to make money so they can host your tent server
for free. Others charge users directly and don't need ads. It's your choice.
### Does Tent cost money?
Tent is a set of protocols like email or the world wide web. Tent itself is and
will always be free. Anyone can run or implement a Tent service or write a new
app that works with Tent. Just like email, some providers are free and others
cost money. Don't like any of the existing providers? Start your own.
### Can I donate to Tent?
You can not donate money to Tent. If you want to support the Tent effort there
are several ways you can help:
1. **Start your own Tent server.** The most important thing you can do is switch to
using Tent. You can host your own Tent server by downloading the code here or
sign up for a hosted server at Tent.is. Thank you for using Tent!
2. **Tell your friends.** The next generation of the social web won't be of much
use if people don't use it for their social networks. Tell your friends to
get a Tent server and proudly display your Tent address throughout your
world--on your business card, email signatures, and other social services.
3. **Suggest a feature or change in Tent.** Tent is still under development. If you
see something wrong or confusing or think we left something out, please tell
us by emailing comment@tent.io or creating an issue on our github repository.
4. **Build for Tent.** Please integrate Tent support into your existing and new
services. The Tent ecosystem needs apps as much as users. Tent gives
developers much more freedom than Centralized Social Service Providers have
allowed before. We can't wait to see what the community comes up with. Client
libraries are coming soon.
### Where did Tent come from?
Tent began after a conversation between Jonathan Rudenberg, Daniel Siders, Jesse
Stuart, and Lucas Wojciechowski. It was inspired by hypertext, Xanadu, SMTP, the
World Wide Web, and distributed peer-to-peer services.
### Where can I see some examples?
Here.
### Is there a Tent app for my favorite activity?
If there isn't you should write one!

View file

@ -59,3 +59,7 @@
.vg { color: #19177C } /* Name.Variable.Global */ .vg { color: #19177C } /* Name.Variable.Global */
.vi { color: #19177C } /* Name.Variable.Instance */ .vi { color: #19177C } /* Name.Variable.Instance */
.il { color: #666666 } /* Literal.Number.Integer.Long */ .il { color: #666666 } /* Literal.Number.Integer.Long */
#faq h3 {
font-weight: 200;
}

2
content/blog.slim Normal file
View file

@ -0,0 +1,2 @@
- sorted_articles.each do |post|
== render '_post', post: post

1
content/blog/feed.xml Normal file
View file

@ -0,0 +1 @@
<%= atom_feed limit: 10 %>

40
content/blog/test-post.md Normal file
View file

@ -0,0 +1,40 @@
---
title: Test Post
kind: article
created_at: July 3, 2012 16:45 EDT
---
8-bit post-ironic tattooed sapiente letterpress Austin. Eiusmod put a bird on it
helvetica, direct trade fixie synth aliquip odio swag. Veniam elit officia
proident 3 wolf moon incididunt. Wes anderson placeat hella, leggings vinyl
letterpress cray fap sed irure cliche. Brunch sartorial ennui veniam banh mi,
quis labore beard pitchfork american apparel pop-up wolf occupy qui skateboard.
Ea sint magna labore, nesciunt deserunt esse shoreditch brunch. Wolf ex etsy,
synth whatever shoreditch twee.
Cardigan tattooed aliqua, craft beer laborum marfa dreamcatcher you probably
haven't heard of them. Wolf accusamus messenger bag reprehenderit narwhal.
Aesthetic squid ennui, viral cillum craft beer trust fund ad brooklyn. +1
officia ea, mumblecore pinterest squid mustache twee lo-fi small batch ullamco
eiusmod whatever. Thundercats est cosby sweater synth. Tempor vero scenester
fanny pack, pour-over sint placeat odio. Lo-fi sartorial sustainable cliche,
quinoa bespoke enim nulla irure skateboard master cleanse biodiesel.
DIY sriracha magna est mumblecore, ad seitan pariatur scenester odd future sed
portland kogi. Nulla readymade pork belly eiusmod pitchfork jean shorts.
Exercitation typewriter leggings fixie, high life +1 vero eiusmod ut marfa
thundercats minim cupidatat voluptate cray. Mollit marfa cray incididunt tumblr
art party. Sapiente squid photo booth, polaroid PBR mcsweeney's sriracha ut
chambray veniam narwhal nesciunt post-ironic consectetur est. Jean shorts
sriracha pickled dreamcatcher enim sustainable quinoa fingerstache. Wayfarers
odd future sunt quinoa, iphone pour-over 8-bit leggings synth nostrud.
Austin farm-to-table vero truffaut, wayfarers exercitation umami officia. Enim
DIY mcsweeney's fixie, laboris art party portland american apparel sed readymade
irure nisi eu skateboard tumblr. Voluptate synth direct trade veniam placeat,
trust fund velit quis readymade exercitation butcher kale chips. Ea ex velit
banksy irony, eiusmod carles you probably haven't heard of them put a bird on it
non aute williamsburg organic exercitation excepteur. Godard craft beer master
cleanse tempor, assumenda cliche yr keffiyeh. Pork belly deserunt lo-fi
authentic bushwick irure. Fixie viral messenger bag, magna sapiente nesciunt
ethnic officia dolore lomo artisan cardigan semiotics raw denim quis.

View file

@ -61,8 +61,7 @@ Content-Type: application/json
Location: https://tent.titanous.com/apps/6737b Location: https://tent.titanous.com/apps/6737b
``` ```
```json
{
"id": "6737b", "id": "6737b",
"secret": "3d2adf9a68bf64f4eaff70a7c7700a8", "secret": "3d2adf9a68bf64f4eaff70a7c7700a8",
"mac_algorithm": "hmac-sha-256" "mac_algorithm": "hmac-sha-256"
@ -71,93 +70,22 @@ Location: https://tent.titanous.com/apps/6737b
### Request Parameters ### Request Parameters
<table> | Name | Required | Type | Description |
<thead> | --------------- | -------- | ------ | ----------- |
<tr> | `name` | Required | String | The human name of the app to show the user |
<th>Name</th> | `description` | Required | String | A short description of the application to show the user |
<th>Required</th> | `url` | Required | String | The main url of the app |
<th>Type</th> | `icon` | Optional | String | The url to an icon for the app |
<th>Description</th> | `redirect_uris` | Optional | Array | A list of **exact** (including parameters) urls that will be used as OAuth `redirect_uri` |
</tr> | `scopes` | Optional | Object | A list of scope key to description value mappings of all scopes that the app might use. The descriptions should describe why the specific scope is necessary for the app to function. |
</thead>
<tbody>
<tr>
<td><code>name</code></td>
<td>Required</td>
<td>String</td>
<td>The human name of the app to show the user</td>
</tr>
<tr>
<td><code>description</code></td>
<td>Required</td>
<td>String</td>
<td>A short description of the application to show the user</td>
</tr>
<tr>
<td><code>url</code></td>
<td>Required</td>
<td>String</td>
<td>The main url of the app</td>
</tr>
<tr>
<td><code>icon</code></td>
<td>Optional</td>
<td>String</td>
<td>The url to an icon for the app</td>
</tr>
<tr>
<td><code>redirect_uris</code></td>
<td>Optional</td>
<td>Array</td>
<td>
A list of <strong>exact</strong> (including parameters) urls that will
be used as OAuth <code>redirect_uri</code>.
</td>
</tr>
<tr>
<td><code>scopes</code></td>
<td>Optional</td>
<td>Object</td>
<td>
A list of scope key to description value mappings of all scopes that
the app might use. The descriptions should describe why the specific
scope is necessary for the app to function.
</td>
</tr>
</tbody>
</table>
### Response Parameters ### Response Parameters
<table> | Name | Description |
<thead> | --------------- | ----------- |
<tr> | `id` | The identifier of the app. This is used as the MAC key identifier for requests to/from the Tent server, as well as the `client_id` in the OAuth flow. |
<th>Name</th> | `secret` | The secret used as the MAC key when modifying the registration and receiving notifications. |
<th>Description</th> | `mac_algorithm` | The MAC algorithm to be used. |
</tr>
</thead>
<tbody>
<tr>
<td><code>id</code></td>
<td>
The identifier of the app. This is used as the MAC key identifier for
requests to/from the Tent server, as well as the <code>client_id</code>
in the OAuth flow.
</td>
</tr>
<tr>
<td><code>secret</code></td>
<td>
The secret used as the MAC key when modifying the registration and
receiving notifications.
</td>
</tr>
<tr>
<td><code>mac_algorithm</code></td>
<td>The MAC algorithm to be used.</td>
</tr>
</tbody>
</table>
## App Registration Modification ## App Registration Modification
@ -211,112 +139,29 @@ user-agent to it:
#### Parameters #### Parameters
<table> | Name | Required | Description |
<thead> | --------------------------- | --------- | ----------- |
<tr> | `client_id` | Required | The `id` obtained by registering with the Tent server |
<th>Name</th> | `redirect_uri` | Required | The URI to redirect to after authentication is complete. It must **exactly** match a URI (including parameters) provided during app registration in `redirect_uris`. |
<th>Required</th> | `state` | Optional | This parameter will be added to the `redirect_uri` and should always be set to a random string that is stored in the session, and then verified to prevent cross-site request forgery attacks. |
<th>Description</th> | `scope` | Optional | A comma-separated list of scopes that the app is requesting access to. |
</tr> | `tent_profile_info_types` | Optional | A comma-separated list of `profile_info_type_url#version` profile info type specifiers that the app is requesting access to. Set to `all` to request full access to the profile. |
</thead> | `tent_post_types` | Optional | A comma-separated list of `post_type_url#version` type/version specifiers that the app is requesting access to. Set to `all` to request access to all posts. |
<tbody>
<tr>
<td><code>client_id</code></td>
<td>Required</td>
<td>
The <code>id</code> obtained by registering with the Tent server
</td>
</tr>
<tr>
<td><code>redirect_uri</code></td>
<td>Required</td>
<td>
The URI to redirect to after authentication is complete. It must
<strong>exactly</strong> match a URI (including parameters)
provided during app registration in <code>redirect_uris</code>.
</td>
</tr>
<tr>
<td><code>state</code></td>
<td>Optional</td>
<td>
This parameter will be added to the <code>redirect_uri</code> and should
always be set to a random string that is stored in the session, and then
verified to prevent cross-site request forgery attacks.
</td>
</tr>
<tr>
<td><code>scope</code></td>
<td>Optional</td>
<td>
A comma-separated list of scopes that the app is requesting access to.
</td>
</tr>
<tr>
<td><code>tent_profile_info_types</code></td>
<td>Optional</td>
<td>
A comma-separated list of <code>profile_info_type_url#version</code>
profile info type specifiers that the app is requesting access to. Set
to <code>all</code> to request full access to the profile.
</td>
</tr>
<tr>
<td><code>tent_post_types</code></td>
<td>Optional</td>
<td>
A comma-separated list of <code>post_type_url#version</code>
type/version specifiers that the app is requesting access to.
Set to <code>all</code> to request access to all posts.
</td>
</tr>
</tbody>
</table>
#### Scopes #### Scopes
<table> | Scope | Description |
<thead> | ------------------ | ---------------------------------------------------------------------- |
<tr> | `read_profile` | Read profile sections listed in the `profile_info` parameter |
<th>Scope</th> | `write_profile` | Read and write profile sections listed in the `profile_info` parameter |
<th>Description</th> | `read_followers` | Read follower list |
</tr> | `write_followers` | Read follower list and block followers |
</thead> | `read_followings` | Read followings list |
<tbody> | `write_followings` | Read followings list and follow new entities |
<tr> | `read_posts` | Read posts with types listed in the `post_types` parameter |
<td><code>read_profile</code></td> | `write_posts` | Read and publish posts with types listed in the `post_types` parameter |
<td>Read profile sections listed in the <code>profile_info</code> parameter</td>
</tr>
<tr>
<td><code>write_profile</code></td>
<td>Read and write profile sections listed in the <code>profile_info</code> parameter</td>
</tr>
<tr>
<td><code>read_followers</code></td>
<td>Read follower list</td>
</tr>
<tr>
<td><code>write_followers</code></td>
<td>Read follower list and block followers</td>
</tr>
<tr>
<td><code>read_followings</code></td>
<td>Read followings list</td>
</tr>
<tr>
<td><code>write_followings</code></td>
<td>Read followings list and follow new entities</td>
</tr>
<tr>
<td><code>read_posts</code></td>
<td>Read posts with types listed in the <code>post_types</code> parameter</td>
</tr>
<tr>
<td><code>write_posts</code></td>
<td>Read and publish posts with types listed in the <code>post_types</code> parameter</td>
</tr>
</tbody>
</table>
### Redirect ### Redirect
@ -378,32 +223,13 @@ Content-Type: application/json
#### Response Parameters #### Response Parameters
<table> | Name | Description |
<thead> | --------------- | ------------------------------------------------ |
<tr> | `access_token` | Used as the MAC key identifier. |
<th>Name</th> | `mac_key` | Used as the MAC key for requests. |
<th>Description</th> | `mac_algorithm` | The MAC algorithm to be used. |
</tr> | `token_type` | Specifies the token type. Currently always `mac` |
</thead>
<tbody>
<tr>
<td><code>access_token</code></td>
<td>Used as the MAC key identifier.</td>
</tr>
<tr>
<td><code>mac_key</code></td>
<td>Used as the MAC key for requests.</td>
</tr>
<tr>
<td><code>mac_algorithm</code></td>
<td>The MAC algorithm to be used.</td>
</tr>
<tr>
<td><code>token_type</code></td>
<td>Specifies the token type. Currently always <code>mac</code></td>
</tr>
</tbody>
</table>
## Request Authentication ## Request Authentication

View file

@ -1,14 +0,0 @@
---
title: Home
---
<h1>A Brand New nanoc Site</h1>
<p>Youve just created a new nanoc site. The page you are looking at right now is the home page for your site. To get started, consider replacing this default homepage with your own customized homepage. Some pointers on how to do so:</p>
<ul>
<li><p><strong>Change this pages content</strong> by editing the “index.html” file in the “content” directory. This is the actual page content, and therefore doesnt include the header, sidebar or style information (those are part of the layout).</p></li>
<li><p><strong>Change the layout</strong>, which is the “default.html” file in the “layouts” directory, and create something unique (and hopefully less bland).</p></li>
</ul>
<p>If you need any help with customizing your nanoc web site, be sure to check out the documentation (see sidebar), and be sure to subscribe to the discussion group (also see sidebar). Enjoy!</p>

1
content/index.slim Normal file
View file

@ -0,0 +1 @@
#faq == render_child('/_faq/')

5
layouts/_post.slim Normal file
View file

@ -0,0 +1,5 @@
article
h1 == link_to @post[:title], @post.identifier.chop
- time = Time.parse(@post[:created_at])
date title=time.strftime('%F %R %Z') datetime=time.strftime('%FT%T%:z') pubdate=true = time.strftime('%B %-d, %Y')
== @content || @post.compiled_content

View file

@ -2,5 +2,8 @@ doctype html
html lang='en' html lang='en'
head == render 'head' head == render 'head'
body body
#container == render 'navbar'
== yield .container
.row
.span8.offset2
== yield

7
layouts/navbar.slim Normal file
View file

@ -0,0 +1,7 @@
.navbar.navbar-static-top
.navbar-inner
a.brand href='/' Tent
ul.nav
== nav_link_with_active 'Intro', '/'
== nav_link_with_active 'Blog', '/blog'
== nav_link_with_active 'Docs', '/docs'

1
layouts/none.slim Normal file
View file

@ -0,0 +1 @@
== yield

9
layouts/post.slim Normal file
View file

@ -0,0 +1,9 @@
doctype html
html lang='en'
head == render 'head'
body
== render 'navbar'
.container
.row
.span8.offset2
== render '_post', post: @item, content: yield

View file

@ -5,6 +5,10 @@ RubyPython.start python_exe: 'python2.6' if ENV['RACK_ENV'] == 'production'
class MarkdownHTML < Redcarpet::Render::HTML class MarkdownHTML < Redcarpet::Render::HTML
include Redcarpet::Render::SmartyPants include Redcarpet::Render::SmartyPants
def initialize(options={})
super options.merge(with_toc_data: true)
end
def block_code(code, language) def block_code(code, language)
Pygments.highlight(code, lexer: language) Pygments.highlight(code, lexer: language)
end end

14
lib/nav.rb Normal file
View file

@ -0,0 +1,14 @@
include Nanoc::Helpers::LinkTo
def nav_link_with_active(text, target, attributes = {})
path = target.is_a?(String) ? target : target.path
rep_path = @item_rep.path
active = if path == '/'
path == rep_path
else
/^#{path}/ =~ rep_path
end
"<li #{'class="active"' if active}>" + link_to(text, target, attributes) + "</li>"
end

4
lib/render_child.rb Normal file
View file

@ -0,0 +1,4 @@
def render_child(name)
child = @item.children.find { |child| child.identifier == name }
child.reps.find { |rep| rep.name == :default }.content_at_snapshot(:last)
end