freoでツイッターライク?なお手軽投稿

quick-post.jpg

ツイッターライクというかてがろぐライクというか、ログインした状態であれば管理画面からでなくサイトの表から投稿できる用にするカスタマイズTIPSです。このカスタマイズはすでに「kirsche*」さんで解説されているものを元にしています(jQuery部分はほぼそのままです)。ここの解説ではよくわからないという場合はそちらをご参考にどうぞ。また、以下のコードは自分の覚書も兼ねているためHTML5・Smarty3の書き方になっています。適宜読み替えてください。

最終目標

上図のように、ログインした状態だとエントリー一覧の上に簡素な投稿フォームが表示されそこからエントリーを登録できるようにする。

header.html

<script src="{$freo.core.http_url}{$smarty.const.FREO_JS_DIR}common.js" defer></script>

の上あたりに

<!--{if $smarty.request.freo.mode == 'entry' && $freo.user.authority == 'root'}-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.form/4.3.0/jquery.form.min.js" integrity="sha384-qlmct0AOBiA2VPZkMY3+2WqkHtIQ9lSdAsAn5RUJD/3vA5MKDgSGcdmIv4ycVxyn" crossorigin="anonymous" defer></script>
<script src="{$freo.core.http_url}{$smarty.const.FREO_JS_DIR}plugins/quick-post.js" defer></script>
<!--{/if}-->

を挿入し、管理者としてログインした状態でエントリー一覧を表示したときに今回のカスタマイズで必要となるスクリプト(後述)を読み込みます。freoでサイト全体を管理するなどの方法でサイトトップとエントリー一覧を分けていない場合は$smarty.request.freo.mode == 'entry'の「entry」を「default」としてください。

entry/default.html または default/default.html

エントリー一覧を表示するループの開始

<!--{foreach from=$entries nofilter item='entry'}-->

の前に投稿フォーム用の記述を挿入します。

<!--{if $freo.user.authority == 'root'}-->
<form action="{$freo.core.http_file}/admin/entry_form{if $freo.query.id}?id={$freo.query.id}{/if}" method="post" enctype="multipart/form-data" id="quick-post">
	<fieldset>
		<legend>エントリー登録フォーム</legend>
		<input type="hidden" name="freo[token]" value="{$token}">
		<input type="hidden" name="entry[id]" value="{$input.entry.id}">
		<dl>
			<dt>タイトル</dt>
			<dd><input type="text" name="entry[title]" size="50" value="{$input.entry.title}" id="set-title"></dd>
			<dt>本文</dt>
			<dd><textarea name="entry[text]" cols="30" rows="5" id="tiny_mce">{$input.entry.text}</textarea></dd>
		</dl>
		<p><input type="submit" value="登録する" id="set-form"></p>
		<!--{if $freo.config.entry.tag}-->
		<input type="hidden" name="entry[tag]" value="つぶやき">
		<!--{/if}-->
		<input type="hidden" name="entry[datetime][year]" id="datetime_year" value="{$input.entry.datetime|date_format:'%Y'}">
		<input type="hidden" name="entry[datetime][month]" id="datetime_month" value="{$input.entry.datetime|date_format:'%m'}">
		<input type="hidden" name="entry[datetime][day]" id="datetime_day" value="{$input.entry.datetime|date_format:'%d'}">
		<input type="hidden" name="entry[datetime][hour]" id="datetime_hour" value="{$input.entry.datetime|date_format:'%H'}">
		<input type="hidden" name="entry[datetime][minute]" id="datetime_minute" value="{$input.entry.datetime|date_format:'%M'}">
		<input type="hidden" name="entry[datetime][second]" id="datetime_second" value="{$input.entry.datetime|date_format:'%S'}">
		<input type="hidden" name="entry[status]" value="publish">
		<input type="hidden" name="entry[display]" value="publish">
		<input type="hidden" name="entry[comment]" value="closed">
		<input type="hidden" name="entry[trackback]" value="closed">
		<!--{if $freo.config.entry.restriction}-->
		<input type="hidden" name="entry[restriction]" value="">
		<input type="hidden" name="entry[password]" value="">
		<!--{/if}-->
	</fieldset>
</form>
<!--{/if}-->

タイトルと本文以外の入力必須項目は<input type="hidden" ~略~>で送信しています。上記のコードでは

  • エントリーの状態:公開
  • エントリーの表示:初期画面に表示する
  • コメントの受付:受け付けない
  • トラックバックの受付:受け付けない
  • エントリーの公開終了:指定しない
  • 閲覧制限(設定管理で閲覧制限を利用するに設定したときのみ):制限なし

となっています。また、このフォームから投稿したものには「つぶやき」というタグをつけるようにしています。

jQuery

header.htmlで読み込む2つのスクリプトは以下の用途に使います。

  • jQuery Form Plugin
    • CDN利用
    • 投稿後のページ遷移をコントロールする(そのままだと管理画面へ飛んでしまいます)
  • quick-post.js
    • 必須項目である投稿日時を投稿ボタンを押した時に自動挿入
    • タイトル未記入の場合に代替えテキストを自動挿入
    • jQuery Form Plugin用記述

quick-post.js

以下をquick-post.jsという名前でjs/plugins/に置きます。

$(document).ready(function () {
$('#set-form').click(function () {
//現在日時設定
	var now = new Date(),
	year   = now.getFullYear(),
	month  = now.getMonth() + 1,
	day    = now.getDate(),
	hour   = now.getHours(),
	minute = now.getMinutes(),
	second = now.getSeconds();
	if (month  < 10) { month  = '0' + month;  }
	if (day    < 10) { day    = '0' + day;    }
	if (hour   < 10) { hour   = '0' + hour;   }
	if (minute < 10) { minute = '0' + minute; }
	if (second < 10) { second = '0' + second; }
	$('#datetime_year').val(year);
	$('#datetime_month').val(month);
	$('#datetime_day').val(day);
	$('#datetime_hour').val(hour);
	$('#datetime_minute').val(minute);
	$('#datetime_second').val(second);
//タイトルの入力
	if ($('#set-title').val() === '') {
		$('#set-title').val('NO TITLE');
	}
});
});
//jQuery Form Plugin
$('#quick-post').ajaxForm();
var url = $(location).attr('href')
//オプション値あり
var options = {
	resetForm: true, // 成功時にformをクリア
	success : function () {
		window.location.href = url;
	}
};
$('#quick-post').ajaxForm(options);

上記ではタイトル未記入で投稿ボタンを押すと「NO TITLE」という文字列が代入されます。

サンプル・注意点

成功すればこのようなことができます(カーソル込みキャプチャができていないのでわかりにくいですが非ログイン状態→ログインしてリロード、タイトル未記入で投稿ボタンを押したタイミングで「NO TITLE」が代入され投稿されています)。

このカスタマイズで設置したフォームはただのテキストエリアなのでプレーンな文字列しか投稿できません(HTMLを手打ちすれば反映されます)。Tiny MCEを適用すれば…?と思ったのですがそうすると入力した本文が消えてしまいました😥

参考