2011年09月29日

cakephp で携帯サイト開発まとめ

お願いします♪いいねとかつぶやいたりして下さい
 
携帯サイト構築まとめ

今回、相性占い.netを制作したときのまとめ。
http://www.aiura.net

以下 head に追加

・リンクの色をモバゲー風に合わせる
<style type="text/css">
<![CDATA[
a:link{color:#00F;}
a:visited{color:#00F;}
a:focus{color:;}
]]>
</style>

・携帯サイトのキャッシュをさせない
<meta http-equiv="pragma" content="no-cache" />
<meta http-equiv="cache-control" content="no-chache" />
<meta http-equiv="expires" content="-1" />

・以下 ktai helper に追加した方が良いもの
/**
* モバゲー風タイトルタグを生成
* <?=$ktai->title('メニュー','#262f7c');?>
*/
function title($str,$color = '#007128'){
$res = '<div style="text-align:center;background-color:'.$color.';"><span style="color:white;">'.$str.'</span></div><hr size="1" style="width:100%;height:1px;margin:2px 0;padding:0;color:#999999;background:#999999;border:1px solid #999999;" />';

return $res;
}

/*
画像を回り込ませる
$ktai->float('/app/webroot/media/filter/xmini/img/4e60758ee3494.jpg','<a href="game.html">ゲーム</a><br />バスケで給料UP!?');
*/
function imgbox($img,$str = '')
{
return '<img src="'.$img.'" style="float:left;margin-top:3px;margin-right:3px;margin-bottom:8px;" align="left" border="0" />'.$str.'<br clear="all" />';
}


/*
点線のラインを引く
<?=$ktai->line();?>
*/
function line()
{
return '<img src="/app/webroot/img/m/line.gif"><br />';
}

・font サイズを合わせる為に
bodyタグ直下 <? $ktai->font();?>
body閉じタグの直上に <? $ktai->fontend(); ?>

を付けること

・携帯サイトの layout 切り替えは before Render で行うこと

<? $ktai->font('small','div','warning');?>
ここが赤くて小さいもじで表示されれば御の字
<? $ktai->fontend(); ?>

ktai helper は、pcからのデバッグじゃ div タグも何も表示されない。
携帯から見れば見れるけど。注意!

pages は コントローラーを通らない。
よって、pagesの際は一つ一つレイアウトを設定する必要がある。

<?
$this->set('title_for_layout','特定商取引法表示及び会社概要');
$this->layout = 'default';
?>


・formヘルパーを改造

◎Ktai ヘルパーをformヘルパー内で使えるようにする


1 $form->error をやった場合、携帯サイトなら自動的に red色の css で色を変更する。

function error($field, $text = null, $options = array()) {
$defaults = array('wrap' => true, 'class' => 'formError', 'escape' => false);
$options = array_merge($defaults, $options);
$this->setEntity($field);

if ($error = $this->tagIsInvalid()) {
if (is_array($error)) {
list(,,$field) = explode('.', $field);
if (isset($error[$field])) {
$error = $error[$field];
} else {
return null;
}
}

if (is_array($text) && is_numeric($error) && $error > 0) {
$error--;
}
if (is_array($text)) {
$options = array_merge($options, array_intersect_key($text, $defaults));
if (isset($text['attributes']) && is_array($text['attributes'])) {
$options = array_merge($options, $text['attributes']);
}
$text = isset($text[$error]) ? $text[$error] : null;
unset($options[$error]);
}

if ($text != null) {
$error = $text;
} elseif (is_numeric($error)) {
$error = sprintf(__('Error in field %s', true), Inflector::humanize($this->field()));
}
if ($options['escape']) {
$error = h($error);
unset($options['escape']);
}

if(!$this->Ktai->is_ktai() && !Configure::read('mobileTest')){

if ($options['wrap']) {
$tag = is_string($options['wrap']) ? $options['wrap'] : 'div';
unset($options['wrap']);
return $this->Html->tag($tag, $error, $options);
} else {
return $error;
}
} else {
return '<div style="color:red;">'.$error.'</div>';
}

} else {
return null;
}
}

2 入力モードを 半角カナのみ 数字のみ に限定する

・css に以下を追記
.hankaku,.numonly {
ime-mode: inactive; /* 半角モード */
}

これでclass に hankaku もしくは numonly があれば PCの場合は半角入力のみしかできないようにする

・フォームヘルパーを改造
     /*
          携帯サイト用にオプションタグを変更する
     */
     function ktaiHelp($fieldName, $options = array())
     {
          //フィールド名に応じて変更
          switch($fieldName){
               case 'email':
               case 'pass':
                    $options['istyle'] = 3;
                    $options['mode'] = 'alphabet';
                    $options['style'] = 'ime-mode:inactive;';
                    $options['format'] = '*x';
               break;
          }
         
          //クラス名に応じて変更
          if(isset($options['class'])){    
               if(preg_match('/hankaku/',$options['class'])){
                    $options['istyle'] = 3;
                    $options['mode'] = 'alphabet';
                    $options['style'] = 'ime-mode:inactive;';
                    $options['format'] = '*x';
               }
              
               if(preg_match('/numonly/',$options['class'])){
                    $options['istyle'] = 4;
                    $options['mode'] = 'numeric';
                    $options['style'] = 'ime-mode:inactive;';
                    $options['format'] = '*N';
               }
          }
         
          return $options;
     }
    
    

     function input($fieldName, $options = array()) {
          $this->setEntity($fieldName);
         
          //オリジナル
          $options = Set::merge($options, $this->ktaiHelp($fieldName, $options));
         
          $options = array_merge(
               array(
                    'before' => null,
                    'between' => null,
                    'after' => null,
                    'format' => null,
                    'label' => false,
                    'legend' => false,
                    'div' => false
               ),
               $this->_inputDefaults,
               $options
          );
         

          $modelKey = $this->model();
          $fieldKey = $this->field();
          if (!isset($this->fieldset[$modelKey])) {
               $this->_introspectModel($modelKey);
          }

          if (!isset($options['type'])) {
               $magicType = true;
               $options['type'] = 'text';
               if (isset($options['options'])) {
                    $options['type'] = 'select';
               } elseif (in_array($fieldKey, array('psword', 'passwd', 'password'))) {
                    $options['type'] = 'password';
               } elseif (isset($this->fieldset[$modelKey]['fields'][$fieldKey])) {
                    $fieldDef = $this->fieldset[$modelKey]['fields'][$fieldKey];
                    $type = $fieldDef['type'];
                    $primaryKey = $this->fieldset[$modelKey]['key'];
               }

               if (isset($type)) {
                    $map = array(
                         'string'  => 'text',     'datetime'  => 'datetime',
                         'boolean' => 'checkbox', 'timestamp' => 'datetime',
                         'text'    => 'textarea', 'time'      => 'time',
                         'date'    => 'date',     'float'     => 'text'
                    );

                    if (isset($this->map[$type])) {
                         $options['type'] = $this->map[$type];
                    } elseif (isset($map[$type])) {
                         $options['type'] = $map[$type];
                    }
                    if ($fieldKey == $primaryKey) {
                         $options['type'] = 'hidden';
                    }
               }
               if (preg_match('/_id$/', $fieldKey) && $options['type'] !== 'hidden') {
                    $options['type'] = 'select';
               }

               if ($modelKey === $fieldKey) {
                    $options['type'] = 'select';
                    if (!isset($options['multiple'])) {
                         $options['multiple'] = 'multiple';
                    }
               }
          }
          $types = array('checkbox', 'radio', 'select');

          if (
               (!isset($options['options']) && in_array($options['type'], $types)) ||
               (isset($magicType) && $options['type'] == 'text')
          ) {
               $view =& ClassRegistry::getObject('view');
               $varName = Inflector::variable(
                    Inflector::pluralize(preg_replace('/_id$/', '', $fieldKey))
               );
               $varOptions = $view->getVar($varName);
               if (is_array($varOptions)) {
                    if ($options['type'] !== 'radio') {
                         $options['type'] = 'select';
                    }
                    $options['options'] = $varOptions;
               }
          }

          $autoLength = (!array_key_exists('maxlength', $options) && isset($fieldDef['length']));
          if ($autoLength && $options['type'] == 'text') {
               $options['maxlength'] = $fieldDef['length'];
          }
          if ($autoLength && $fieldDef['type'] == 'float') {
               $options['maxlength'] = array_sum(explode(',', $fieldDef['length']))+1;
          }

          $divOptions = array();
          $div = $this->_extractOption('div', $options, true);
          unset($options['div']);

          if (!empty($div)) {
               $divOptions['class'] = 'input';
               $divOptions = $this->addClass($divOptions, $options['type']);
               if (is_string($div)) {
                    $divOptions['class'] = $div;
               } elseif (is_array($div)) {
                    $divOptions = array_merge($divOptions, $div);
               }
               if (
                    isset($this->fieldset[$modelKey]) &&
                    in_array($fieldKey, $this->fieldset[$modelKey]['validates'])
               ) {
                    $divOptions = $this->addClass($divOptions, 'required');
               }
               if (!isset($divOptions['tag'])) {
                    $divOptions['tag'] = 'div';
               }
          }

          $label = null;
          if (isset($options['label']) && $options['type'] !== 'radio') {
               $label = $options['label'];
               unset($options['label']);
          }

          if ($options['type'] === 'radio') {
               $label = false;
               if (isset($options['options'])) {
                    $radioOptions = (array)$options['options'];
                    unset($options['options']);
               }
          }

          if ($label !== false) {
               $label = $this->_inputLabel($fieldName, $label, $options);
          }

          $error = $this->_extractOption('error', $options, null);
          unset($options['error']);

          $selected = $this->_extractOption('selected', $options, null);
          unset($options['selected']);

          if (isset($options['rows']) || isset($options['cols'])) {
               $options['type'] = 'textarea';
          }

          if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time' || $options['type'] === 'select') {
               $options += array('empty' => false);
          }
          if ($options['type'] === 'datetime' || $options['type'] === 'date' || $options['type'] === 'time') {
               $dateFormat = $this->_extractOption('dateFormat', $options, 'MDY');
               $timeFormat = $this->_extractOption('timeFormat', $options, 12);
               unset($options['dateFormat'], $options['timeFormat']);
          }

          $type = $options['type'];
          $out = array_merge(
               array('before' => null, 'label' => null, 'between' => null, 'input' => null, 'after' => null, 'error' => null),
               array('before' => $options['before'], 'label' => $label, 'between' => $options['between'], 'after' => $options['after'])
          );
          $format = null;
          if (is_array($options['format']) && in_array('input', $options['format'])) {
               $format = $options['format'];
          }
          unset($options['type'], $options['before'], $options['between'], $options['after'], $options['format']);
         
          //オリジナル
          $options = Set::merge($options, $this->ktaiHelp($fieldName, $options));
         
          switch ($type) {
               case 'hidden':
                    $input = $this->hidden($fieldName, $options);
                    $format = array('input');
                    unset($divOptions);
               break;
               case 'checkbox':
                    $input = $this->checkbox($fieldName, $options);
                    $format = $format ? $format : array('before', 'input', 'between', 'label', 'after', 'error');
               break;
               case 'radio':
                    $input = $this->radio($fieldName, $radioOptions, $options);
               break;
               case 'text':
               case 'password':
               case 'file':
                    $input = $this->{$type}($fieldName, $options);
               break;
               case 'select':
                    $options += array('options' => array());
                    $list = $options['options'];
                    unset($options['options']);
                    $input = $this->select($fieldName, $list, $selected, $options);
               break;
               case 'time':
                    $input = $this->dateTime($fieldName, null, $timeFormat, $selected, $options);
               break;
               case 'date':
                    $input = $this->dateTime($fieldName, $dateFormat, null, $selected, $options);
               break;
               case 'datetime':
                    $input = $this->dateTime($fieldName, $dateFormat, $timeFormat, $selected, $options);
               break;
               case 'textarea':
               default:
                    $input = $this->textarea($fieldName, $options + array('cols' => '30', 'rows' => '6'));
               break;
          }

          if ($type != 'hidden' && $error !== false) {
               $errMsg = $this->error($fieldName, $error);
               if ($errMsg) {
                    $divOptions = $this->addClass($divOptions, 'error');
                    $out['error'] = $errMsg;
               }
          }

          $out['input'] = $input;
          $format = $format ? $format : array('before', 'label', 'between', 'input', 'after', 'error');
          $output = '';
          foreach ($format as $element) {
               $output .= $out[$element];
               unset($out[$element]);
          }
         
          if (!empty($divOptions['tag'])) {
               $tag = $divOptions['tag'];
               unset($divOptions['tag']);
               $output = $this->Html->tag($tag, $output, $divOptions);
          }
         
          return $output;
     }




●ビュー
▼メールアドレス<br />
<?=$form->input('email',array('type' => 'text' , 'class' => 'span-10 need hankaku'));?><br />

ってやれば PCはPC用の半角限定
携帯は携帯用の半角限定CSSが吐き出される。

また ktaiHelp の内容を書き換えることにより、
email の時はアルファベット数字を許可
days の時は 数字のみ許可などと変更できる。
こうすれば hankaku とか入力しなくても自動的に入力フォームを最適化してくれる。


http://www.hideblog.net/nikkis/show/186/

のキャッシュの取り方がスマートフォン用になっているので、
これを修正する。

携帯だと絵文字が文字化けするので機種毎にキャッシュを取るか、
キャッシュを取らないようにしないといけない。
つまりスマートフォンしか取れないか。


これはダメ。エラーがでるのでひでぶろぐ通りに 各それぞれで $this->view をやる必要がある
QDmailのthemeバグを修正 3819 3820 を以下のように修正しておく。
でないと、themeなんて class 見つからないよと出ちゃう

//$view = & new $this->Controller->view( $this->Controller , false );
//$view = 'View';

・app_controller.phpの改造

auだと、どうしてもキャッシュが残る。
なので href の最後にタイムスタンプを追加し、新しいページにアクセスするようにする。

・外部サイトへのリンクはタイムスタンプ無し
・maitoリンクもタイムスタンプ無し
・#、同一ページ内リンクもタイムスタンプ無し

if($this->Ktai->is_ktai() || Configure::read('mobileTest')){
$this->output = preg_replace('/href=["\'](?!http|mailto|#)(.*?)["\']/','href="$1?t='.time().'"',$this->output);
$this->output = mb_convert_kana($this->output, 'rak');
}

aタグ以外を削除(/aがきえちゃうのでそれだけ後付けしてね)
<[^a|\?].*?>


関連するタグ: 携帯サイト cakephp
あなたにとって有用な記事でしたか?是非ブックマークしておくことをおすすめします。
 




ライブラリを配布しちゃったり
webデザイン
Fireworks
HTMLコーディング
CSS
Dreamweaver
携帯サイト
webプログラム
PHP
正規表現
cakephp
MYSQL
javascript
webマーケティング
adwords
analytics
windows7
ショートカットキー
おすすめ情報
サイト
facebook
ライブラリ
配布
アプリ
iphone
ipad
サーバー
さくらサーバー
全ての記事を読む




トップ - 最新の記事一覧 - お問い合わせ