Module: JSONRPC2::HTML
- Defined in:
- lib/jsonrpc2/html.rb
Overview
HTML output helpers for browseable API interface
Constant Summary collapse
- ASSET_DIR =
File.dirname(File.dirname(__FILE__))+'/assets'
- MISSING =
<<-EOM <!DOCTYPE html> <html> <head><title>404 Not found</title></head> <body>404 Not found</body> </html> EOM
Class Method Summary collapse
-
.call(interface, request) ⇒ Rack::Response
Process browser request for #interface.
-
.describe(interface, request, info, options = {}) ⇒ Object
Returns HTML page describing method.
-
.format_result(result) ⇒ Object
Format JSON result.
-
.html5(title, body, options = {}) ⇒ Object
Wrap body in basic bootstrap template using cdn.
Class Method Details
.call(interface, request) ⇒ Rack::Response
Process browser request for #interface
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
# File 'lib/jsonrpc2/html.rb', line 64 def call(interface, request) #require 'pp'; pp interface.about if interface.auth_with response = catch(:rack_response) do interface.auth_with.browser_check(request.env); nil end return response if response end case request.path_info when %r'^/_assets/((img|css|js)/[a-z][-a-z0-9.]+)$' name = $1 path = File.join(ASSET_DIR, name) if File.exist?(path) [200, {'Content-Type' => { '.js' => 'text/javascript', '.css' => 'text/css', '.png' => 'image/png'}[File.extname(name)]}, [File.read(path)]] else [404, {'Content-Type' => 'text/html'}, []] end when /^\/([a-zA-Z_0-9]+)/ method = $1 if info = interface.about_method(method) if json = request.POST['__json__'] begin data = JSON.parse(json) result = interface.new(request.env).dispatch(data) rescue => e result = e.class.name + ": " + e. end end [200, {'Content-Type' => 'text/html'}, html5(method,describe(interface, request, info, :result => result), :request => request) ] else [404, {'Content-Type' => 'text/html'}, html5("Method not found", "<h1>No such method</h1>", :request => request)] end else body = RedCloth.new(interface.to_textile).to_html.gsub(/\<h3\>(.*?)\<\/h3\>/, '<h3><a href="'+request.script_name+'/\1">\1</a></h3>') [200, {'Content-Type' => 'text/html'}, html5('Interface: '+interface.name.to_s, body, :request => request)] end end |
.describe(interface, request, info, options = {}) ⇒ Object
Returns HTML page describing method
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 |
# File 'lib/jsonrpc2/html.rb', line 109 def describe interface, request, info, = {} params = {} if info[:params] info[:params].each do |param| params[param[:name]] = case param[:type] when 'String' "" when 'Boolean', 'false' false when 'true' true when 'null' nil when 'Number', 'Integer' 0 when /^Array/ [] when 'Time' "00:00" when 'DateTime' Time.at(0).iso8601 when 'Date' '1970-01-01' else {} end end end <<-EOS <h1>Method Info: #{info[:name]}</h1> #{RedCloth.new(interface.method_to_textile(info)).to_html} <hr> <div class="row"> <div class="span6"> <h2>Test method</h2> </div> <div class="span6"> <h3>Result</h3> </div> </div> <div class="row"> <div class="span6"> <form method="POST" action="#{request.script_name}/#{info[:name]}"> <textarea name="__json__" cols="60" rows="8" class="span6"> #{CGI.escapeHTML((request.POST['__json__'] || JSON.pretty_unparse({'jsonrpc'=>'2.0', 'method' => info[:name], 'id' => 1, 'params' => params})).strip)} </textarea> <div class="form-actions"> <input type="submit" class="btn btn-primary" value="Call Method"> </div> </form> </div> <div class="span6"> <pre style="white-space: prewrap">#{format_result([:result])}</pre> </div> </div> EOS end |
.format_result(result) ⇒ Object
Format JSON result
170 171 172 173 174 175 176 177 |
# File 'lib/jsonrpc2/html.rb', line 170 def format_result(result) CGI.escapeHTML(JSON.pretty_unparse(JSON.parse(result))).gsub(%r<("|")https?://[^"]+?("|")>) do |str| url = CGI.unescapeHTML(str)[1...-1] %Q["<a href="#{CGI.escapeHTML(url)}">#{CGI.escapeHTML(url)}</a>"] end rescue Exception => e CGI.escapeHTML(result.to_s) end |
.html5(title, body, options = {}) ⇒ Object
Wrap body in basic bootstrap template using cdn
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/jsonrpc2/html.rb', line 8 def html5(title, body, ={}) request = [:request] [ <<-HTML5 <!DOCTYPE html><html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>#{title}</title> #{[:head]} <link rel="stylesheet" href="#{request.script_name}/_assets/css/bootstrap.min.css"> <script src="#{request.script_name}/_assets/js/jquery-1.10.2.min.js"></script> <script src="#{request.script_name}/_assets/js/bootstrap.min.js"></script> <style> body { padding-top: 60px; /* 60px to make the container go all the way to the bottom of the topbar */ } </style> </head> <body> <div class="navbar navbar-fixed-top"> <div class="navbar-inner"> <div class="container"> <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse"> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </a> <a class="brand" href="#">JSON-RPC Interface</a> <div class="nav-collapse"> <ul class="nav"> <li class="#{['', '/'].include?(request.path_info) ? 'active' : ''}"><a href="#{request.script_name}/">API Overview</a></li> </ul> </div><!--/.nav-collapse --> </div> </div> </div> <div class="container">#{body}</div> </body> </html> HTML5 ] end |