WordPressによるWEBサイト開発

WEBサイト作成

WordPressによるWEBサイト開発1 - MVCモデル的な設計


投稿される情報をユーザー単位に時系列に保存し、「会計システム」「インドネシアの税法」というようなカテゴリ、または「PPN」「WordPress」というようなタグ単位にフィルタして表示できるのがWordpressの最大の強みであり、これらカテゴリやタグなどの投稿記事の切り口(分類)をタクソノミーと呼んでいます。

情報系(参照系)と業務系(更新系)という分類

個人のブログから企業サイトまで「簡単に早く見栄え良く」WEBサイトを立ち上げるためにWordPressは有効であり、「で、一体どこまで出来るの?」という話になった場合、一般的にはWEB開発プラットフォームは「情報系(参照系)向き、業務系(更新系)不向き」とよく言われます。

確かにフォームへの入力値に基づいて頻繁にSQLでマスタを参照したり、計算ロジックが実行され出力結果を保管し、分析帳票を作成する業務システムのプラットフォームとしてWordPressは向きません。

  • 更新系システムの特徴
    1. 取引データが複数機能に渡って継続的に利用される。
    2. マスタとそれに伴う管理画面が多い。
    3. 必然的にデータ更新のSQL文が複雑になる。
  • 参照系システムの特徴
    1. 取引データは基本は参照に利用される。
    2. マスタの数が少なくマスタ同士の連携も少ない。
    3. データ更新のSQL文がシンプル。

WordPressは上記の更新系システムの特徴はWordPressには不向きであり、参照系システムの特徴に向いていると言えますが、Salesforceなどのクラウドベースの開発プラットフォーム全般は「CRM向き、ERP不向き」と言えます。

CMSとしてのWordPressに向いていないものを無理やり適用するのではなく「出来ること、適していること」に特化させて、不得意な分野はそれに適したツール(言語)で分業開発するが、WEBサイト全体としての「一体感」はキープしたい、というのが現実的な方針だと思います。

MVCモデルではないWordPess

フロントエンド開発を「ユーザーに見える部分の開発」、バックエンド開発を「ユーザーに見えない裏方処理の開発」と定義すれば、WEBサイト全体はフロントエンド(View)で入力されたデータが、バックエンドで処理(Controller)されて、データベースに格納(Model)されるという動きをします。

  1. フロントエンドHTML+CSS+Javascript(jQuery)で対応可能な範囲のWordPressテーマのテンプレートファイル開発。
  2. バックエンドHTMLフォーム(フロントエンド)からの入力情報に基づいて機能するformタグのaction属性で指定されるPHPプログラムの開発やWordPressプラグイン開発(functions.php)など。

WordPressはテーマ(View)とコアシステム&拡張機能プラグイン(Controller)とMySQLが独立して機能するという意味で、MVCモデルのような動きをすると言えますが、MVCフレームワークではないのでWordPressをインストールしたディレクトリやテーマフォルダの中に、viewとかcontrollerとかmodelというフォルダは存在しません。

MVC開発環境に慣れた開発者にとっては、ここがWordPressの気持ち悪いところなのかもしれませんが、WordPressユーザーの大多数はブログユーザーなので、コアシステム(WordPress本体)をテーマで着せ替えるというWordPressの概念が重要なのであって、ディレクトリ構造は問題になりません。

フロントエンドからバックエンドの呼び出し方(View)

このフロントエンドからバックエンドの呼び出し方にはいくつか方法があります。

PHPコードを直接埋め込む

投稿やページからロジックを動かす仕組みが必要になりますが、WordPressにはタグ付きでPHPコードを埋め込めるプラグインExec-PHPがあります。

ショートコードでfunctions.phpのユーザー関数を呼び出す

PHPコードはfunctions.phpに書いて、WordPressの標準機能であるショートコードで呼び出す方法であり、ショートコードを定義するWordPress関数add_shortcode()の第一引数にショートコードを、第二引数に呼び出す関数をセットします。

(functions.php)

function shortcodeFunc() {
  echo '<table width="580"><tr><td align="left" valign="middle" width="180" class="setsu"><input type="hidden" id="mydate1" name="mydate1" value="" />';

  echo '<table><tr><td><div id="mydatediv1" class="anchor"></div></td><td>';
	echo '<img src="cal.gif" style="cursor:pointer;" alt="Select date" onclick="javascript:show_datedialog(\'datedialog1\',\'mydate1\',\'mydatediv1\');" /><div id="datedialog1" class="datedialog">';

  echo '</div></td></tr></table>';
}
add_shortcode('shortcode1', 'shortcodeFunc');

(テンプレートファイル)

[shortcode1]

JavaScriptやスタイルシートを特定の投稿画面にのみ追加したい場合、Custom JS WidgetとCustom CSS Widgetをfunctions.phpに追加すると、投稿画面からJavaScriptを追加できます。

外部PHPプログラムをfunctions.phpからincludeする。

コードが長い場合は、functions.phpの関数内でPHPプログラムをinclude(またはrequire)し、出力されたHTMLフォームからJavaScriptを呼び出します。

これならフロントエンドはWordPressに任せて、ロジックは従来型のPHPとJavaScriptで開発可能であり、理屈ではWordPressをベースに業務系システムの開発が出来ることになります。

(functions.php)

function shortcodeFunc() {
  include("bc/datedialog-files/datedialog.php");
}
add_shortcode('shortcode2', 'shortcodeFunc');

(テンプレートファイル)

[shortcode2]

Hookによるイベントドリブン(Controller)

functions.phpまたはincludeした外部PHPファイルの関数を呼び出す場合と、PHPファイルをプラグイン化する場合とがあります。

AsprovaのCOMインターフェイス同様、WordPressもプラグインAPIがあり、WordPressの動作をコアシステムに触れずに外から操作できますが、これはコアシステム内のロジックの前後に、do_action(’フック名’,'引数')とapply_filters('フック名','引数')というアクセスポイント(プラグインキー)を設置しているからです(WordPressプラグインの開発)。

  1. フィルターフック一覧(入出力データの加工)
  2. アクションフック一覧(イベントにあわせて実行)

つまりコアシステムのプラグインキーのタイミングでプラグイン関数を実行させたり、コアシステムの関数内で戻り値にフックを引っ掛けてあれば、関数add_action('フック名','プラグイン関数名')や関数add_filter(’フック名','プラグイン関数名')により引数を修正できます。

このプラグインAPIの使い方は主にアクションフックとフィルターフックの2通りあります。

<?php
/*
Plugin Name:おはようSelamat pagi!
Description:おはようをSelamat pagi!に変換
Author:yamazou
*/

function selamat_pagi($content){
 return str_replace('おはよう','Selamat pagi!',$content);
}

add_filter('the_content','selamat_pagi');
?>

add_filter関数でHookとしてthe_contentを指定していますので、「コアシステムがデータベースから取得した投稿コンテンツを画面に出力する前」にselamat_pagi()という関数を実行させます。

何でこんなことが可能かというと、コンテンツを出力する関数the_content()の$content出力部分にapply_filters()がかましてあるからです。

この関数はwp-includes/post-template.phpにあります。

function the_content($more_link_text=null,$stripteaser=false){
   $content=get_the_content($more_link_text=null,$stripteaser=false);
   $content=apply_filters('the_content',$content)
}

ここにapply_filters()がかましてあるのは「the_contentというフィルターで$contentを修正してもOK」という意味であり、もしapply_filtersがなかったら出力前に$contentの修正は出来ません。

apply_filters関数はフィルターフックthe_contentに追加された関数add_filters('the_content','selamat_pagi')を呼び出し実行した上で、戻り値$contentをthe_content関数(テンプレートタグ)に返します。

 

カスタムフィールド追加によるメタデータ指向(Model)

WordPressのデータベース構造(Codex日本語版)

テーブル関連があまりにシンプルで、ER図見た瞬間に業務機能単位のモジュールが処理するトランザクションが伝票番号で連携され、多くのマスタを必要とする業務系(更新系)に不向きであることが明白なのですが、そもそもwp_postsでコンテンツを分類している投稿タイプ(post_type)は以下の5種類です。

  1. 投稿(Post)
  2. ページ(Page)
  3. メディア(attachment)
  4. リビジョン(revision)
  5. ナビゲーション(nav_menu)

すべてのコンテンツを「post_typeカラムで差別化している」いわゆる単一テーブル継承方式です。

クラウド時代に入りマルチテナント、いわゆる単一データベース共通スキーマ方式指向にある現在、テーブル統一化はトレンドなのかもしれませんが、なんでもかんでもwp_postsに保存されてしまうことによる、テーブルの肥大化が心配されます。

wp_posts

新規にカスタム投稿タイプを追加した場合、デフォルトの投稿記事や固定ページ同様に、タイトルと本部まではwp_postsテーブルに格納されます。

  1. ID 投稿ID(保存順に自動採番)
  2. post_author 投稿者のユーザID
  3. post_date 投稿日時
  4. post_date_gmt 投稿日時(GMT)
  5. post_content 本文
  6. post_title タイトル
  7. post_excerpt 抜粋オプション
  8. post_status 投稿ステータス 'publish': 公開済み 'pending': ペンディング 'draft': 草稿 'private': プライベート(非公開) 'static':(2.0.x 以前はページ) 'object': 'attachment': 'inherit': 継承(添付ファイル、改訂履歴・自動保存のとき) 'future': 予約投稿
  9. comment_status コメントステータス 'open': 許可 'closed': 不許可 'registered_only': 登録ユーザのみ
  10. ping_status ピン・ステータス 'open': トラックバック・ピンバックを受け付ける 'closed': 受け付けない
  11. post_password 閲覧パスワード
  12. post_name 投稿スラッグ '{親ID}-revision(-#)' (改訂履歴のとき) '{親ID}-autosave' (自動保存のとき)
  13. to_ping text
  14. pinged ピン通知済み URL
  15. post_modified 更新日時
  16. post_modified_gmt 更新日時(GMT)
  17. post_content_filtered
  18. post_parent 親ID 親ページの投稿ID 添付ファイルが属する投稿ID 改訂履歴・自動保存のベース投稿ID
  19. guid varchar(255)
  20. menu_order ページの表示順
  21. post_type 投稿種別 'post': 投稿 'page': ページ 'attachment': 添付ファイル 'revision': 改訂履歴・自動保存
  22. post_mime_type 添付ファイルのとき MIMEタイプ(image/png など)
  23. comment_count コメント数

wp_postmeta

デフォルトの投稿タイプ(post, page)からはタイトルとコンテンツの2つしか入力できないので、カスタムフィールドで追加情報(メタデータ)として情報を追加できますが、データはメタデータとしてwp_postmetaに格納されます。

wp_postmetaではカスタムフィールドの値がmeta_id(ユニークキー)とpost_id(投稿ID)とmeta_key(名前)をキーに管理されます。

  1. meta_id メタID(一意)(登録順に自動採番)
  2. post_id 投稿ID
  3. meta_key カスタムフィールドのキー名
  4. meta_value カスタムフィールドの値

カスタム投稿タイプの定義方法

デフォルトの投稿タイプにカスタムフィールドを追加するのではなく、全く新規の投稿タイプを作成するにはfunctions.phpにregister_post_type()でフォームを定義し、WordPressコアシステム(root/wp-settings.php)のdo_action('init')のタイミングで以下のプラグイン関数を実行させます。

//カスタム投稿タイプ追加
function new_post_type(){
	//カスタム投稿タイプを作る
	register_post_type(
		'additional-post',
		array(
			'label'=> 'カスタム投稿タイプ',
			'public' => true,
			'hierarchical'=> false,
			'has_archive' => true,
			'supports' => array(
				 'title',
				 'editor',
				 'thumbnail',
				 'excerpt'
			),
			'menu_position' => 5
		)
	);
}
add_action('init', 'new_post_type');

アクションフックinitのタイミング、つまりdo_action('init')がプラグイン関数new_post_typeを呼び出し、「カスタム投稿タイプ」という投稿画面にsupportsにセットした配列の値、タイトル・本文・アイキャッチ画像・抜粋という入力項目が表示されるようにします。

root/wp-settings.php抜粋

do_action( 'init' );
// Check site status
if ( is_multisite() ) {
	if ( true !== ( $file = ms_site_check() ) ) {
		require( $file );
		die();
	}
	unset($file);
}



おすすめ記事一覧

1

よく会計の世界では「利益と減価償却でキャッシュを作る」と言われ、これは企業のキャッシュの源泉が利益と減価償却の二種類あるという意味なのですが、減価償却費はキャッシュの流出のない費用であり、P/L上の当期利益額よりも実際には減価償却費分だけキャッシュは多く残っているという数字遊びをしているだけで、物理的にキャッシュが生み出されるわけではありません。

2

毎月の生産でいくらコストがかかったかを計算する原価計算(実際原価)業務は、インドネシアではシステム化されている事例は少なく、細かく計算すれば時間がかかり、どんぶり勘定だと見たい情報が見られず、コロナ禍の影響で時間に余裕が出来た今は収益改善という観点から原価計算のやり方を見直す絶好の機会です。

3

ジャカルタでは、2019年4月にMRT地下鉄の第1期区間(総延長15.7km)が正式開通しましたが、コロナ禍の中にあった今年6月に、現在の始発駅であるPlaza Indonesia前のBendaran HI駅から、北ジャカルタのKotaまでの6.3km、西ジャカルタのアンチョールの車両基地までの5.2kmの総延長11.5km(11駅)を第2期区間として工事が開始されました。

4

2014年に誕生したジョコウィ政権は、事あるごとに中国寄りと言われ、2015年に中国と日本が受注合戦を繰り広げ日本の新幹線方式での導入が確実視されていたジャカルタ~バンドゥン高速鉄道案件では、インドネシア政府が手のひら返し中国案に鞍替えし、日本を袖にしたのは記憶に新しいところですが、南シナ海の南方にあるナトゥナ諸島周辺の排他的経済水域(EEZ)は、中国が主権を主張する「九段線」と呼ばれる境界と重複しており、中国漁船が公船を伴って活動する違法漁業問題で中国と対立しています。

大統領選挙で考えたギャップにハマるということ 5

ギャップにキュンとするというのは人間の本能みたいなもので、ジョコウィの私利私欲のない素朴なおじさん像と、その実強力なリーダーシップを発揮する実務派という内面が、一見普通の人だが実はスゴイというギャップ好きのインドネシア人に大ウケして、大衆は一種の集団催眠状態にあるようです。

情報の質のレベル 6

見える化された結果を共有化することで問題点が共通認識されますが、共有化が進むことで情報の持つ希少価値が薄れて困る人間がいる場合、有益な情報を独占することでポジションを高めようという政治力が働きます。

7

日本人がインドネシアに来ると、インドネシア人ののんびり加減にイライラするというのは昔からよく聞く話で、インドネシア在住日本人にとってのバイブル的小説である深田祐介著「ガルーダ商人」の中でも、インドネシア宗教省の高官が日本人とインドネシア人を自宅に招待する際に、インドネシア人向けの招待状には、遅刻することを前提にパーティ開始時間を三十分早く書いておくという記述があるほどです。

宗教によって異なる「死んだらどうなる」の考え方 8

キリスト教もイスラム教もともにユダヤ教から派生した宗教であり、それぞれイエス・キリスト(本人が神)またはアッラーという唯一無二の神を信じます。

株価操作なんてインドネシア株では当たり前 9

株価は売り注文と買い注文により変動し、大量の売り注文を買う注文がたくさん入れば、他の投資家達は「俺も俺も」と続くことで株価が上がります。

心臓に毛が生えたインドネシア人のずうずうしい転職活動を応援してみた 10

インドネシア人は秘密の話は誰かに暴露しないと精神の安定を保てない人が多いため、内緒の話に情報の希少性は少なく信憑性も低いことが多いので、「ここだけの話」という枕詞付きで聞かされる話は話半分に聞いておいたほうがいいかもしれません。

日系企業のインドネシアでの存在意義 11

今のまま日本の人口減が続けば、内需は縮小の一途をたどるわけで、そうなると日本国内市場だけで生き残るのは難しいと判断する国内企業が、海外市場に活路を見出そうとするのは必然です。

チャンスはあるが勝てる分野を見つけるのが難しい 12

実際にインドネシアに住んでみて、自分で動いて人と話しをして、現地の事情を少しずつ理解していくにつれて、インドネシアで起業することが意外と手強いことに気づき、その難しさの原因は、高い送料と関税であったりローカル企業との競争であったり、就労ビザ(IMTA)や外国人技能開発基金(DPKK)などのランニングコストの高さであったりします。

インドネシアのシステムインテグレーション業界 13

先日JETRO(日本貿易振興機構)さんと、インドネシアの中小企業のIT投資について意見交換させていただく機会をいただいたのですが、そこで「システム投資のコストメリットはどのように説明できるのか」という、システムインテグレーターの存在価値にも関わる重要な問題提起がありました。

肉体と精神と心と魂 14

「Body and Soul」といえば、昨日の内閣改造に伴う人事で内閣府政務官に内定した自民党の今井絵理子参議院員がメンバーだったSPEEDのデビュー曲であり、インドネシアの老舗女性ファッションブランド名でもあります。

ジャカルタのラーメン市場 15

僕がインドネシアに初めて来たのが1997年10月、インドネシア語は分からないし、仕事は辛いし、周囲の人間は理不尽だし、一時期日本に帰りたくて仕方がない時期がありましたが、当時自分をかろうじてインドネシアに繋ぎ止める心の支えとなっていたのが、協栄プリンスビル(今のWisma Keiai)の日本食レストラン「五右衛門」であり、ここでキムチラーメンを食べることが唯一の楽しみと言っても過言ではありませんでした。

ブランド力、技術力、資金力の3要素 16

1998年のジャカルタ暴動後、ルピアが暴落し海外からのドル建て債務を抱えた国内企業が利子の支払いに苦しんでいた頃、僕は外貨が獲得できるインドネシアでの新しいビジネスを探していました。

日本とインドネシアの間でのタイムマシン経営が通じなくなっている件 17

先進国と後進国との間にある流行のタイムラグを利用して、先進国での成功例を後進国で実践するビジネスモデルをタイムマシン経営といいますが、インターネットの普及に伴い情報がフラット化してしまい、モノと情報のタイムラグが限りなく小さくなった今、先駆者である中小零細同業他社が乱立し市場が出来上がったところに、後発の大手が参入し先発零細を駆逐していく、という典型的な負けパターンにはまります。

サリナデパートとマクドナルド 18

本日5月10日を最後にインドネシアのマクドナルド第1号店であるサリナデパート店(Sarinah)が閉店になりますが、ジャカルタのショッピングモールが新しいコンセプトでモダンにリニューアルされ続ける中で、僕がインドネシアに来たばかりの20数年前には、若者の待ち合わせ場所の定番でもあったサリナデパートやブロックMのパサラヤ(Pasaraya)などは完全に時代に取り残されてしまいました。

不景気の歴史 19

僕がインドネシアに来てからこれまで何度か経済不況を見てきましたが、今回の新型コロナウィルスの感染拡大により、間違いなく景気後退しますので、数年後にはこれがコロナショックとかコロナ不況とか呼ばれるようになるのかもしれません。

日本のバブル経済崩壊後とインドネシアの通貨危機後 20

自分が大学に入学したのがバブル経済末期の1991年、土地も株価もMAX爆上げして、三菱地所がアメリカの象徴であるロックフェラーセンタービルを買収し、ジュリアナ東京でワンレンボディコン(登美丘高校ダンス部のバブリーダンスみたいなやつ)のお姉さん達が扇子振って踊っている時期でした。

内需と外需の自国経済に及ぼす影響 21

公共事業投資を行っても、お金が企業内や個人の貯蓄に滞留してしまい国内消費が増えないのが日本の状況であり、国内消費は増えても消費材の輸入品比率が高く、国内資産が海外に流出しているのがインドネシアの状況です。

2019年の総選挙を前にインドネシア政治史のおさらい 22

来年の大統領選挙(Pemilu Pilpres Pileg Indonesia 2019)に向けての選挙運動(Kampanye)を解禁するにあたり、投票用紙に印字される順番はジョコウィ現職大統領・マフル副大統領候補組が1番、プラボウォ大統領候補・サンディアガウノ副大統領候補組が2番と決まりました。

コーヒーをもっと楽しくもっと美味しく 23

インドネシアは北回帰線と南回帰線をはさむコーヒーベルトに位置するコーヒー栽培に適した国で、1602年の東インド会社の進出を契機にオランダの植民地支配が300年以上続き、その間アラビカ種のコーヒーが持ち込まれ、気候のいい高原地帯で栽培が開始されました。

インドネシア人の悪魔祓い 24

人間誰しも自分の中に悪魔が潜んでおり、それが何らかのきっかけで表面に出て来るという考え方自体には、背景に宗教が有るか無いかの違いだけで、基本的に理解できる話であり、それを信じるか信じないかは別として、そういう考えがあることを認めることは大切なことだと思います。

-WEBサイト作成

© 2020 バテラハイシステム Powered by STINGER