lib/lti_template_builder/recipes/lti_extension/template.erb
inject_into_file "app/controllers/#{name}/lti_controller.rb", after: "def index\n" do <<-"RUBY"
@launch_params = params.reject!{ |k,v| ['controller','action'].include? k }
end
def launch
url = params[:url]
if url && url =~ /\\Ahttps?:\\/\\/.+\\..+\\Z/
redirect_to url
else
head 500
end
end
def embed
launch_params = JSON.parse(params[:launch_params] || "{}")
tp = IMS::LTI::ToolProvider.new(nil, nil, launch_params)
tp.extend IMS::LTI::Extensions::Content::ToolProvider
# The following code is used as an example of content being returned.
# This should be replaced by actual logic.
embed_type = params[:embed_type]
if embed_type =~ /Video/
@content_type = "iframe"
@title = "Getting Started in Canvas Network"
@url = "https://player.vimeo.com/video/79702646"
@width = "500"
@height = "284"
elsif embed_type =~ /Picture/
@content_type = "image_url"
@title = "Laughing Dog"
@url = "https://dl.dropboxusercontent.com/u/2176587/laughing_dog.jpeg"
@width = "284"
@height = "177"
elsif embed_type =~ /Link/
@content_type = "url"
@title = "Edu App Center"
@url = "https://www.eduappcenter.com"
end
redirect_url = build_url(tp, @title, @url, @width, @height, @content_type)
if redirect_url.present?
redirect_to redirect_url
end
end
def xml_config
host = "\#{request.protocol}\#{request.host_with_port}"
url = "\#{host}\#{root_path}"
title = "#{name.humanize.titleize}"
tool_id = "#{name}"
tc = IMS::LTI::ToolConfig.new(:title => title, :launch_url => url)
tc.extend IMS::LTI::Extensions::Canvas::ToolConfig
tc.description = "[description goes here]"
tc.canvas_privacy_anonymous!
tc.canvas_domain!(request.host)
tc.canvas_icon_url!("\#{host}/assets/#{name}/icon.png")
tc.canvas_text!(title)
tc.set_ext_param('canvas.instructure.com', :tool_id, tool_id)
<%= @additional_configs.join("\n") %>
render xml: tc.to_xml
end
def health_check
head 200
end
private
def build_url(tp, title, url, width, height, content_type)
if tp.accepts_content?
redirect_url = nil
if content_type == "image_url" && tp.accepts_url?
redirect_url = tp.image_content_return_url(url, width, height, title)
elsif content_type == "iframe" && tp.accepts_iframe?
redirect_url = tp.iframe_content_return_url(url, width, height, title)
elsif tp.accepts_url?
redirect_url = tp.url_content_return_url(url, title, title)
elsif tp.accepts_lti_launch_url?
launch_url = launch_url(url: url)
redirect_url = tp.lti_launch_content_return_url(launch_url, title, title)
end
return redirect_url
end
RUBY
end
route 'root "lti#index"'
route 'match "/" => "lti#index", via: [:get, :post]'
route 'get "health_check" => "lti#health_check"'
route 'get "config(.xml)" => "lti#xml_config", as: :lti_xml_config'
route 'match "launch" => "lti#launch", as: :launch, via: [:get, :post]'
route 'get "test/backdoor"'
remove_file "app/views/#{name}/lti/index.html.erb"
create_file "app/views/#{name}/lti/index.html.erb" do <<-'RUBY'
<div class="container">
<h4 class="page-header">
<%%= link_to "config.xml", lti_xml_config_path, class: "btn btn-xs btn-primary pull-right" %>
<%%= image_tag "NAME/icon.png" %> My LTI App
</h4>
<p>
This is an example of how you can select a resource and have it be embedded via LTI.
</p>
<%%= form_tag lti_embed_path do %>
<input type="hidden" name="launch_params" value="<%%= @launch_params.to_json %>" />
<div class="row">
<div class="col-xs-4">
<input type="submit" name="embed_type" class="btn btn-large btn-info btn-block"
value="Embed a Video" />
</div>
<div class="col-xs-4">
<input type="submit" name="embed_type" class="btn btn-large btn-success btn-block"
value="Embed a Picture" />
</div>
<div class="col-xs-4">
<input type="submit" name="embed_type" class="btn btn-large btn-warning btn-block"
value="Embed a Link" />
</div>
</div>
<%% end %>
</div>
RUBY
end
gsub_file "app/views/#{name}/lti/index.html.erb", "NAME", name
create_file "app/views/#{name}/lti/embed.html.erb" do <<-'RUBY'
<div class="container">
<h4 class="page-header">Embed Code Generated</h4>
<p>
You're not in a system that supports auto-inserting content,
so you'll need to copy and past the following code by hand
in order to insert it into your content.
</p>
<textarea class="form-control" rows="4"><iframe title="<%%= @title %>" width="<%%= @width %>" height="<%%= @height %>" src="<%%= @url %>" /></textarea>
</div>
RUBY
end
inject_into_file "app/controllers/#{name}/lti_controller.rb", after: "require_dependency \"#{name}/application_controller\"\n" do <<-"RUBY"
require "ims/lti"
RUBY
end
gsub_file "spec/controllers/#{name}/lti_controller_spec.rb", "get 'index'\n", "get 'index', use_route: :#{name}\n"
route 'post "embed" => "lti#embed", as: :lti_embed'
inject_into_file "spec/controllers/#{name}/lti_controller_spec.rb", after: "response.should be_success\n end\n" do <<-"RUBY"
describe "GET config" do
it "should generate a valid xml cartridge" do
request.stub(:env).and_return({
"SCRIPT_NAME" => "/#{name}",
"rack.url_scheme" => "http",
"HTTP_HOST" => "test.host",
"PATH_INFO" => "/#{name}"
})
get 'xml_config', use_route: :#{name}
expect(response.body).to include('<blti:title>#{name.humanize.titleize}</blti:title>')
expect(response.body).to include('<blti:description>[description goes here]</blti:description>')
expect(response.body).to include('<lticm:property name="text">#{name.humanize.titleize}</lticm:property>')
expect(response.body).to include('<lticm:property name="tool_id">#{name}</lticm:property>')
expect(response.body).to include('<lticm:property name=\"icon_url\">http://test.host/assets/#{name}/icon.png</lticm:property>')
end
end
RUBY
end
inject_into_file "spec/controllers/#{name}/lti_controller_spec.rb", after: "icon.png</lticm:property>')" do <<-"RUBY"
<%= @extra_expects.join("\n") %>
RUBY
end
inside("app/assets/images/#{name}") do
run "curl -O https://dl.dropboxusercontent.com/u/2176587/icon.png"
end