LoginSignup
10
9

More than 5 years have passed since last update.

Gist外部埋め込みHTMLをJSONPで受け取る

Last updated at Posted at 2013-12-27

Gistをブログなど外部ページで表示したい場合、
Embed用JavaScript("https://gist.github.com/<ユーザー名>/<Gist ID>.js")が提供されているけれど、
これは document.write() を呼んでHTMLを書き込んでいるため、
動的なページ読み込みとの相性が良くない。
(document.write()を一時的に上書きして出力内容を保存し、最後に任意の箇所にappendするなど)

別途JSONやJSONPで document.write()書き込み内容と同様のHTMLタグ文字列を返すAPIも存在しているようなので
それを使用して外部ページ埋め込みを行ってみることにする。

JSではdocument.write()を二回呼び、一回目でCSSへのリンク用タグ, 二回目で内容自体を書き込んでいるが、
JSONでは stylesheet, div に加えて description , owner, created_at といった情報も返される。

JQuery + CoffeeScript でこの JSON を処理してみる。

gist.html
<p>euler1.hs</p>
<div class="gist" data-user="zaneli" data-id="6131635" data-file="euler1.hs"></div>
<p>euler2-1.hs</p>
<div class="gist" data-user="zaneli" data-id="6131635" data-file="euler2-1.hs"></div>
<button id="readmorebtn" />readmore</button>
<div id="readmorearea"></div>
gist.coffee
$ ->
  appendGist = ->
    host = "https://gist.github.com"
    $(".gist").each (index) ->
      $this = $(@)

      id = $this.data "id"
      return unless id?

      user = $this.data "user"
      file = $this.data "file"

      url = (x for x in [host, user, "#{id}.json"] when x?).join "/"
      param = ("#{k}=#{v}" for k, v of {callback : "callback#{index}",file: file} when v?).join "&"

      $this.attr "class", "gist#{index}"
      $.ajax
        type: "GET",
        url: "#{url}?#{param}",
        dataType: "jsonp",
        jsonpCallback: "callback#{index}",
        success: (json) ->
          $(".gist#{index}").append """<link rel="stylesheet" href="#{host}/#{json.stylesheet}" />"""
          $(".gist#{index}").append json.div

  $("#readmorebtn").click ->
    $("#readmorearea").append("""
      <p>euler2-2.hs</p>
      <div class="gist" data-user="zaneli" data-id="6131635" data-file="euler2-2.hs"></div>
      <p>all</p>
      <div class="gist" data-user="zaneli" data-id="6131635"></div>""")
    appendGist()

  appendGist()

user が指定されていない場合
(#{host}/#{id}.json にリクエストを投げるとユーザー名を補ったURLにリダイレクトされる)、
ファイル名が指定されていない場合
(一つのGistに複数ファイルがある場合、指定するとそのファイルのみ、指定しないと全てのファイルが返される)
などを考慮して、
url と param を作るところでリスト内包表記的に処理してみたが、パッと見分かりづらくなったかもしれない…。
ユーザー名を指定しない前提でシンプルにやるなら

url = "#{host}/#{id}.json?callback=callback#{index}"
url += "&file=#{file}" if file?

とか

url = "#{host}/#{id}.json?callback=callback#{index}#{if file? then "&file=#{file}" else ""}"

でも十分なはず。
(無駄にリダイレクトが発生してしまうので、逆にユーザー名指定必須だったりユーザー名固定でもいいかも。)

無名関数ではなくappendGistという関数名をつけたのは、
ページ初期表示時と動的なページ読み込み時にそれぞれ呼ぶことを想定しているため。

10
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
9