0

我可以找到一些 Twitter Bootstrap 2.x 插件,其中包含 CakePHP 2.x 的一些帮助程序,但我找不到 CakePHP 1.3.x。

https://github.com/slywalker/TwitterBootstrap

https://github.com/loadsys/twitter-bootstrap-helper

这两个插件非常酷,但仅适用于 CakePHP 2.x。

CakePHP 1.3.x 有插件吗?

4

4 回答 4

3

不,不会有。CakePHP 1.3 是旧的,而 Twitter Bootstrap 2.x 是新的。几乎没有人再用 1.3 创建新项目了,所以没有人会觉得有必要为它创建新项目的插件。

如果您使用 Twitter Bootstrap 启动一个新项目,请改用 Cake 2.x。它更好更快。

于 2012-09-07T12:45:43.797 回答
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](布局宽度:这会将 .spanN 类添加到您的控件中)

此外,默认情况下,“maxlength”属性是通过查询数据库元数据来设置的。但是,如果您设置了模型的 $_schema 属性,它将使用那里指定的长度(您可以只在属性的数组中放入您想要严格控制最大长度的字段)。Flash 和 Flashes 方法也可以使用,您可以使用它们在布局/元素中替换它们。

顺便说一句:我很想从 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));
    }

}
?>
于 2012-10-26T20:01:11.967 回答
1

没有插件,但在您的项目中安装并不是特别难。将样式表添加到 CSS 文件夹,将 JavaScript 添加到 js,将字形图标添加到 img。从您的布局中调用它们并开始更新所有视图中的 CSS 类。这种 CSS 类的手动更新是永远不会有插件的原因。

如果您想查看一个集成了 Bootstrap 的特别出色的 Cake 2.x 项目,请查看 CakeStrap。您也许可以从中复制 View 文件夹并将其调整为 1.3 的命名约定。

于 2012-09-07T22:07:59.633 回答
0

您仍然可以将 cakephp 1.3 与 bootstrap 3.0 一起使用。

<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)); ?>
于 2014-04-16T08:20:35.420 回答