Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
9
Help us understand the problem. What is going on with this article?
@zaneli@github

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

More than 5 years have passed since last update.

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という関数名をつけたのは、
ページ初期表示時と動的なページ読み込み時にそれぞれ呼ぶことを想定しているため。

9
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
9
Help us understand the problem. What is going on with this article?