2012-09-06 65 views

回答

3

不,不會有。 CakePHP 1.3是舊的,Twitter Bootstrap 2.x是新的。幾乎沒有人用1.3創建新項目,所以沒有人會覺得有必要爲它的新項目創建一個插件。

如果您使用Twitter Bootstrap啓動一個新項目,請改爲使用Cake 2.x。它更好,更快。

+0

謝謝。我在我的個人項目中使用CakePHP2.x,但我的商業客戶不允許我在他們的項目中使用2.x ... – supermomonga

+0

突出顯示性能的+1 –

1

沒有插件,但在您的項目上安裝並不困難。將樣式表添加到CSS文件夾,將JavaScript添加到js,並將圖形添加到img。從佈局調用它們並開始更新所有視圖中的CSS類。這種手動更新CSS類是爲什麼永遠不會有插件。

如果你想看到一個特別出色的Cake 2.x項目集成了Bootstrap,可以看看CakeStrap。您可能可以從中複製View文件夾,並將其修改爲1.3的命名約定。

+0

謝謝。我會嘗試從2.0插件中製作引導式助手。 – supermomonga

1

我已經回到Cake 2.0的Twitter Bootstrap助手。它不是一個插件,而是一個幫手,只是把它放在一個名爲app/views/helpers/t_b_s.php的文件中。並在您的意見中,將所有$this->Form->input()呼叫全部替換爲$this->TBS->input()。此方法是我在生產應用程序中測試和使用的唯一方法。

此方法將創建許多表單控件類型,自動或顯式。 'type'選項可以是:text,textarea,textdate(帶有jquery.calendar插件的文本輸入),checkbox,select,radioGroup(你可以通過'selectOptions'屬性傳遞一個有效選項的數組)。您可以使用選項'prepend','append','ly_w'=> [1,2,3,4](Layout Width:這將添加.spanN類到您的控件)

此外,默認情況下'maxlength'屬性通過查詢數據庫元數據來設置。但是如果你有該模型的$ _schema屬性設置,它將使用在那裏指定的長度(你可以只放入屬性的數組中的字段,你想要一個嚴格的maxlenght控制)。 Flash和閃爍方法也可以工作,您可以使用它們在您的佈局/元素中替換它們。

順便說一句:我渴望從1.3遷移到2,但我遇到了dbo_firebird數據源的麻煩。我已經從github的驅動程序開始,但我已經編寫並修補了很多東西,例如,我會在適當的線程上尋求幫助。

<?php 
/** 
* Helper to generate Twitter's Bootstrap UI interface controls and styles. 
* Based on the code from Joey Trapp 
* 
* @author Lev A Gutierrez 
* 
*/ 

/** 
* Helper that captures the Session flash and renders it in proper html 
* for the twitter bootstrap alert-message styles. 
* 
* @author Joey Trapp 
* 
*/ 
class TBSHelper extends AppHelper { 

    /** 
    * Helpers available in this helper 
    * 
    * @var array 
    * @access public 
    */ 
    public $helpers = array("Form", "Html", "Ajax", "Session", 'Number', 'Time', 'Text'); 


    // Confirm Replacement 
    /** 
    * Creates an HTML link. 
    * 
    * If $url starts with "http://" this is treated as an external link. Else, 
    * it is treated as a path to controller/action and parsed with the 
    * HtmlHelper::url() method. 
    * 
    * If the $url is empty, $title is used instead. 
    * 
    * ### Options 
    * 
    * - `escape` Set to false to disable escaping of title and attributes. 
    * 
    * @param string $title The content to be wrapped by <a> tags. 
    * @param mixed $url Cake-relative URL or array of URL parameters, or external URL (starts with http://) 
    * @param array $options Array of HTML attributes. 
    * @param string $confirmMessage JavaScript confirmation message. 
    * @return string An `<a />` element. 
    * @access public 
    * @link http://book.cakephp.org/view/1442/link 
    */ 
     function link($title, $url = null, $options = array(), $confirmMessage = false) { 
      $escapeTitle = true; 
      if ($url !== null) { 
       $url = $this->url($url); 
      } else { 
       $url = $this->url($title); 
       $title = $url; 
       $escapeTitle = false; 
      } 

      if (isset($options['escape'])) { 
       $escapeTitle = $options['escape']; 
      } 

      if ($escapeTitle === true) { 
       $title = h($title); 
      } elseif (is_string($escapeTitle)) { 
       $title = htmlentities($title, ENT_QUOTES, $escapeTitle); 
      } 

      if (!empty($options['confirm'])) { 
       $confirmMessage = $options['confirm']; 
       unset($options['confirm']); 
      } 
      if ($confirmMessage) { 
       $confirmMessage = str_replace("'", "\'", $confirmMessage); 
       $confirmMessage = str_replace('"', '\"', $confirmMessage); 
       $options['onclick'] = "return bootbox.confirm('{$confirmMessage}');"; 
      } elseif (isset($options['default']) && $options['default'] == false) { 
       if (isset($options['onclick'])) { 
        $options['onclick'] .= ' event.returnValue = false; return false;'; 
       } else { 
        $options['onclick'] = 'event.returnValue = false; return false;'; 
       } 
       unset($options['default']); 
      } 
      return sprintf($this->Html->tags['link'], $url, $this->_parseAttributes($options), $title); 
     } 


    /** 
    * Takes an array of options to output markup that works with 
    * twitter bootstrap forms. 
    * 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function input($field, $options = array()) { 

     // Checkout how the input parameters are given 
     if (is_array($field)) { 
      $options = $field; 
      $field = $options['field']; 
     } else { 
      $options["field"] = $field; 
     } 

     if (!isset($field)) { return ''; } 

     $out = $theGroup = $theHelp = $theLabel = $theControl = $theError = $help_inline = $help_block = $theStyleClass = $theScripts = $thePrependAppendClass = $theSelectOptions = ''; 

     // Default options, etc... 
     if(isset($options['type'])) 
      $theType=$options['type']; 

     $defaults = array(
      'help_inline' => '', 
      'help_block' => '', 
     ); 

//  $options = array_merge($defaults, $options); 

     // Determine both model and field parameters 
     $theModel = ucfirst($this->Form->defaultModel); 
     $split = explode(".", $options["field"]); 
     if($split && sizeof($split)>1) { 
      $theModel = ucfirst($split[0]); 
      $theField = ucfirst($split[1]); 
     } 
     else { 
      $theField = ucfirst($split[0]); 
     } 

     $options['field'] = $theModel.(!empty($theModel)?'.':'').$theField; 

     // Introspects the Model to get field's info 
     if (!isset($this->Form->fieldset[$theModel])) { 
      $this->Form->_introspectModel($theModel); 
     } 

     // Get the field's metadata into the theFieldMeta variable 
     if(isset($this->Form->fieldset) && 
      array_key_exists($theModel, $this->Form->fieldset) && 
      array_key_exists('fields', $this->Form->fieldset[$theModel]) 
      ) { 
      $theFieldMeta=$this->Form->fieldset[$theModel]['fields'][strtolower($theField)]; 
     } 

     // If the field's type is text or String, 
     // then set the MaxLength option when it is not passed by parameter. 
     if(!array_key_exists('maxlength', $options) && 
      isset($theFieldMeta['length']) && 
      isset($theFieldMeta['type']) && 
      ($theFieldMeta['type']=='text' || $theFieldMeta['type']=='string') 
     ) { 
      $options['maxlength']=$theFieldMeta['length']; 
     } 

     // Generate a Label for the Control 
     if (!isset($options['label']) || $options['label'] === false) { 
      $options['label'] = ''; 
     } else if (!empty($options['label'])) { 
      $theLabel = '<label for="'.$theModel.$theField.'" class="control-label">'.$options['label'].'</label>'; 
     } else { 
      if(!isset($options['label'])) 
       $theLabel = '<label for="'.$theModel.$theField.'" class="control-label">'.$theField.'</label>'; 
     } 
     $options['label']=false; 

     // Generate the extra Prepend/Appended content 
     if (!empty($options['prepend'])) { 
      $thePrepend=$this->Html->tag('span',$options['prepend'], array('class'=>'add-on')); 
      $options['prepend']=null; 
      $thePrependAppendClass="input-prepend"; 
     } 
     if (!empty($options["append"])) { 
      $theAppend=$this->Html->tag("span",$options['append'], array('class'=>'add-on')); 
      $options['append']=null; 
      $thePrependAppendClass.="input-append"; 
     } 

     // generate the error... 
     list($help_inline, $help_block) = $this->_help_markup($options); 

     // generate the error message for the input field, if any... 
     if ($this->Form->error($field)) { 
//   echo WCR.WCR."Error-${field}::".$this->Form->error($field); 
      $theError=$this->Form->error($field); 
      $help_block = $this->Html->tag(
       "span", 
       str_replace(array('<div class="error-message">','</div>'),'',$this->Form->error($field)), 
       array("class" => "help-inline") 
      ); 
     } 

     // Get the control's layout width and define the control's style class 
     if(isset($options['class'])) $theStyleClass=trim($options['class']); 
     if(isset($options['ly_w'])) { 
      $theStyleClass.=' span'.$options['ly_w']; 
      $options['ly_w']=null; 
     } 
     $options['class']=trim($theStyleClass); 

     if(isset($options['type']) && $options['type']=='textdate') { 
      $options['type']='text'; 
      $theScripts.=' $(\'#'.$theModel.'.'.$options['field'].'\').datepicker({ dateFormat: \'yy-mm-dd\'});'; 
//   $options['dateFormat'] = 'DMY'; 
     } 

     // generate the form's input control (main thing) 
      // 
     $options['div']=false; 

     if(isset($options['type']) && $options['type']=='radiogroup') { 
      $theSelectOptions=$options['selectOptions']; 
      $options['selectOptions']=null; 
      $theControl = $this->Form->radio($field, $theSelectOptions, array('label'=>'','legend'=>'','div'=>false)); 
     } 
     else { 
      if(isset($this->data[$theModel][strtolower($theField)]) && 
      !empty($this->data[$theModel][strtolower($theField)]) && 
       is_numeric(trim($this->data[$theModel][strtolower($theField)])) && 
       trim($this->data[$theModel][strtolower($theField)])<>'' && 
       !is_integer(trim($this->data[$theModel][strtolower($theField)])) 
       ) 
      if(isset($options['format'])) { 
       if($options['format']==='currency') { 
        $options['value']=$this->Number->currency(trim($this->data[$theModel][strtolower($theField)]), array('places'=>'2')); 
       } 
       if($options['format']==='integer') { 
        $options['value']=$this->Number->format(trim($this->data[$theModel][strtolower($theField)]), array('places'=>'0'));     
       } 

      } 

      $theControl = $this->Form->input($field, $options);   
     } 

     // clean the error message, if any. 
     $theControl = str_replace($this->Form->error($field),'',$theControl); 

/* 
     if(stristr('type="text"',$theControl)) { 
      str_ireplace('type="text"', 'type="text" maxlength="'..'"'); 
     } 
*/  
     // create the prepend-append div 
     if(!empty($thePrepend) || !empty($theAppend)) { 
      $controlGroup = $this->Html->tag(
          "div", 
          (!empty($thePrepend)?$thePrepend:''). 
          $theControl. 
          (!empty($theAppend)?$theAppend:''), 
          array("class" => $thePrependAppendClass)); 
     } 
     else { 
      $controlGroup = $theControl; 
     } 

     // control's div 
     $controlGroup = $this->Html->tag(
      "div", 
      $controlGroup. 
      $help_inline.$help_block, 
      array("class" => "controls input".(isset($options['multiple'])?' multiple-input':'')) 
     ); 

     if(!empty($theScripts)) { 
      $theScripts='<script>'.$theScripts.'</script>'; 
     } 

     // final control-group div. Set the field's style here. 
     $controlGroup = $this->Html->tag(
      "div", 
      $theLabel.$controlGroup.$theScripts, 
      array("class" => "control-group".(!empty($theError)?' error':'')) 
     ); 

     return $controlGroup."\n"; 
    } 

    /** 
    * Takes the options from the input method and returns an array of the 
    * inline help and inline block content wrapped in the appropriate markup. 
    * 
    * @param mixed $options 
    * @access public 
    * @return string 
    */ 
    public function _help_markup($options) { 
     $help_markup = array("help_inline" => "", "help_block" => ""); 
     foreach (array_keys($help_markup) as $help) { 
      if (isset($options[$help]) && !empty($options[$help])) { 
       $help_class = str_replace("_", "-", $help); 
       $help_markup[$help] = $this->Html->tag(
        "span", 
        $options[$help], 
        array("class" => $help_class) 
       ); 
      } 
     } 
     return array_values($help_markup); 
    } 

    /** 
    * Outputs a list of radio form elements with the proper 
    * markup for twitter bootstrap styles 
    * 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function radio($field, $options = array()) { 
     if (is_array($field)) { 
      $options["field"] = $field; 
     } else { 
      $options = $field; 
     } 
     if (!isset($options["options"]) || !isset($options["field"])) { return ""; } 
     $opt = $options["options"]; 
     $options["options"]=null; 
     $inputs = ""; 
     foreach ($opt as $key => $val) { 
      $input = $this->Form->radio(
       $options["field"], 
       array($key => $val), 
       array("label" => false) 
      ); 
      $id = array(); 
      preg_match_all("/id=\"[a-zA-Z0-9_-]*\"/", $input, $id); 
      if (isset($id[0][1]) && !empty($id[0][1])) { 
       $id = $id[0][1]; 
       $id = substr($id, 4); 
       $id = substr($id, 0, -1); 
       $input = $this->Html->tag("label", $input, array("for" => $id)); 
      } 
      $inputs .= $this->Html->tag("li", $input); 
     } 
     $options["input"] = $this->Html->tag("ul", $inputs, array("class" => "inputs-list")); 
     return $this->input($options); 
    } 

    /** 
    * Wraps the form button method and just applies the Bootstrap classes to the button 
    * before passing the options on to the FormHelper button method. 
    * 
    * @param string $value 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function button($value = "Submit", $options = array()) { 
     $options = $this->button_options($options); 
     return $this->Form->button($value, $options); 
    } 

    /** 
    * Wraps the html link method and applies the Bootstrap classes to the options array 
    * before passing it on to the html link method. 
    * 
    * @param mixed $title 
    * @param mixed $url 
    * @param array $options 
    * @param mixed $confirm 
    * @access public 
    * @return string 
    */ 
    public function button_link($title, $url, $options = array(), $confirm = false) { 
     $options = $this->button_options($options); 
     return $this->Html->link($title, $url, $options, $confirm); 
    } 

    /** 
    * Wraps the postLink method to create post links that use the bootstrap button 
    * styles. 
    * 
    * @param mixed $title 
    * @param mixed $url 
    * @param array $options 
    * @param mixed $confirm 
    * @access public 
    * @return string 
    */ 
    public function button_form($title, $url, $options = array(), $confirm = false) { 
     $options = $this->button_options($options); 
     return $this->Form->postLink($title, $url, $options, $confirm); 
    } 

    /** 
    * Takes the array of options from $this->button or $this->button_link and returns 
    * the modified array with the bootstrap classes 
    * 
    * @param mixed $options 
    * @access public 
    * @return string 
    */ 
    public function button_options($options) { 
     $valid_styles = array("danger", "info", "primary", "success"); 
     $valid_sizes = array("small", "large"); 
     $style = isset($options["style"]) ? $options["style"] : ""; 
     $size = isset($options["size"]) ? $options["size"] : ""; 
     $disabled = isset($options["disabled"]) ? (bool)$options["disabled"] : false; 
     $class = "btn"; 
     if (!empty($style) && in_array($style, $valid_styles)) { $class .= " {$style}"; } 
     if (!empty($size) && in_array($size, $valid_sizes)) { $class .= " {$size}"; } 
     if ($disabled) { $class .= " disabled"; } 
     unset($options["style"]); 
     unset($options["size"]); 
     unset($options["disabled"]); 
     $options["class"] = isset($options["class"]) ? $options["class"] . " " . $class : $class; 
     return $options; 
    } 

    /** 
    * Delegates to the HtmlHelper::getCrumbList() method and sets the proper class for the 
    * breadcrumbs class. 
    * 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function breadcrumbs($options = array()) { 
     return $this->getCrumbList(array_merge(array("class" => "breadcrumb"), $options)); 
    } 

    /** 
    * Delegates to the HtmlHelper::addCrumb() method. 
    * 
    * @param mixed $title 
    * @param mixed $link 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function add_crumb($title, $url, $options = array()) { 
     return $this->Html->addCrumb($title, $url, $options); 
    } 

    /** 
    * Creates a Bootstrap label with $messsage and optionally the $type. Any 
    * options that could get passed to HtmlHelper::tag can be passed in the 
    * third param. 
    * 
    * @param string $message 
    * @param string $type 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function label($message = "", $style = "", $options = array()) { 
     $class = "label"; 
     $valid = array("success", "important", "warning", "notice"); 
     if (!empty($style) && in_array($style, $valid)) { 
      $class .= " {$style}"; 
     } 
     if (isset($options["class"]) && !empty($options["class"])) { 
      $options["class"] = $class . " " . $options["class"]; 
     } else { 
      $options["class"] = $class; 
     } 
     return $this->Html->tag("span", $message, $options); 
    } 

    /** 
    * Renders alert markup and takes a style and closable option 
    * 
    * @param mixed $content 
    * @param array $options 
    * @access public 
    * @return void 
    */ 
    public function alert($content, $options = array()) { 
     $close = ""; 
     if ((isset($options['closable']) && $options['closable']) || !isset($options['closable']) ||true) { 
      $close = '<a href="#" class="close" data-dismiss="alert">x</a>'; 
     } 
     $style = isset($options["style"]) ? $options["style"] : "flash"; 
     $types = array("info", "success", "error", "warning"); 
     if ($style === "flash") { 
      $style = "info"; 
     } 
     if (strtolower($style) === "auth") { 
      $style = "error"; 
     } 
     if (!in_array($style, array_merge($types, array("auth", "flash")))) { 
      $style = "error"; 
     } 
     $class = "alert alert-{$style}"; 
     return $this->Html->tag(
      'div', 
      '<h4 class="alert-heading">'.$style.'!</h4>'. 
      "{$close}<p>{$content}</p>", 
      array("class" => $class) 
     ); 
    } 

    /** 
    * Captures the Session flash if it is set and renders it in the proper 
    * markup for the twitter bootstrap styles. The default key of "flash", 
    * gets translated to the warning styles. Other valid $keys are "info", 
    * "success", "error". The $key "auth" with use the error styles because 
    * that is when the auth form fails. 
    * 
    * @param string $key 
    * @param $options 
    * @access public 
    * @return string 
    */ 
    public function flash($key = "flash", $options = array()) { 
     $content = $this->_flash_content($key); 
     if (empty($content)) { return ''; } 
     $close = false; 
     if ((isset($options['closable']) && $options['closable'])) { 
      $close = true; 
     } 
     return $this->alert($content, array("style" => $key, "closable" => $close)); 
    } 

    /** 
    * By default it checks $this->flash() for 5 different keys of valid 
    * flash types and returns the string. 
    * 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function myflashes($options = array()) { 
     if (!isset($options["keys"]) || !$options["keys"]) { 
      $options["keys"] = array("info", "success", "error", "warning", "flash"); 
     } 
     if (isset($options["auth"]) && $options["auth"]) { 
      $options["keys"][] = "auth"; 
      unset($options["auth"]); 
     } 
     $keys = $options["keys"]; 
     unset($options["keys"]); 
     $out = ''; 
     foreach($keys as $key) { 
      $thisFlash=$this->_flash_content($key); 
      if(!empty($thisFlash)) { 
       if($key=='default') { 
        $out.='<div id="flashMessage" class="alert alert-info"> 
    <a class="close" data-dismiss="alert">×</a> 
    <h4 class="alert-heading">Atencion !</h4> 
    <p>'. 
    $thisFlash.' 
    </p> 
</div>'; 
       } 
       else { 
        $out.=$thisFlash; 
       } 
      } 
     } 
     return $out; 
    } 

    /** 
    * By default it checks $this->flash() for 5 different keys of valid 
    * flash types and returns the string. 
    * 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function flashes($options = array()) { 
     if (!isset($options["keys"]) || !$options["keys"]) { 
      $options["keys"] = array("info", "success", "error", "warning", "flash"); 
     } 
     if (isset($options["auth"]) && $options["auth"]) { 
      $options["keys"][] = "auth"; 
      unset($options["auth"]); 
     } 
     $keys = $options["keys"]; 
     unset($options["keys"]); 
     $out = ''; 
     foreach($keys as $key) { 
      $out .= $this->flash($key, $options); 
     } 
     return $out; 
    } 


/** 
* Create a text field with Autocomplete. 
* 
* Creates an autocomplete field with the given ID and options. 
* 
* options['with'] defaults to "Form.Element.serialize('$field')", 
* but can be any valid javascript expression defining the additional fields. 
* 
* @param string $field DOM ID of field to observe 
* @param string $url URL for the autocomplete action 
* @param array $options Ajax options 
* @return string Ajax script 
* @link http://book.cakephp.org/view/1370/autoComplete 
*/ 
    function autoComplete($field, $url = "", $options = array()) { 
     $out=$this->Ajax->autocomplete($field, $url, $options); 
     return $out; 
    } 

    /** 
    * Returns the content from SessionHelper::flash() for the passed in 
    * $key. 
    * 
    * @param string $key 
    * @access public 
    * @return void 
    */ 
    public function _flash_content($key = "flash") { 
     return $this->Session->flash($key, array("element" => null)); 
    } 

    /** 
    * Displays the alert-message.block-messgae div's from the twitter 
    * bootstrap. 
    * 
    * @param string $message 
    * @param array $links 
    * @param array $options 
    * @access public 
    * @return string 
    */ 
    public function block($message = null, $options = array()) { 
     $style = "warning"; 
     $valid = array("warning", "success", "info", "error"); 
     if (isset($options["style"]) && in_array($options["style"], $valid)) { 
      $style = $options["style"]; 
     } 
     $class = "alert-message block-message {$style}"; 
     $close = $links = ""; 
     if (isset($options["closable"]) && $options["closable"]) { 
      $close = '<a href="#" class="close">x</a>'; 
     } 
     if (isset($options["links"]) && !empty($options["links"])) { 
      $links = $this->Html->tag(
       "div", 
       implode("", $options["links"]), 
       array("class" => "alert-actions") 
      ); 
     } 
     return $this->Html->tag("div", $close.$message.$links, array("class" => $class)); 
    } 

} 
?> 
0

你仍然可以在bootstrap 3.0中使用cakephp 1.3。

<style> 
.form-control {width:auto} 
</div> 
<?php 
echo $this->Form->create('YourForm',array(
     'inputDefaults'=>array(
     'label' => array(
     'class' => 'col col-md-4 control-label' 
    ), 
    'div' => 'form-group', 
     'wrapInput' => 'col col-md-8', 
     'class' => 'form-control' 
    ), 
    'class'=>'form-horizontal', 
    )); ?> 

<div class='col-md-12'> 
    //your form control here 
</div> 
<?php echo $this->Form->end(__('', false)); ?>