ドグサレ初心者のへっぽこビッグウェーブ

地球の底辺にいるゴミがプログラミングとか音楽とかを語るクソブログ

そこは#じゃなくて.でしょうが!!〜idっていつ使う時あるの?あとTurbolinksは魔物〜

masterkei.hatenablog.com
前回でとりあえずニコ動をたくさんエンベッドすることができるようになったものの、サイズがデフォルトに戻ってしまったので、レスポンシブにしたいぞなもし。

wayohoo.com
CSSで変える方法みっけた。

けど外部プレイヤー表示するところのembedも指定してるんだけどなぁ。なぜだ?

// niconico responsive embed
#nico_player{
  position: relative;
  padding-bottom: 56.25%;
  padding-top: 30px; height: 0; overflow: hidden;
  margin-bottom: 20px;
}

#nico_player embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

#と.を間違えるというクソアンドクソ

単純にclass属性じゃなくてid属性になってたからでした。

// niconico responsive embed
.nico_player{
  position: relative;
  padding-bottom: 56.25%;
  padding-top: 30px; height: 0; overflow: hidden;
  margin-bottom: 20px;
}

.nico_player embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

じゃないとだめでしょうが!!
目のつけどころがシャープだけど気づくの遅くてドットつかれた!!

なーんて



www.nicovideo.jp



埋め込みって難しいすね



で、できてると思ってたらさー

直接リンクだったら出るけど、他のページからリンクすると出ない。

Turbolinksがゴールの邪魔をする

もっかいJSPJavaScriptのPro)に聞いたら、あーこれTurbolinksですね。って。


...

自分も教本読んでなんかイベント発生しないこともあるから気をつけろ的なことかいてあったから関係あるのかなーと思ってたんだよねー

けどちゃんと読んでなかった。
Amazon.co.jp: Ruby on Rails 4アプリケーションプログラミング 電子書籍: 山田祥寛: Kindleストア

まず、「〜/books」への初回アクセスでは、Turbolinksの有効/無効に関わらず、ページ本体+すべてのアセットが読み込まれます。しかし、「〜/books」から「〜/books/new」への遷移では、片やページ本体のみが、片やページ本体+すべてのアセットが読み込まれる点に注目です。

書いてあった。

その幻想をぶち殺す!
というわけで、GemfileのTurbolinksをコメントアウト
application.jsでもTurbolinkをrequireしていたので、同じくコメントアウト


これで出るようになりましったーーーーーーーー

JSPが言うには、
「Turbolinksは昔みたいに回線が貧弱だったり、クライアント側でスクリプトを書きまくってた時代は重宝されてたけど、今の時代はそんなに必要ないんじゃないですかねー。こういう落とし穴もあるし。」
とのことでした。へぇー(白目)

ついでにdetail/indexからtitle/showにリンクさせる

意外とdetail情報をみることが多いのでレイアウトをなんとかしたいんだけども、まずは行き来しやすいようにリンクをば。

<%= link_to 'New Anime detail', controller: :anime_details, action: :new, anime_title_id: @anime_title.id %>
<br>
<%= link_to 'アニメタイトルに戻る', controller: :anime_titles, action: :show, id: @anime_title.id %>
<hr>
<%= link_to 'アニメタイトル一覧', anime_titles_path %>  |
<%= link_to 'トップへ', root_path %>

このあたりのリンクぺたぺたも美しくないので、そのうちどうにかしたいすな。




TODO:
フォームの例外処理エラーがおかしい
トップからtitle/showへの遷移、2回目以降がなぜかおかしな位置(ページ中段)に遷移するので修正
detailページのレイアウト直すのとdetail -> title/showの動線を置く
動画URLもっと楽に入れたい

難しいことしなくてもコピペで完成する時代(ニコニコ外部プレーヤー貼り付けの巻)

前回の続き。masterkei.hatenablog.com


結局よくわからんなぁ。。。となってしまいました。
幸いにも近くにJavascriptのプロがいたので、泣きついてみる。


「わざわざこんな難しいことしなくても、ニコニコの外部URLを張り付ければいいんじゃないですか?」


そうかなー、とか思いながら貼り付けてみた。






できた。


できたーーーーーー



ていうかなんでこれ試さなかったんだろう。

URL丸ごとレコードに格納して、エスケープで表示させたらうまく行かなかった

URLの一部だけをレコードに入れて、スクリプトを書いた

この流れの中で、「URLの一部だけレコードに格納して、タグを直で書く」という発想が抜けたんだな。

くーやしーぃ


というわけで最終的にはこんな感じに。

<div id="g">
  <div class="container">
    <div class="row centered">
      <div class="col-md-8 col-md-offset-2">
        <h2>エンディングテーマ</h2>
        <% @anime_details.each do |anime_detail| %>
            <% if anime_detail.ed_artist? %>
                <br><p>artist:<span class="h3"> <%= anime_detail.ed_artist %></span></p>
                <p>title:<span class="h3"> <%= anime_detail.ed_title %></span></p>
                <% if /\/watch\/([^&]+)/ =~ anime_detail.ed_movie  #niconico %>
                    <div class="nico_player">
                      <script type="text/javascript" src="http://ext.nicovideo.jp/thumb_watch/<%= $1 %>"></script>
                      <noscript><a href="http://www.nicovideo.jp/watch/<%= $1 %>">ニコニコ動画リンク</a></noscript>
                    </div>
      <% elsif /\?v=([^&]+)/ =~ anime_detail.ed_movie #youtube %>
                    <div class="youtube-container">
                      <iframe id="player" type="text/html" width="640" height="390"
                              src="https://www.youtube.com/embed/<%= $1 %>"
                              frameborder="0"></iframe>
                    </div>
                <% end %>
            <% end %>
        <% end %>
      </div><!-- /col-md-8 -->
    </div><!-- /row -->
  </div><!-- /.container -->
</div>


表示できマスタング


わからなくなったときは一回入り口まで戻ってみるのも大事だということを学びましたです。






しかしこれだと今度は.nico_playerのスタイルが反映されなくなった。
アチラを立てればコチラが立たず。。。


つづく。masterkei.hatenablog.com

ニコニコ動画プレーヤーをレスポンシブにエンベッド

とか大層なこと言ってるけど、実際はyoutubeをエンベッドしたときと同じcss書いてるだけ。

masterkei.hatenablog.com

[ .scss ]

// niconico responsive embed
#nico_player{
  position: relative;
  padding-bottom: 56.25%;
  padding-top: 30px; height: 0; overflow: hidden;
  margin-bottom: 20px;
}

#nico_player embed {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

[ .html.erb ]

<div id="nico_player">
</div>
<p><script type="text/javascript">
    $(function(){
        document._write = document.write;
        document.write = function(msg) {
            // id名nico_playerに表示させる
            $("#nico_player").html(msg);
            //document.writeを元に戻す
            document.write = document._write;
        }
        var src = "http://ext.nicovideo.jp/thumb_watch/<%= $1 %>";
        var dst = $("<scr"+"ipt>");  //タグと間違われないようにsplit
        dst.attr("type", "text/javascript");
        dst.attr("src", src);
        //追加
        $("body").append(dst);
    });
</script></p>


テテーン

複数のニコ動貼り付けに対応させる

ニコ動を複数貼り付けると対応できないことが判明。指定したidがあるタグに直接書き込んでるんだもんそうなるよね。

なんとかなるんじゃないかと思ってやってみる。

  • スクリプト記述先のidは適当に変数使ってインクリメントして作る。超ゴリ押し。
  • 引数が複数回呼び出しに対応していないので、同じく上の変数使う。超ゴリ赤木。具体的には以下。
    • document.write上書きするときのファンクションの引数msgのとこ
    • スクリプトを書き込むidの指定のとこ
      • サイズ等指定した「nico_player」はclass属性とし、新しく「nico + 変数」をid属性にする

[ .html.erb ]

...
<% ed_mov = 1 %>
...
...(eachメソッドで以下繰り返し)...
<div class="nico_player" id="nico<%= ed_mov %>">
</div>
<p><script type="text/javascript">
    $(function(){
        document._write = document.write;
        document.write = function(msg_<%= ed_mov %>) {
            // id名niconumに表示させる
            $("#nico<%= ed_mov %>").html(msg_<%= ed_mov %>);
            //document.writeを元に戻す
            document.write = document._write;
        }
        var src = "http://ext.nicovideo.jp/thumb_watch/<%= $1 %>";
        var dst = $("<scr"+"ipt>");  //タグと間違われないようにsplit
        dst.attr("type", "text/javascript");
        dst.attr("src", src);
        //追加
        $("body").append(dst);
    });
</script></p>

複数表示はできたものの。
リロードする度に順番が変わったり変わったりラジバンダリ。

多分document.writeの実行順序がアレでアレな影響なんだろうな。。。


このへん調べて見たらdocument.write死ねってブログたくさんありますね



つづく。masterkei.hatenablog.com



TODO:
フォームの例外処理エラーがおかしい
トップからtitle/showへの遷移、2回目以降がなぜかおかしな位置(ページ中段)に遷移するので修正
detailページのレイアウト直すのとdetail -> title/showの動線を置く
動画URLもっと楽に入れたい

silent sirenはかわいいしかわいいからもうなんだっていいかわいければいい

今年入ってからのサイサイの卑怯ドラムへの邁進っぷりが半端ない。
まぁそうだよね。

www.youtube.com


www.youtube.com


イントロのギターリフとかデジャブ感半端ないな。

なんだろう、こういうの求めてないのになぁ。

もっと違う方向の方がよかったんだけどなぁ。


こういう、軽音部の幹部とすごい仲良くしてて、自分達では絶対に客呼ばないしリハも時間通り来ないけど
ちやほやされてるザ・ギャルバンって感じのほうがよかったのに。



www.youtube.com




※卑怯ドラムについてはこちらbasement-times.com

力技でyoutube動画だけじゃなくてニコニコ動画もエンベッドさせてみる

テストデータをいろいろ入れてみていると、youtubeに情報が存在しない場合が多々あり。

そしてそんなときに限ってニコニコ動画ではあったりして。

ニコニコ動画も貼り付けたーい!!


だがしかし。absg.hatenablog.com
ニコ動はURLだけでなくJavascript埋め込まないとダメっぽい空気。

うーんうーんと悩んでみた結果、
「動画情報のレコードにニコ動外部プレイヤーのURLまるっと格納すればいいんじゃね?」という結論に至る。

なので、 anime_detail.ed(またはop)_movie のレコードのタイプを、

の2通りが入ってくると想定して場合分け表示すればいいのではなかろうか。

これをマッチングさせて処理を挟むことにする。

まるっと外部プレイヤーURLを格納して呼び出す

ためしに表示部分を正規表現で条件分岐させてみる。
以下、調べたとことか引っかかったところ。注意すべし。

  • パターンマッチングの基本は「正規表現 =~ 文字列」
    • 正規表現は "/hoge/"とスラッシュで囲む。
    • "^"で行頭からのマッチングパターンにできる
  • 複数条件分岐の場合は、「else if」じゃない!「elsif」です(参照) エルスィフ。
  • ニコ動の場合はhtmlタグを出力したいので、"<%== %>"と=を二つ重ねてエスケープしないで出力する
    • 単純に"<%= %>"で囲むとエスケープ処理されてしまい文字列が出力されてしまう
- <div class="youtube-container">
-   <iframe id="player" type="text/html" width="640" height="390"
-           src="<%= anime_detail.ed_movie %>"
-           frameborder="0"></iframe>
- </div>

+ <% if /^<script/ =~ anime_detail.ed_movie %>     //ニコ動の場合
+     <%== anime_detail.ed_movie %>     //エスケープせずに出力
+ <% elsif /www.youtube.com/ =~ anime_detail.ed_movie %>     //youtubeの場合はこれまでと同じ
+     <div class="youtube-container">
+       <iframe id="player" type="text/html" width="640" height="390"
+               src="<%= anime_detail.ed_movie %>"
+               frameborder="0"></iframe>
+     </div>
+ <% end %>

やってみたらできました。わーい。いいぞいいぞー。

と、思ったら。

テストで別の位置に直貼りしたニコ動urlがあったから動いてたぽい。ちくしょう。
ページ直打ちだったら表示されるけど、別ページからの遷移だと表示されず。
scriptタグは記述されてるけど、その後に追記されるはずのエンベッドが書かれない。

scriptタグはあるけど動いてないぽい原因はdocument.writeだそうです

なんだかnoscript以降がバニシュしてしまうもよう。
www.htmq.com
バニシュするのが通常のご様子。あらはずかしい。


mementoo.info

ニコニコ動画の外部プレイヤーはページのはじめの読み込みのときにしか表示されず、javascriptで読み込みの後から追加で表示させようと思ってもうまくいきません。これは実際に中身を見てみればわかることですが、ソース内で「document.write」を使用して表示させているからです。

だそうです。くぅー。

こうなると、動画URLは以下の2通りで考えてもよさそう

というわけでこのサイトを参考に、jQueryを使って要素内に直接書き出し。

<% if /^<script/ =~ anime_detail.ed_movie %>
    <div id="nico_player">
    </div>
    <p><script type="text/javascript">
       $(function(){
           document._write = document.write;
           document.write = function(msg) {
               // id名nico_playerに表示させる
               $("#nico_player").html(msg);
               //document.writeを元に戻す
               document.write = document._write;
           }
           var id = "sm00000000";
           var src = "http://ext.nicovideo.jp/thumb_watch/" + id;
           var dst = $("<scr"+"ipt>");  //タグと間違われないようにsplit
           dst.attr("type", "text/javascript");
           dst.attr("src", src);
           //追加
           $("body").append(dst);
       });
    </script></p>
<% elsif /www.youtube.com/ =~ anime_detail.ed_movie %>
    <div class="youtube-container">
       <iframe id="player" type="text/html" width="640" height="390"
                 src="<%= anime_detail.ed_movie %>"
                 frameborder="0"></iframe>
    </div>
<% end %>

とりあえずこれで画像表示できるようになりマスタング

パターンマッチングをもう一度整理

ただこのままだと条件分岐おかしいし手打ちで動画表示させてるので、anime_detail.ed(またはop)_movie に格納するURLのパターンをもう一度整理。
URLはわざわざ外部貼り付けURLとか出さずにアドレスバーから直接コピペすることができるようになって楽かも。

[anime_detail.ed(またはop)_movieに格納するURL]

[パターンマッチング]

[引用パラメータ]

  • youtube型:hogehoge(v=以降部分)
  • niconico型:hogehoge(watch/以降部分)


マッチング場所と引用パラメータ別々にする必要なくない?と思うのでやりなおして。

[ マッチング&引用パラメータ ]

  • youtube型:?v=でマッチさせて、以降のid部分を抽出
  • niconico型:/watch/でマッチさせて、以降のid部分を抽出

これに合わせて条件分岐とniconico型の引用パラメータ、youtube型のsrcパラメータなどなどを修正。

まとめ

最終的に作成した、サイトURLからニコニコ動画 or youtube動画をエンベッド埋め込みする方法。

[anime_detail.op_movieに格納するURL]

[ .html.erb ] ※cssは省略

<% @anime_details.each do |anime_detail| %>
    <% if anime_detail.op_artist? %>
        <br><p>artist:<span class="h3"> <%= anime_detail.op_artist %></span></p>
        <p>title:<span class="h3"> <%= anime_detail.op_title %></span></p>
        <% if /\/watch\/([^&]+)/ =~ anime_detail.op_movie  #niconico %>
            <div id="nico_player">
            </div>
            <p><script type="text/javascript">
                $(function(){
                    document._write = document.write;
                    document.write = function(msg) {
                        // id名nico_playerに表示させる
                        $("#nico_player").html(msg);
                        //document.writeを元に戻す
                        document.write = document._write;
                    }
                    var src = "http://ext.nicovideo.jp/thumb_watch/<%= $1 %>";
                    var dst = $("<scr"+"ipt>");  //タグと間違われないようにsplit
                    dst.attr("type", "text/javascript");
                    dst.attr("src", src);
                    //追加
                    $("body").append(dst);
                });
            </script></p>
        <% elsif /\?v=([^&]+)/ =~ anime_detail.op_movie  #youtube %>
            <div class="youtube-container">
                <iframe id="player" type="text/html" width="640" height="390" src="https://www.youtube.com/embed/<%= $1 %>" frameborder="0"></iframe>
            </div>
        <% end %>
    <% end %>
<% end %>

スクリプト部分は外部ファイルで置いた方が収まりがいいのだろうけど、とりあえずはこれで。


あとはURLをどうやって楽にテーブルに格納するかだなぁ。ぬーん。


TODO:

  • フォームの例外処理エラーがおかしい
  • トップからtitle/showへの遷移、2回目以降がなぜかおかしな位置(ページ中段)に遷移するので修正
  • detailページのレイアウト直すのとdetail -> title/showの動線を置く
  • 動画URLもっと楽に入れたい

条件分岐を入れて空レコードの場合は表示させないようにする

OPとEDを入れていくと、たまに「4話だけ特殊OP」とか「11話だけ特殊ED」とか出てくる。

その場合はop_title / ed_title(presence:trueバリデーションかけてる)に「-」と入力して後は空にしてみる。

が、すでに枠をiframeでとっちゃってるので、空白のエリアができてしまった。

というわけで「レコードが存在する場合だけ記述する」ように "if anime_detail.op_artist?" で囲む。

-            <br><p>artist:<span class="h3"> <%= anime_detail.op_artist %></span></p>
-            <p>title:<span class="h3"> <%= anime_detail.op_title %></span></p>
-            <div class="youtube-container">
-              <iframe id="player" type="text/html" width="640" height="390"
-                      src="<%= anime_detail.op_movie %>"
-                      frameborder="0"></iframe>
-            </div>
-        <% end %>

+            <% if anime_detail.op_artist? %>
+                <br><p>artist:<span class="h3"> <%= anime_detail.op_artist %></span></p>
+                <p>title:<span class="h3"> <%= anime_detail.op_title %></span></p>
+                <div class="youtube-container">
+                  <iframe id="player" type="text/html" width="640" height="390"
+                          src="<%= anime_detail.op_movie %>"
+                          frameborder="0"></iframe>
+                </div>
+            <% end %>
+      <% end %>

これだとartist書いちゃうと表示されるのがちょっと弱いので考える必要はあるけど、とりあえず。
久しぶりにrailsの方をいじったので復習も兼ねて。

navbarは冤罪、真犯人はrow → だと思ったらdevだった、死にたい

なぜか一部のページで横幅がおかしい件、要素の検証で辿っていったところ、
どうやらナビバーが悪さをしている可能性。
条件分岐でhomeやらtitleやらにターゲットを変えてたけどここなのか?


と思ったら全然違った。htmlの要素を一つずつ削って確認したら、以下の「row」要素があると横スクロール出てくることが判明。

<dev class="container ptb">
  <div class="row">
    <h2 class="centered mb">スタッフ情報</h2>
    <% @anime_details.each do |anime_detail| %>
        <p class="centered mb"><%= anime_detail.profile %></p>
    <% end %>
  </div><!-- /row -->
</dev><!-- /.container -->

rowの仕様がわからんよう

rowってなんじゃらほいと調べてみると、以下の情報あり。
Twitter Bootstrapのcontainer、row、col(span)の正しい使い方 -- ぺけみさお

ポイントは、コンテンツはcontainerクラスかcolクラスの内部に記述するようにすることだ。rowクラスの直下にはコンテンツを書いてはいけない。
というのも、Bootstrapのグリッドシステムは、(1)containerクラスがパディングを確保する。(2)rowクラスがネガティブマージンでそれを打ち消す。この組み合わせでコンテンツの始点が整列するように作られている。そのため、rowクラスの直下に何かを書くと、少し左にずれてしまうのだ。

多分これが原因ぽい。
けど、他のところでも同じようにrow直下にコンテンツ置いてるんだよなぁ。。。
なんでここだけおかしくなるのだろふか。

よくよく見てみると、直で書かずにpタグで囲んだり、containerを更に上からタグで囲んでたりしてたからたまたま影響出てなかったもよう。タグってこわい。

(containerの上から更に囲んでた例)

<div id="g">
  <div class="container">
    <div class="row centered">
      <h2>オープニングテーマ</h2>
      ....

(pタグで囲んでた例)

<div class="container">
  <div class="row centered">
    <p><strong>アニメタイトル:</strong></p>
    ....

とりあえず現状問題の場所をpタグで囲んでみた。ついでにクラスが被ってるとこも省略。

<dev class="container ptb">
  <div class="row centered">
    <p><h2>スタッフ情報</h2></p>
    <% @anime_details.each do |anime_detail| %>
        <p class="mb"><%= anime_detail.profile %></p>
    <% end %>
  </div><!-- /row -->
</dev><!-- /.container -->


実はこれを書いてた時点ですでに問題点は明確であった。。。

逆にpタグでおかしくなってた

直らないんだけど!もう!意固地か!!

いろいろやったけどもrowがあると横にちょっとはみ出る。どうあがいても絶望。


htmlを見直すと、最初のcontainerクラスがきちんと入れ子になっていない。
どうやら

タグでパーシャルを囲んでいたので、パーシャルの中身のcontainerがちゃんと動いてなかったぽい。

<p>
  <!-- details -->
  <%= render partial: 'anime_details/staffandcast', locals: { anime_title: @anime_title, anime_details: @anime_details } %>
</p>

とやると、パーシャルの中身のいろんなとこがpタグに囲まれてた。カオス。
[ _staffandcast.html.erb ]

<dev class="container ptb">
  <div class="row centered">
    <div class="col-md-8 col-md-offset-2">
      <p><h2>スタッフ情報</h2></p>
      <% @anime_details.each do |anime_detail| %>
          <p class="mb"><%= anime_detail.profile %></p>
      <% end %>
    </div>
  </div><!-- /row -->
</dev><!-- /.container -->

[ 作成されたhtml ]

<p>
  <!-- details -->
  <dev class="container ptb">
  </dev>
</p>
<div class="row centered">
  <div class="col-md-8 col-md-offset-2">
    <p></p><h2>スタッフ情報</h2><p></p>
    <p class="mb"> ※呼び出されたスタッフ情報 </p>
  </div>
</div>

pタグ外したらちゃんとした入れ子になりました。

widthが901pxから931pxに増えてる

次はwidthの設定がおかしくなっているところを確認。

<dev class="container">   ← width: 901px
  <div class="row centered"> ← width: 931px
    <div class="col-md-8 col-md-offset-2">
      <h2>スタッフ情報</h2>
      <p class="mb"> ※呼び出されたスタッフ情報 </p>
    </div>
  </div><!-- /row -->
</dev>

上のコードをプレビューで見たらdevって黒文字になっててtypoしてることに気づいてワロタ。
ってかここまでこの記事に書き込んだコード全部devになっとるやんけ。
はてな記法すごい。スペルミスもわかっちゃう。

divにしたら全部解決しました。

あーまた死にたくなるやつやこれーあー


あー!

http://g.s9t.jp/data/a34013b247ad03480cabf8526d9b47ec.png

Rubymineのエラー表示の色が悪いせいだ!
と責任転嫁してみる。



とりあえずグリッドの中にクラスの無い

タグ入れるとカオスになるので他の場所も外しとこう。



にしても修正にほんと時間かかってしまった。もっとスマートに検証作業する方法はないものか。

今度レイアウト崩れあったらの検索から始めようとおもいました。






TODO:

  • フォームの例外処理エラーとか横幅とかいろいろおかしい件
  • トップからtitle/showへの遷移、2回目以降がなぜかおかしな位置(ページ中段)に遷移するので修正