soyshop
└── webapp
    └── src
        └── module
            ├── features
            │   └── arrival_shop_info
            │       └── module.ini
            └── plugins
                └── arrival_shop_info
                    ├── page
                    │   ├── ShopInfoAreaPage.class.php
                    │   └── ShopInfoAreaPage.html
                    └── soyshop.admin.top.php

SOY2HTMLで処理とデザインを切り分ける


前回の記事でSOY2HTMLFactoryで処理の部分のPHPファイルと表示の部分のHTMLファイルに分けた。

分けたファイルが上のツリーでいうところの太字の2ファイルになる。

※ショップ情報表示プラグイン(ID:arrival_shop_info)を参考にしています


先にHTMLファイルを見てみると、

ShopInfoAreaPage.html

<dl>
	<dt>ショップ名</dt>
	<dd><!-- soy:id="shop_name" /--></dd>

	<dt>公開URL</dt>
	<dd><a soy:id="shop_url" target="_blank"></a></dd>
</dl>

すべてHTMLの記述と思いきや、

soy:idが二箇所ある。


SOY CMSの開発秘話前編でsoy:id(文中ではcms:id)はプログラマとデザイナがサイトの作成時やWebアプリの開発時に同じファイルを触れないようにするための仕組みで紹介していますが、

この仕様に則ると今回の二箇所のsoy:idは同名のPHPのクラスファイルの方で生成することになります。


というわけで、同名のPHPファイルを改めてみてみると、

ShopInfoAreaPage.class.php

<?php

class ShopInfoAreaPage extends WebPage{

	private $configObj;

	function __construct(){}

	function execute(){
		parent::__construct();

		$this->addLabel("shop_name", array(
			"text" => SOYShop_ShopConfig::load()->getShopName()
		));

		$this->addLink("shop_url", array(
			"text" => soyshop_get_site_url(true),
			"link" => soyshop_get_site_url(true)
		));
	}

	function setConfigObj($configObj){
		$this->configObj = $configObj;
	}
}

execute内でHTML側で使用しているsoy:idと同じ記述がある。

HTML側で使用できるsoy:idを作成する場合、PHPファイル側で、

$this->addLabel("shop_name", array(
	"text" => SOYShop_ShopConfig::load()->getShopName()
));

このようにSOY2HTMLを継承しているWebPageクラスのメソッドのaddLabelを利用することで、

同名のHTMLファイルでPHP側の処理の結果を出力できるsoy:idタグを生成することができます。


addLabelの詳しい使用方法は、第一引数にsoy:id="***"の***に当たる箇所を指定して、

第二引数の配列内でtextプロパティ、もしくはhtmlプロパティにPHPの処理の結果を入れます。


第二引数内で使用できる値は文字列をエンコードして出力したい場合は

array("text" => "hoge")のようにして、


HTMLの記述そのまま表示したい場合は、

array("html" => "<p>hoge</p>")

のようにします。


addLabelを詳しく知りたい場合は、

もともとは、

$this->createAdd("shop_name", "HTMLLabel", array(
	"text" => SOYShop_ShopConfig::load()->getShopName()
));

が正式な書き方で、

第二引数で指定してあるものが、soy:idの生成時にベースとしたいクラス(機能)で

/common/lib/soy2_build.phpを開きclass HTMLLabelでテキスト検索すると

該当するクラスを読むことができます。


/* SOY2HTML/SOY2HTMLComponents/HTMLLabel.class.php */
/**
 * @package SOY2.SOY2HTML
 */
class HTMLLabel extends SOY2HTML{
	const SOY_TYPE = SOY2HTML::HTML_BODY;
	var $text;
	private $width;
	private $isFolding;
	private $foldingTag = "<br />";
	private $isHtml = false;
	private $suffix = "...";
	function setText($text){
		$this->text = (string)$text;
	}
	function getText(){
		return (string)$this->text;
	}
	function setHtml($html){
		$this->text = (string)$html;
		$this->isHtml = true;
	}
	function getObject(){
		$text = $this->getText();
		if($this->isHtml){
			return $text;
		}else{
			if(strlen($this->width) >0){
				if($this->isFolding != true){
					$width = max(0, $this->width - mb_strwidth($this->suffix));
					$short_text = mb_strimwidth($text,0,$width);
		    		if(mb_strwidth($short_text) < mb_strwidth($text)){
				    	$short_text .= $this->suffix;
		    		}
		    		if(mb_strwidth($short_text) < mb_strwidth($text)){
		    			$text = $short_text;
		    		}
					return htmlspecialchars($text,ENT_QUOTES,SOY2HTML::ENCODING);
				}else{
					$folded = "";
					while(strlen($text)>0){
						$tmp = mb_strimwidth($text, 0, $this->width);
						$text = mb_substr($text, mb_strlen($tmp));
						$folded .= htmlspecialchars($tmp,ENT_QUOTES,SOY2HTML::ENCODING);
						if(strlen($text) >0) $folded .= $this->foldingTag;
					}
					return $folded;
				}
			}else{
				return htmlspecialchars($text,ENT_QUOTES,SOY2HTML::ENCODING);
			}
		}
	}
	function setWidth($width){
		$this->width = $width;
	}
	function setIsFolding($flag){
		$this->isFolding = (boolean)$flag;
	}
	function setFoldingTag($tag){
		$this->foldingTag = $tag;
	}
	public function getSuffix() {
		return $this->suffix;
	}
	public function setSuffix($suffix) {
		$this->suffix = $suffix;
	}
}

機会があれば、HTMLLabel以外のものも紹介できればと思います。


補足

$this->addLabel("shop_name", array(
	"soy2prefix" => "cms",
	"text" => SOYShop_ShopConfig::load()->getShopName()
));

第二引数の配列内でsoy2prefixの値を指定すると、

soy:id="***"のsoyの箇所がsoy2prefix(今回はcms)に置換されます。

※soy2prefix => "cms"でcms:id="****"になる