アナログCPU:5108843109

ゲームと音楽とプログラミング(酒と女とロックンロールのノリで)

('ω') < イザユケエンジニャー

iframeのデメリットを無理矢理消化した実装(JS+PHP+Smarty版)

iframeの二大デメリット
「URLが切り替わらない(常にフレームの外側ページのもの)」
「内側ページのURLを直接叩くとフレームが出ない」
を解決すべく

とりあえず↑を検討した後、やっぱ微妙だなと思って
PHPSmartyの力も借りて実装したバージョン。

仕組みはそれなりに変わっていますが
HTMLとJSのコードは変わってないので(減っただけなので)
そのへんは省略します。上記の記事も併せて参考にしてください。

まずは完成サンプル

構成としては、JS版で作ったときと同じく
フレームページ(以下、親)と
iframe内側のコンテンツページ(以下、子)を作ることになりますが、
PHPSmartyも利用するので

  • 親テンプレート(Smarty, HTML, JS)
  • 親コントローラ(PHP, Smarty
  • 子ページ(HTML, JS)

を用意します。

親テンプレート(frame_parent.html)

ここはJS版とほぼ同じ。
Smartyテンプレートなので、iframeのsrc部分のみ「child_uri」で置換可能にしています。

JS部分はURLの書き換え処理のみ。(JS版の記事を参照)

<HTML+Smarty

<!-- header -->
<div style="height: 100px; background-color: #CCC">
  <div>
    <span><a href="frame_parent.html">親の再読み込み</a></span>
    <span><a href="frame_child_1.html" target="content_iframe">子1</a></span>
    <span><a href="frame_child_2.html" target="content_iframe">子2</a></span>
  </div>
</div>

<!-- iframe -->
<iframe id="content_iframe" name="content_iframe" src="{$child_uri}" style="width: 100%; height: calc(100% - 100px); border: 0;"></iframe>

<JS>

$('#content_iframe').load(function(){
    var contents = $("#content_iframe").contents();
    var url = contents[0].URL;
    var domain = "//" + contents[0].domain;
    var url_child = url.slice(url.indexOf(domain) + domain.length);
    history.replaceState("", "", url_child);
});
親コントローラ(frame.php

使用しているフレームワークなどによっていろいろと書き換える必要はありますが
簡単に、最低限必要な部分を記載。
PHP

<?
// $param_child_uriという変数に、
// 子から渡された子自身のパス(例:/frame_child_1.html)が入っているものとします。
// そのへんの処理は適宜…

// 子
// セットされている場合はそれを採用、
// セットされていない場合や空文字の場合はデフォルトページを指定
$child_uri = isset($param_child_uri) ? $param_child_uri : "";
$child_uri = ($child_uri == "") ? "frame_child_1.html" : $child_uri;

// テンプレートに表示対象の子ページパスをセットして呼び出し
$this->template->assign("child_uri" , $child_uri);
$this->template->display("smarty/template/frame_parent.html");
子ページ

HTML部分はなんでもいいので省略。
JSも、リダイレクト先が親のHTMLから親のPHPに変わっただけ。
もちろん子がPHPSmarty環境であってもOKです。とにかく↓のJSがあればOK。

<JS>

if(window == window.parent) {
    var childUri = location.pathname + location.search;
    location.href = "frame.php?child=" + childUri;
}

解説?

HTMLやJSについてはJS版の記事を参照してください。
JS版と異なるのは
「子のURLを直接指定されたときに、その子ページに親のフレームをくっつけて表示する」方法を
PHPSmartyを用いてちょっとキレイにした点のみです。

JS版では「指定された子を表示→親にリダイレクト→親のiframe内書き換え」となかなかアレな感じでしたが
こちらの方法では「指定された子を表示→親にリダイレクト(ただしiframeの中身は指定された子)」なので
一応ワンステップ減っています。