Movable Type検索結果画面のMTIncludeタグでファイルを読み込む方法
Movable Type検索結果画面のMTIncludeタグでファイルを読み込む方法を紹介します。
1.はじめに
MTで再構築するファイルの拡張子を".php"にして、そのページの中で頻繁に更新される部分を、
<?php include('foo.html'); ?>
で読み込むことで、ページ全体の再構築不要で情報を更新することができます。
ただ、検索結果ページはPerlのCGIで動作するため、PHPの方法を利用することができません。
ということで、検索結果画面のMTIncludeタグでファイルを読み込む方法を紹介します。
2.検索結果画面のMTIncludeタグでファイルを読み込む
1項のfoo.phpのパスを、仮に「/var/www/html/foo.html」とします。
このファイルを検索結果画面のMTIncludeタグで読み込むには、下記の手順が必要です。
まず、mt-config.cgiに
AllowFileInclude 1
を設定します(注:4項参照)。
次に、ファイル読み込み部分を次のようにします。
<$mt:Include file="/var/www/html/foo.html"$>
これで、検索結果画面でも情報を更新する部品を利用することができます。
3.サイトパスにテンプレートタグを使用する
2項ではファイルパスに「/var/www/html」を直接記述しましたが、テンプレートタグでサイトパスを取得するには次のように記述します。
<mt:Setvarblock name="foo"><$mt:SitePath$>/foo.html</mt:setvarblock>
<$mt:Include file="$foo"$>
1行目のMTSetVarBlockタグで、サイトパスとファイル名を文字列結合したものを、変数fooに設定します。
2行目のMTIncludeタグで、fileモディファイアに「$foo」と書くことで、変数fooの内容が展開され、
<$mt:Include file="/var/www/html/foo.html"$>
と同じ結果となります。
4.注意事項
AllowFileIncludeはセキュリティ対策として、デフォルトで無効(=0)となっています。
理由は「テンプレート編集の権限だけをもつユーザーが、ファイルシステム上の任意のファイルを読み出せるのは問題であるため」のようです。
このカスタマイズを利用する場合は、上記のセキュリティに十分配慮してください。
ansibleのcopyモジュールでディレクトリを生成する方法
ansibleのcopyモジュールでディレクトリを生成する方法を紹介します。
1.問題点
ansibleのcopyモジュールでファイルをコピーしたいのですが、コピー先のディレクトリがなく、エラーになります。
試したのは下記の2種類です。
test.yml
---
- name: テスト
copy:
src: /tmp/hoge.txt
dest: /tmp/aaa/bbb/hoge.txt2
remote_src: yes
または
---
- name: テスト
copy:
src: /tmp/hoge.txt
dest: /tmp/aaa/bbb
remote_src: yes
これを実行すると、下記のように"Destination directory /tmp/aaa/bbb does not exist"というエラーになります。
$ ansible-playbook -i inventory test.yml
PLAY [act] ***************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************
ok: [server]
TASK [test : test.ymlをインクルード] *************************************************************************************************************
included: /var/tmp/ansible/roles/test/tasks/test.yml for server
TASK [test : テスト] *****************************************************************************************************************************
fatal: [server]: FAILED! => {"changed": false, "msg": "Destination directory /tmp/aaa/bbb does not exist"}
TASK [test : エラーが発生したため停止] ***********************************************************************************************************
fatal: [server]: FAILED! => {"changed": false, "msg": "ロール実行中にエラー発生"}
PLAY RECAP ***************************************************************************************************************************************
server : ok=2 changed=0 unreachable=0 failed=1 skipped=0 rescued=1 ignored=0
ということで、ansibleのcopyモジュールでディレクトリを生成する方法を紹介します。
2.ansibleのcopyモジュールでディレクトリを生成する
ansibleのcopyモジュールでディレクトリを生成するには、destオプションを"/"で終わらせます。
---
- name: テスト
copy:
src: /tmp/hoge.txt
dest: /tmp/aaa/bbb/
remote_src: yes
このansibleを実行すると正常にディレクトリを生成してくれます。
$ ansible-playbook -i inventory test.yml
PLAY [act] ***************************************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************************
ok: [server]
TASK [test : test.ymlをインクルード] *************************************************************************************************************
included: /var/tmp/ansible/roles/test/tasks/test.yml for server
TASK [test : テスト] *****************************************************************************************************************************
changed: [server]
PLAY RECAP ***************************************************************************************************************************************
server : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
jQuery+ajaxでモーダルのコンテンツを取得する方法
jQuery+ajaxでモーダルのコンテンツを取得する方法を紹介します。
1.はじめに
モーダル表示の使い方は、たとえば商品ページで、その商品の詳細画像を表示するといったことが多いと思います。
その場合、HTMLページ内にすべてのモーダル用コンテンツを配置して、そこから取得・表示する実装になると思います。
ですが、ページ内にモーダル用のコンテンツをすべて記述すると、場合によってはページのサイズが大きくなり、ロード時間に影響します。
また商品ページではなく、たとえばモーダルをブログの記事ページとして表示させたい場合、上記の方法では大量のコンテンツをページ内に書き出す必要がありますが、現実的ではありません。
ということで、本記事ではモーダル用コンテンツをjQuery+ajaxで取得し、さらの前後リンクのコンテンツもjQuery+ajaxで取得する方法を紹介します。
2.サンプル
下記のリンクをクリックするとサンプルページに遷移します。
テキスト途中にある「ひらく」をクリックするとモーダルが表示され、前後リンクをクリックするとコンテンツをajaxで読み出して表示を切り替えます。
「あああ」のテキストを大量に挿入しているのは、モーダル表示後にスクロールしてもモーダルが移動しないことを示すためのものです。
サンプルはモーダルコンテンツの取得と前後リンクだけに着目しているので、CSSは最小限です。またアニメーションや「閉じる」ボタンの実装もありません。
以下、ソースとjQueryの解説です。
3.ソース
<meta charset="UTF-8" />
<style>
#modal {
display: block;
position: fixed;
opacity: 1;
z-index: 11000;
left: 45%;
margin-left: -77px;
top: 100px;
}
#modal_content {
border: 1px solid #000000;
padding: 30px;
}
#left {
position: absolute;
top: 100px;
left: -170px;
}
#right {
position: absolute;
top: 100px;
right: -170px;
}
</style>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
$(function(){
$(".open_modal").on('click', function(){
var url = $(this).attr('data-url');
$.ajax({
type: "POST",
url: url,
dataType: "html"
}).done(function(data) {
let main = $($.parseHTML(data)).filter('#main').html();
let prev = $($.parseHTML(data)).filter('#previous').text();
let next = $($.parseHTML(data)).filter('#next').text();
$('#modal_content').html(main);
if ( prev ) {
$('#left').attr('data-url', prev);
$('#left').css('display', 'block');
} else {
$('#left').css('display', 'none');
}
if ( next ) {
$('#right').attr('data-url', next);
$('#right').css('display', 'block');
} else {
$('#right').css('display', 'none');
}
$('#modal').css('display', 'block');
});
});
});
</script>
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<div class="open_modal" data-url="https://www.koikikukan.com/samples/20240313/test1.html">ひらく</div>
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<p>あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<br />あああ<b
r />あああ</p>
<div id="modal" style="display:none;">
<div class="open_modal" id="left" data-url=""><</div>
<div class="open_modal" id="right" data-url="">></div>
<div id="modal_content"></div>
</div>
4.解説
「ひらく」のclass属性"open_modal"をclickイベントで待ち合わせます。
<div class="open_modal" data-url="https://www.koikikukan.com/samples/20240313/test1.html">ひらく</div>
:
<script>
$(function(){
$(".open_modal").on('click', function(){
クリックされると要素内のdata-url属性値に設定したURLをattrメソッドで取得します。
var url = $(this).attr('data-url');
data-urlの値は下記のdata()でも取得できますが、この方法ではDOMのキャッシュが誤って取得されてしまうため、この記事の執筆時点ではdata()は絶対に使わないでください(この事象で2日ほど悩みました)。
var url = $(this).data('url');
取得したURLでコンテンツをajaxで取得します。
$.ajax({
type: "POST",
url: url,
dataType: "html"
$.ajax以外に$getでも取得可能です。
なお非同期による取得ではキャッシュが取得されてしまうこともあるので、POSTメソッドを使用する、cacheオプションをfalseにする等の対処を行ってください。
取得したコンテンツをそのままHTMLに展開できないケースを考慮して、部分取得を行います。
ここではコンテンツ部分と前後リンク部分をparseHTML()とfilter()を使います。この方法がベストプラクティスと思われます。
}).done(function(data) {
let main = $($.parseHTML(data)).filter('#main').html();
let prev = $($.parseHTML(data)).filter('#previous').text();
let next = $($.parseHTML(data)).filter('#next').text();
取得したHTMLをモーダルに反映します。
$('#modal_content').html(main);
URLを前後リンクに反映させます。このときも前述と同様の理由でdata()ではなく、attr()を使用してください。リンクがない場合は非表示にしています。
if ( prev ) {
$('#left').attr('data-url', prev);
$('#left').css('display', 'block');
} else {
$('#left').css('display', 'none');
}
if ( next ) {
$('#right').attr('data-url', next);
$('#right').css('display', 'block');
} else {
$('#right').css('display', 'none');
}
すべての設定が終わったらdisplayプロパティを使ってモーダル全体を表示します。
$('#modal').css('display', 'block');