summaryrefslogtreecommitdiff
path: root/app/views
diff options
context:
space:
mode:
Diffstat (limited to 'app/views')
-rw-r--r--app/views/.gitkeep0
-rw-r--r--app/views/common/_action_buttons.html.haml11
-rw-r--r--app/views/common/_download_button.html.haml8
-rw-r--r--app/views/common/_home_page_buttons.html.haml8
-rw-r--r--app/views/emails/_email.html.haml6
-rw-r--r--app/views/home/_content.html.haml2
-rw-r--r--app/views/kaminari/_first_page.html.haml9
-rw-r--r--app/views/kaminari/_gap.html.haml8
-rw-r--r--app/views/kaminari/_last_page.html.haml9
-rw-r--r--app/views/kaminari/_next_page.html.haml12
-rw-r--r--app/views/kaminari/_page.html.haml14
-rw-r--r--app/views/kaminari/_paginator.html.haml19
-rw-r--r--app/views/kaminari/_prev_page.html.haml12
-rw-r--r--app/views/layouts/_footer.html.haml4
-rw-r--r--app/views/layouts/_header.html.haml2
-rw-r--r--app/views/layouts/_masthead.html.haml2
-rw-r--r--app/views/layouts/application.html.haml3
-rw-r--r--app/views/pages/pricing.html.haml6
-rw-r--r--app/views/sessions/new.html.haml9
-rw-r--r--app/views/sessions/new.json.erb3
-rw-r--r--app/views/users/_change_password.html.haml21
-rw-r--r--app/views/users/_change_pgp_key.html.haml13
-rw-r--r--app/views/users/_change_service_level.html.haml18
-rw-r--r--app/views/users/_destroy_account.html.haml27
-rw-r--r--app/views/users/_edit.html.haml14
-rw-r--r--app/views/users/_user.html.haml4
-rw-r--r--app/views/users/_warnings.html.haml12
-rw-r--r--app/views/users/edit.html.haml1
-rw-r--r--app/views/users/index.html.haml13
-rw-r--r--app/views/users/new.html.haml21
-rw-r--r--app/views/users/show.html.haml30
-rw-r--r--app/views/v1/sessions/new.json.erb3
-rw-r--r--app/views/webfinger/host_meta.xml.erb11
-rw-r--r--app/views/webfinger/search.xml.erb7
34 files changed, 332 insertions, 10 deletions
diff --git a/app/views/.gitkeep b/app/views/.gitkeep
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/app/views/.gitkeep
diff --git a/app/views/common/_action_buttons.html.haml b/app/views/common/_action_buttons.html.haml
new file mode 100644
index 0000000..c74fcd1
--- /dev/null
+++ b/app/views/common/_action_buttons.html.haml
@@ -0,0 +1,11 @@
+.home-buttons
+ .row-fluid.second
+ .login.span4
+ %span.link= link_to(icon('ok-sign', icon_color) + t(:login), login_path, :class => 'btn')
+ %span.info= t(:login_info)
+ .signup.span4
+ %span.link= link_to(icon('user', icon_color) + t(:signup), signup_path, :class => 'btn')
+ %span.info= t(:signup_info)
+ .help.span4
+ %span.link= link_to(icon('question-sign', icon_color) + t(:get_help), new_ticket_path, :class => 'btn')
+ %span.info= t(:help_info)
diff --git a/app/views/common/_download_button.html.haml b/app/views/common/_download_button.html.haml
new file mode 100644
index 0000000..e57c56b
--- /dev/null
+++ b/app/views/common/_download_button.html.haml
@@ -0,0 +1,8 @@
+.home-buttons
+ .row-fluid.first
+ .span2
+ .download.span8
+ = link_to client_download_url, class: "btn btn-large btn-primary" do
+ = big_icon('download')
+ = t(:download_client)
+ .span2
diff --git a/app/views/common/_home_page_buttons.html.haml b/app/views/common/_home_page_buttons.html.haml
new file mode 100644
index 0000000..8c47983
--- /dev/null
+++ b/app/views/common/_home_page_buttons.html.haml
@@ -0,0 +1,8 @@
+- icon_color = :black
+
+= render 'common/download_button'
+- if local_assigns[:divider]
+ .row-fluid
+ .span12
+ = render local_assigns[:divider]
+= render 'common/action_buttons', icon_color: icon_color
diff --git a/app/views/emails/_email.html.haml b/app/views/emails/_email.html.haml
new file mode 100644
index 0000000..ea59cec
--- /dev/null
+++ b/app/views/emails/_email.html.haml
@@ -0,0 +1,6 @@
+= wrapped(email, local_assigns) do
+ = email
+ - if local_assigns[:with].try(:include?, :delete)
+ = link_to(user_email_alias_path(@user, email), :method => :delete) do
+ %i.icon-remove
+
diff --git a/app/views/home/_content.html.haml b/app/views/home/_content.html.haml
index 3d351e9..e47fdaf 100644
--- a/app/views/home/_content.html.haml
+++ b/app/views/home/_content.html.haml
@@ -9,6 +9,4 @@
.row-fluid
%hr
%p
- = link_to "fetch a cert", cert_path
- %p
= link_to "make donation", new_payment_path if APP_CONFIG[:payment].present?
diff --git a/app/views/kaminari/_first_page.html.haml b/app/views/kaminari/_first_page.html.haml
new file mode 100644
index 0000000..34436e3
--- /dev/null
+++ b/app/views/kaminari/_first_page.html.haml
@@ -0,0 +1,9 @@
+-# Link to the "First" page
+-# available local variables
+-# url: url to the first page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%li
+ = link_to_unless current_page.first?, raw(t 'views.pagination.first'), url, :remote => remote
diff --git a/app/views/kaminari/_gap.html.haml b/app/views/kaminari/_gap.html.haml
new file mode 100644
index 0000000..51de678
--- /dev/null
+++ b/app/views/kaminari/_gap.html.haml
@@ -0,0 +1,8 @@
+-# Non-link tag that stands for skipped pages...
+-# available local variables
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%li.disabled
+ = raw(t 'views.pagination.truncate')
diff --git a/app/views/kaminari/_last_page.html.haml b/app/views/kaminari/_last_page.html.haml
new file mode 100644
index 0000000..c90433c
--- /dev/null
+++ b/app/views/kaminari/_last_page.html.haml
@@ -0,0 +1,9 @@
+-# Link to the "Last" page
+-# available local variables
+-# url: url to the last page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+%li
+ = link_to_unless current_page.last?, raw(t 'views.pagination.last'), url, {:remote => remote}
diff --git a/app/views/kaminari/_next_page.html.haml b/app/views/kaminari/_next_page.html.haml
new file mode 100644
index 0000000..ea6cab2
--- /dev/null
+++ b/app/views/kaminari/_next_page.html.haml
@@ -0,0 +1,12 @@
+-# Link to the "Next" page
+-# available local variables
+-# url: url to the next page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+- if current_page.last?
+ %li.disabled
+ %span= raw(t 'views.pagination.next')
+- else
+ %li= link_to(raw(t 'views.pagination.next'), url, :rel => 'next', :remote => remote)
diff --git a/app/views/kaminari/_page.html.haml b/app/views/kaminari/_page.html.haml
new file mode 100644
index 0000000..2f2f142
--- /dev/null
+++ b/app/views/kaminari/_page.html.haml
@@ -0,0 +1,14 @@
+-# Link showing page number
+-# available local variables
+-# page: a page object for "this" page
+-# url: url to this page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+
+- if page.current?
+ %li.active
+ %span= page
+- else
+ %li= link_to(page, url, {:remote => remote, :rel => page.next? ? 'next' : page.prev? ? 'prev' : nil})
diff --git a/app/views/kaminari/_paginator.html.haml b/app/views/kaminari/_paginator.html.haml
new file mode 100644
index 0000000..79c5b92
--- /dev/null
+++ b/app/views/kaminari/_paginator.html.haml
@@ -0,0 +1,19 @@
+-# The container tag
+-# available local variables
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+-# paginator: the paginator that renders the pagination tags inside
+= paginator.render do
+ .pagination
+ %ul
+ -#= first_page_tag unless current_page.first?
+ = prev_page_tag #unless current_page.first?
+ - each_page do |page|
+ - if page.left_outer? || page.right_outer? || page.inside_window?
+ = page_tag page
+ - elsif !page.was_truncated?
+ = gap_tag
+ = next_page_tag #unless current_page.last?
+ -#= last_page_tag unless current_page.last?
diff --git a/app/views/kaminari/_prev_page.html.haml b/app/views/kaminari/_prev_page.html.haml
new file mode 100644
index 0000000..d274bf4
--- /dev/null
+++ b/app/views/kaminari/_prev_page.html.haml
@@ -0,0 +1,12 @@
+-# Link to the "Previous" page
+-# available local variables
+-# url: url to the previous page
+-# current_page: a page object for the currently displayed page
+-# num_pages: total number of pages
+-# per_page: number of items to fetch per page
+-# remote: data-remote
+- if current_page.first?
+ %li.disabled
+ %span= raw(t 'views.pagination.previous')
+- else
+ %li= link_to(raw(t 'views.pagination.previous'), url, :rel => 'prev', :remote => remote)
diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml
index 5909bdd..340d36c 100644
--- a/app/views/layouts/_footer.html.haml
+++ b/app/views/layouts/_footer.html.haml
@@ -6,5 +6,5 @@
= link_to icon('info-sign') + t(:about), about_path
- if lookup_context.exists?('pages/contact')
= link_to icon('comment') + t(:contact), contact_path
- - if APP_CONFIG[:service_levels]
- = link_to icon('shopping-cart') + t(:pricing), pricing_path \ No newline at end of file
+ - if APP_CONFIG[:service_levels].present?
+ = link_to icon('shopping-cart') + t(:pricing), pricing_path
diff --git a/app/views/layouts/_header.html.haml b/app/views/layouts/_header.html.haml
index 157f1df..a1dd47a 100644
--- a/app/views/layouts/_header.html.haml
+++ b/app/views/layouts/_header.html.haml
@@ -8,5 +8,5 @@
%li
= link_to t(:logout), logout_path, :method => :delete
- if @user && @show_navigation
- .user_heading
+ .lead
= @user.email_address
diff --git a/app/views/layouts/_masthead.html.haml b/app/views/layouts/_masthead.html.haml
index 35225a1..fde5915 100644
--- a/app/views/layouts/_masthead.html.haml
+++ b/app/views/layouts/_masthead.html.haml
@@ -2,5 +2,3 @@
.title
%span.sitename
%a{:href => home_path}= APP_CONFIG[:domain]
- - if @show_navigation
- = t(:user_control_panel) \ No newline at end of file
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 1cd4ec3..d213fe1 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -14,6 +14,9 @@
= render 'layouts/masthead'
#main
.container-fluid
+ - if @show_navigation
+ .row-fluid
+ %h1= t(:user_control_panel)
- if logged_in?
.row-fluid
.span12
diff --git a/app/views/pages/pricing.html.haml b/app/views/pages/pricing.html.haml
index 77699d8..e339d27 100644
--- a/app/views/pages/pricing.html.haml
+++ b/app/views/pages/pricing.html.haml
@@ -13,9 +13,9 @@
%td= level[:name]
%td= level[:description]
%td
- - if level[:cost].nil? || level[:cost] == 0
+ - if level[:rate].nil? || level[:rate] == 0
= t(:free)
- else
- = level[:cost].map{|currency,cost| "#{cost} #{currency}"}.join(', ')
+ = level[:rate].collect{|currency, price| "#{currency} #{price}"}.join(', ')
- else
- No service levels are configured. \ No newline at end of file
+ No service levels are configured.
diff --git a/app/views/sessions/new.html.haml b/app/views/sessions/new.html.haml
new file mode 100644
index 0000000..bb7e4bd
--- /dev/null
+++ b/app/views/sessions/new.html.haml
@@ -0,0 +1,9 @@
+.span1
+.span9
+ %h2=t :login
+ .lead=t :login_info
+ = render :partial => 'users/warnings'
+ = simple_form_for [:api, @session], validate: true, html: { id: :new_session, class: 'form-horizontal hidden js-show', style: "display:none;" } do |f|
+ = f.input :login, :required => false, :label => t(:username), :input_html => { :id => :srp_username }
+ = f.input :password, :required => false, :input_html => { :id => :srp_password }
+ = f.button :wrapped, value: t(:login), cancel: home_path
diff --git a/app/views/sessions/new.json.erb b/app/views/sessions/new.json.erb
new file mode 100644
index 0000000..36154b8
--- /dev/null
+++ b/app/views/sessions/new.json.erb
@@ -0,0 +1,3 @@
+{
+"errors": <%= raw @errors.to_json %>
+}
diff --git a/app/views/users/_change_password.html.haml b/app/views/users/_change_password.html.haml
new file mode 100644
index 0000000..425e3ee
--- /dev/null
+++ b/app/views/users/_change_password.html.haml
@@ -0,0 +1,21 @@
+-#
+-# CHANGE PASSWORD
+-#
+-# * everything about this form is handled with javascript. So take care when changing any ids.
+-# * the login is required when changing the password because it is used as part of the salt when calculating the password verifier.
+-# however, we don't want the user to change their login without generating a new key, so we hide the ui for this
+-# (although it works perfectly fine to change username if the field was visible).
+-#
+
+- form_options = {:url => '/not-used', :html => {:class => user_form_class('form-horizontal'), :id => 'update_login_and_password', :data => {token: session[:token]}}, :validate => true}
+= simple_form_for @user, form_options do |f|
+ %legend= t(:change_password)
+ = hidden_field_tag 'user_param', @user.to_param
+ .hidden
+ = f.input :login, :label => t(:username), :required => false, :input_html => {:id => :srp_username}
+ = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password }
+ = f.input :password_confirmation, :required => false, :input_html => { :id => :srp_password_confirmation }
+ .control-group
+ .controls
+ = f.submit t(:save), :class => 'btn btn-primary'
+
diff --git a/app/views/users/_change_pgp_key.html.haml b/app/views/users/_change_pgp_key.html.haml
new file mode 100644
index 0000000..e465125
--- /dev/null
+++ b/app/views/users/_change_pgp_key.html.haml
@@ -0,0 +1,13 @@
+-#
+-# CHANGE PGP KEY
+-#
+-# this will be replaced by a identities controller/view at some point
+-#
+
+- form_options = {:html => {:class => user_form_class('form-horizontal'), :id => 'update_pgp_key', :data => {token: session[:token]}}, :validate => true}
+= simple_form_for [:api, @user], form_options do |f|
+ %legend= t(:advanced_options)
+ = f.input :public_key, :as => :text, :hint => t(:use_ascii_key), :input_html => {:class => "full-width", :rows => 4}
+ .control-group
+ .controls
+ = f.submit t(:save), :class => 'btn', :data => {"loading-text" => "Saving..."}
diff --git a/app/views/users/_change_service_level.html.haml b/app/views/users/_change_service_level.html.haml
new file mode 100644
index 0000000..42315a2
--- /dev/null
+++ b/app/views/users/_change_service_level.html.haml
@@ -0,0 +1,18 @@
+-# TODO: probably won't want here, but here for now. Also, we will need way to ensure payment if they pick a non-free plan.
+-#
+-# SERVICE LEVEL
+-#
+- if APP_CONFIG[:service_levels]
+ - form_options = {:html => {:class => user_form_class('form-horizontal'), :id => 'update_service_level', :data => {token: session[:token]}}, :validate => true}
+ = simple_form_for @user, form_options do |f|
+ %legend= t(:service_level)
+ - if @user != current_user
+ = t(:desired_service_level)
+ = f.select :desired_service_level_code, ServiceLevel.select_options, :selected => @user.desired_service_level.id
+ - if @user != current_user
+ %p
+ = t(:effective_service_level)
+ = f.select :effective_service_level_code, ServiceLevel.select_options, :selected => @user.effective_service_level.id
+ .control-group
+ .controls
+ = f.submit t(:save), :class => 'btn', :data => {"loading-text" => "Saving..."}
diff --git a/app/views/users/_destroy_account.html.haml b/app/views/users/_destroy_account.html.haml
new file mode 100644
index 0000000..445f3c4
--- /dev/null
+++ b/app/views/users/_destroy_account.html.haml
@@ -0,0 +1,27 @@
+-#
+-# DESTROY ACCOUNT
+-#
+
+%legend
+ - if @user == current_user
+ = t(:destroy_my_account)
+ - else
+ = t(:admin_destroy_account, :username => @user.login)
+%p= t(:destroy_account_info)
+= link_to user_path(@user), :method => :delete, :confirm => t(:are_you_sure), :class => "btn btn-danger" do
+ %i.icon-remove.icon-white
+ = t(:destroy_my_account)
+- if @user != current_user and @user.enabled?
+ %legend
+ = t(:deactivate_account, :username => @user.login)
+ %p= t(:deactivate_description)
+ = link_to deactivate_user_path(@user), :method => :post, :class => "btn btn-warning" do
+ %i.icon-pause.icon-white
+ = t(:deactivate)
+- elsif @user != current_user and !@user.enabled?
+ %legend
+ = t(:enable_account, :username => @user.login)
+ %p= t(:enable_description)
+ = link_to enable_user_path(@user), :method => :post, :class => "btn btn-warning" do
+ %i.icon-ok.icon-white
+ = t(:enable)
diff --git a/app/views/users/_edit.html.haml b/app/views/users/_edit.html.haml
new file mode 100644
index 0000000..1d2b68a
--- /dev/null
+++ b/app/views/users/_edit.html.haml
@@ -0,0 +1,14 @@
+-#
+-# edit user form, used by both show and edit actions.
+-#
+-# We render a bunch of forms here. Which we use depends upon config settings
+-# user_actions and admin_actions. They both include an array of actions
+-# allowed to users and admins.
+-# Possible forms are:
+-# 'change_password'
+-# 'change_pgp_key'
+-# 'change_service_level'
+-# 'destroy_account'
+- actions = APP_CONFIG[admin? ? :admin_actions : :user_actions] || []
+- actions.each do |action|
+ = render action
diff --git a/app/views/users/_user.html.haml b/app/views/users/_user.html.haml
new file mode 100644
index 0000000..583d22f
--- /dev/null
+++ b/app/views/users/_user.html.haml
@@ -0,0 +1,4 @@
+%tr
+ %td= link_to user.login, user
+ %td= l(user.created_at, :format => :short)
+ %td= l(user.updated_at, :format => :short)
diff --git a/app/views/users/_warnings.html.haml b/app/views/users/_warnings.html.haml
new file mode 100644
index 0000000..baf80a4
--- /dev/null
+++ b/app/views/users/_warnings.html.haml
@@ -0,0 +1,12 @@
+%noscript
+ %div.alert.alert-error=t :js_required_html
+#cookie_warning.alert.alert-error{:style => "display:none"}
+ =t :cookie_disabled_warning
+:javascript
+ document.cookie = "testing=cookies_enabled; path=/";
+ if(document.cookie.indexOf("testing=cookies_enabled") < 0)
+ {
+ document.getElementById('cookie_warning').style.display = 'block';
+ } else {
+ document.getElementById('cookie_warning').style.display = 'none';
+ }
diff --git a/app/views/users/edit.html.haml b/app/views/users/edit.html.haml
new file mode 100644
index 0000000..434c025
--- /dev/null
+++ b/app/views/users/edit.html.haml
@@ -0,0 +1 @@
+= render 'edit'
diff --git a/app/views/users/index.html.haml b/app/views/users/index.html.haml
new file mode 100644
index 0000000..fc1001e
--- /dev/null
+++ b/app/views/users/index.html.haml
@@ -0,0 +1,13 @@
+- @show_navigation = false
+
+= form_tag users_path, :method => :get, :class => "form-search" do
+ .input-append
+ = text_field_tag :query, params[:query], :id => 'user-typeahead', :class => "search-query", :autocomplete => :off
+ %button.btn{:type => :submit}= t(:search)
+
+%table.table.table-striped
+ %tr
+ %th= t(:username)
+ %th= t(:created)
+ %th= t(:updated)
+ = render @users.all
diff --git a/app/views/users/new.html.haml b/app/views/users/new.html.haml
new file mode 100644
index 0000000..bc36068
--- /dev/null
+++ b/app/views/users/new.html.haml
@@ -0,0 +1,21 @@
+-#
+-# This form is handled entirely by javascript
+-# Please take care when changing element ids.
+-#
+-# The form is hidden when no js is available
+-# to prevent submission in the clear.
+-#
+
+- form_options = {url: '/not-used', html: {id: 'new_user', class: user_form_class('form-horizontal'), style: 'display:none'}, validate: true}
+
+.span1
+.span9
+ %h2=t :signup
+ .lead=t :signup_info
+ = render :partial => 'warnings'
+ = simple_form_for(@user, form_options) do |f|
+ = f.input :login, :label => t(:username), :required => false, :input_html => { :id => :srp_username }
+ = f.input :password, :required => false, :validate => true, :input_html => { :id => :srp_password }
+ = f.input :password_confirmation, :required => false, :validate => true, :input_html => { :id => :srp_password_confirmation }
+ = f.button :wrapped, value: t(:signup), cancel: home_path
+
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
new file mode 100644
index 0000000..ddc33ab
--- /dev/null
+++ b/app/views/users/show.html.haml
@@ -0,0 +1,30 @@
+.overview
+
+ %h2.first= t(:overview_welcome, :username => @user.login)
+
+ - if admin?
+ %p
+ = t(:created)
+ = @user.created_at
+ %br
+ = t(:updated)
+ = @user.updated_at
+ %br
+ = t(:enabled)
+ = @user.enabled?
+
+ %p= t(:overview_intro)
+
+ %ul.unstyled
+ %li= icon('user') + link_to(t(:overview_account), edit_user_path(@user))
+ - # %li= icon('envelope') + link_to(t(:overview_email), {insert path for user identities, presuambly}
+ %li= icon('question-sign') + link_to(t(:overview_tickets), user_tickets_path(@user))
+ %li= icon('shopping-cart') + link_to(t(:overview_billing), billing_top_link(@user)) if APP_CONFIG[:billing]
+
+
+ .container-fluid
+ .row-fluid
+ %h4 To use bitmask services:
+ = link_to client_download_url, class: "btn btn-primary" do
+ %i.icon-arrow-down.icon-white
+ = t(:download_client)
diff --git a/app/views/v1/sessions/new.json.erb b/app/views/v1/sessions/new.json.erb
new file mode 100644
index 0000000..36154b8
--- /dev/null
+++ b/app/views/v1/sessions/new.json.erb
@@ -0,0 +1,3 @@
+{
+"errors": <%= raw @errors.to_json %>
+}
diff --git a/app/views/webfinger/host_meta.xml.erb b/app/views/webfinger/host_meta.xml.erb
new file mode 100644
index 0000000..cfcbcc0
--- /dev/null
+++ b/app/views/webfinger/host_meta.xml.erb
@@ -0,0 +1,11 @@
+<?xml version='1.0' encoding='UTF-8'?>
+ <XRD xmlns='http://docs.oasis-open.org/ns/xri/xrd-1.0'>
+
+ <Subject><%= @host_meta.subject %></Subject>
+
+ <%- @host_meta.links.each do |rel, link| %>
+ <Link rel='<%= rel %>'
+ type='<%= link[:type] %>'
+ template='<%= link[:template] %>' />
+ <%- end %>
+ </XRD>
diff --git a/app/views/webfinger/search.xml.erb b/app/views/webfinger/search.xml.erb
new file mode 100644
index 0000000..7328552
--- /dev/null
+++ b/app/views/webfinger/search.xml.erb
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">
+ <Subject><%= @presenter.subject %></Subject>
+ <%- @presenter.links.each do |rel, link| %>
+ <Link rel=<%=rel%> type=<%=link[:type]%> href="<%= link[:key] %>"/>
+ <% end %>
+</XRD>