草庐IT

php - 如何包装HTML代码而不在Twig中包含新文件?

coder 2024-04-10 原文

我有代表框的CSS div,它们包装了html代码。

<div class="box indent">
  <div class="padding">
    my code here
  </div>
</div>

我创建了一个“layoutbundle”,其中每个HTML包装器(例如框,选项卡,网格等)都放置在单独的 Twig 文件中。以这种方式,可以使用其他布局来实现对其他束的查看。

但是我厌倦了包含。每个小的html包装器都需要一个include,我想知道是否有一种更简单的方法来包装HTML代码。

让我们用一个简单的盒子作为例子。实际上,我创建了几个文件:

包含该框并包含以下内容的box.html.twig文件:
<div class="box indent">
  <div class="padding">
    {% include content %}
  </div>
</div>

几个box-content.html.twig文件,其中包含我的盒子的内容。

最后,我通过执行以下操作在 View 中创建一个框:
{%
  include 'AcmeDemoBundle:layout:box.html.twig'
  with {
    'content': 'ReusableBundle:feature:xxx.html.twig'
  }
%}

有没有一种创建包装器的方法,例如:

a)我一次声明了一个新的包装器:
{% wrapperheader "box" %}
    <div class="box indent">
      <div class="padding">
{% endwrapperheader %}

{% wrapperfooter "box" %}
      </div>
    </div>
{% endwrapperfooter %}

b)然后在我的页面中,使用:
{% wrapper "box" %}
  {# here my content #}
{% endwrapper %}

我想我需要在Twig中添加新的标签扩展名,但是首先我想知道类似的事情是否在本地是可能的。

最佳答案

块法

该方法由Sebastiaan Stok在GitHub上提出。

这个想法使用了block function。它写入给定的块内容,并且可以被调用多次。

包装文件:

{# src/Fuz/LayoutBundle/Resources/views/Default/wrappers.html.twig #}

{% block box_head %}
    <div class="box indent">
      <div class="padding">
{% enblock %}

{% block box_foot %}
      </div>
    </div>
{% enblock %}

功能页:
{{ block('box_head') }}
Some content
{{ block('box_foot') }}

包装宏扩展

这个想法是由Charles在GitHub上提出的。

首先,您在macro.html.twig文件中声明一个宏。
{% macro box(content) %}
    <div class="box indent">
      <div class="padding">
         {{ content | raw }}
      </div>
    </div>
{% endmacro %}

然后,Amd,而不是调用{{ macros.box('my content') }}(请参阅doc,您将开发一个{% wrap %}标签,该标签将处理宏调用,并将[% wrap %}{% endwrap %}之间的参数作为参数。

此扩展很容易开发。我认为可能很难访问宏,但是实际上,它们作为对象存储在上下文中,并且可以轻松地编译调用。

只是一些更改:我们将使用以下语法:
{# to access a macro from an object #}
{% wrap macro_object macro_name %}
  my content here
{% endwrap %}

{# to access a macro declared in the same file #}
{% wrap macro_name %}
   macro
{% endwrap %}

在以下代码中,如果您想使其生效,请不要忘记更改 namespace !

首先,在您的services.yml中添加扩展名:
parameters:
    fuz_tools.twig.wrap_extension.class: Fuz\ToolsBundle\Twig\Extension\WrapExtension

services:
  fuz_tools.twig.wrap_extension:
    class: '%fuz_tools.twig.wrap_extension.class%'
    tags:
      - { name: twig.extension }

在包中,创建一个Twig目录。

添加扩展名,它将返回新的TokenParser(用英语:它将声明新标签)。

Twig/Extension/WrapExtension.php:
<?php

// src/Fuz/ToolsBundle/Twig/Extension/WrapExtension.php

namespace Fuz\ToolsBundle\Twig\Extension;

use Fuz\ToolsBundle\Twig\TokenParser\WrapHeaderTokenParser;
use Fuz\ToolsBundle\Twig\TokenParser\WrapFooterTokenParser;
use Fuz\ToolsBundle\Twig\TokenParser\WrapTokenParser;

class WrapExtension extends \Twig_Extension
{

    public function getTokenParsers()
    {
        return array (
                new WrapTokenParser(),
        );
    }

    public function getName()
    {
        return 'wrap';
    }

}

然后添加TokenParser本身,当解析器找到{% wrap %}标记时就会满足。此TokenParser将检查标记是否被正确调用(在我们的示例中,它具有2个参数),存储这些参数并获取{% wrap %}和{%endwrap%}`之间的内容。

Twig/TokenParser/WrapTokenParser.php:
<?php

// src/Fuz/ToolsBundle/Twig/TokenParser/WrapTokenParser.php

namespace Fuz\ToolsBundle\Twig\TokenParser;

use Fuz\ToolsBundle\Twig\Node\WrapNode;

class WrapTokenParser extends \Twig_TokenParser
{

    public function parse(\Twig_Token $token)
    {
        $lineno = $token->getLine();
        $stream = $this->parser->getStream();

        $object = null;
        $name = $stream->expect(\Twig_Token::NAME_TYPE)->getValue();

        if ($stream->test(\Twig_Token::BLOCK_END_TYPE))
        {
            if (!$this->parser->hasMacro($name))
            {
                throw new \Twig_Error_Syntax("The macro '$name' does not exist", $lineno);
            }
        }
        else
        {
            $object = $name;
            $name = $stream->expect(\Twig_Token::NAME_TYPE)->getValue();
        }

        $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
        $body = $this->parser->subparse(array ($this, 'decideWrapEnd'), true);
        $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);

        return new WrapNode($object, $name, $body, $token->getLine(), $this->getTag());
    }

    public function decideWrapEnd(\Twig_Token $token)
    {
        return $token->test('endwrap');
    }

    public function getTag()
    {
        return 'wrap';
    }

}

接下来,我们需要一个编译器(twig方言中的Node),它将生成与{% wrap %}标记关联的PHP代码。

这个标签是{{ macro_object.box(content) }}的别名,因此我在模板中写了该行,并在生成的生成的php文件(存储在app/cache/dev/twig目录中)中查看了生成的代码。我有 :
echo $this->getAttribute($this->getContext($context, "(macro object name)"), "(name)", array("(body)"), "method");

所以我的编译器变成了:

Twig/Node/WrapNode.php:
<?php

// src/Fuz/ToolsBundle/Twig/Node/WrapNode.php

namespace Fuz\ToolsBundle\Twig\Node;

class WrapNode extends \Twig_Node
{

    public function __construct($object, $name, $body, $lineno = 0, $tag = null)
    {
        parent::__construct(array ('body' => $body), array ('object' => $object, 'name' => $name), $lineno, $tag);
    }

    public function compile(\Twig_Compiler $compiler)
    {
        $compiler
           ->addDebugInfo($this)
           ->write('ob_start();');

        $compiler
           ->addDebugInfo($this)
           ->subcompile($this->getNode('body'));

        if (is_null($this->getAttribute('object')))
        {
            $compiler
               ->write(sprintf('echo $this->get%s(ob_get_clean());', $this->getAttribute('name')) . "\n");
        }
        else
        {
            $compiler
               ->write('echo $this->getAttribute($this->getContext($context, ')
               ->repr($this->getAttribute('object'))
               ->raw('), ')
               ->repr($this->getAttribute('name'))
               ->raw(', array(ob_get_clean()), "method");')
               ->raw("\n");
        }
    }

}

注意:要了解子解析/子编译的工作方式,我阅读了spaceless扩展源代码。

就这样!我们得到了一个别名,该别名使我们可以使用具有较大主体的宏。尝试一下:

macros.html.twig:
{% macro box(content) %}
    <div class="box indent">
      <div class="padding">
         {{ content | raw }} {# Don't forget the raw filter! #}
      </div>
    </div>
{% endmacro %}

一些layout.html.twig:
{% import "FuzLayoutBundle:Default:macros.html.twig" as macros %}

{% wrap macros box %}
test
{% endwrap %}

{% macro test(content) %}
some {{ content | raw }} in the same file
{% endmacro %}

{% wrap test %}
macro
{% endwrap %}

输出:
    <div class="box indent">
      <div class="padding">
test
      </div>
    </div>

some macro in the same file

wrapperheader,wrapperfooter,wrapper扩展

这个方法就是我在问题中告诉您的一种方法。如果您想使用 token 解析器来训练自己,则可以阅读/实现它,但是从功能上讲,它不如以前的方法好。

wrapper.html.twig文件中,声明所有包装器:
{% wrapperheader box %}
    <div class="box">
{% endwrapper %}
{% wrapperfooter box %}
    </div>
{% endwrapperfooter %}

在要素 Twig 文件中,使用包装器:
{% wrapper box %}
This is my content
{% endwrapper %}

以下扩展名有3个问题:
  • 无法在Twig环境中存储数据(例如上下文变量)。因此,当您定义{% wrapperheader NAME %}时,基本上没有干净的方法来检查是否已定义NAME的 header (在此扩展中,我使用静态属性)。
  • 当您对 Twig 文件进行include时,将在运行时而不是立即对其进行解析(我的意思是,将在执行生成的文件时解析包含的 Twig 模板,而不是在解析include标记时解析)。因此,当您解析{% wrapper NAME %}标记时,无法知道先前包含的文件中是否存在包装器。如果您的包装器不存在,则此扩展名仅显示{% wrapper %}{% endwrapper %}之间的内容,而无需任何通知。
  • 此扩展的想法是:当解析器遇到wrapperheaderwrapperfooter标签时,编译器将标签的内容存储在某处,以备将来与wrapper标签一起使用。但是, Twig 上下文作为副本而不是通过引用传递给{% include %}。因此,不可能将{% wrapperheader %}{% wrapperfooter %}信息存储在该上下文中,以用于更高级别的使用(在包含文件的文件中)。我也需要使用全局上下文。

  • 这是代码,请注意更改 namespace 。

    首先,我们需要创建一个扩展,它将为Twig添加新的 token 解析器。

    在包的services.yml中,添加以下行以激活扩展:
    parameters:
        fuz_tools.twig.wrapper_extension.class: Fuz\ToolsBundle\Twig\Extension\WrapperExtension
    
    services:
      fuz_tools.twig.wrapper_extension:
        class: '%fuz_tools.twig.wrapper_extension.class%'
        tags:
          - { name: twig.extension }
    

    在包中,创建一个Twig目录。

    创建以下Twig\Extension\WrapperExtension.php文件:
    <?php
    
    // src/Fuz/ToolsBundle/Twig/Extension/WrapperExtension.php
    
    namespace Fuz\ToolsBundle\Twig\Extension;
    
    use Fuz\ToolsBundle\Twig\TokenParser\WrapperHeaderTokenParser;
    use Fuz\ToolsBundle\Twig\TokenParser\WrapperFooterTokenParser;
    use Fuz\ToolsBundle\Twig\TokenParser\WrapperTokenParser;
    
    class WrapperExtension extends \Twig_Extension
    {
    
        public function getTokenParsers()
        {
            return array(
                new WrapperHeaderTokenParser(),
                new WrapperFooterTokenParser(),
                new WrapperTokenParser(),
            );
        }
    
        public function getName()
        {
            return 'wrapper';
        }
    
    }
    

    现在我们需要添加 token 解析器:我们的语法为{% wrapper NAME %} ... {% endwrapper %},与wrapperheaderwrapperfooter相同。因此,这些 token 解析器用于声明标签,检索包装程序的NAME以及检索正文(在wrapper和endwrapper之间)。

    包装器的 token 解析器:Twig\TokenParser\WrapperTokenParser.php:
    <?php
    
    // src/Fuz/ToolsBundle/Twig/TokenParser/WrapperTokenParser.php
    
    namespace Fuz\ToolsBundle\Twig\TokenParser;
    
    use Fuz\ToolsBundle\Twig\Node\WrapperNode;
    
    class WrapperTokenParser extends \Twig_TokenParser
    {
    
        public function parse(\Twig_Token $token)
        {
            $stream = $this->parser->getStream();
            $name = $stream->expect(\Twig_Token::NAME_TYPE)->getValue();
            $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
            $body = $this->parser->subparse(array($this, 'decideWrapperEnd'), true);
            $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
            return new WrapperNode($name, $body, $token->getLine(), $this->getTag());
        }
    
        public function decideWrapperEnd(\Twig_Token $token)
        {
            return $token->test('endwrapper');
        }
    
        public function getTag()
        {
            return 'wrapper';
        }
    
    }
    

    wrapperheader的 token 解析器:Twig\TokenParser\WrapperHeaderTokenParser.php:
    <?php
    
    // src/Fuz/ToolsBundle/Twig/TokenParser/WrapperHeaderTokenParser.php
    
    namespace Fuz\ToolsBundle\Twig\TokenParser;
    
    use Fuz\ToolsBundle\Twig\Node\WrapperHeaderNode;
    
    class WrapperHeaderTokenParser extends \Twig_TokenParser
    {
        static public $wrappers = array ();
    
        public function parse(\Twig_Token $token)
        {
            $lineno = $token->getLine();
            $stream = $this->parser->getStream();
    
            $name = $stream->expect(\Twig_Token::NAME_TYPE)->getValue();
            if (in_array($name, self::$wrappers))
            {
                throw new \Twig_Error_Syntax("The wrapper '$name''s header has already been defined.", $lineno);
            }
            self::$wrappers[] = $name;
    
            $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
            $body = $this->parser->subparse(array($this, 'decideWrapperHeaderEnd'), true);
            $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
            return new WrapperHeaderNode($name, $body, $token->getLine(), $this->getTag());
        }
    
        public function decideWrapperHeaderEnd(\Twig_Token $token)
        {
            return $token->test('endwrapperheader');
        }
    
        public function getTag()
        {
            return 'wrapperheader';
        }
    
    }
    

    wrapperfooter的 token 解析器:Twig\TokenParser\WrapperFooterTokenParser.php:
    <?php
    
    // src/Fuz/ToolsBundle/Twig/TokenParser/WrapperFooterTokenParser.php
    
    namespace Fuz\ToolsBundle\Twig\TokenParser;
    
    use Fuz\ToolsBundle\Twig\Node\WrapperFooterNode;
    
    class WrapperFooterTokenParser extends \Twig_TokenParser
    {
    
        static public $wrappers = array ();
    
        public function parse(\Twig_Token $token)
        {
            $lineno = $token->getLine();
            $stream = $this->parser->getStream();
    
            $name = $stream->expect(\Twig_Token::NAME_TYPE)->getValue();
            if (in_array($name, self::$wrappers))
            {
                throw new \Twig_Error_Syntax("The wrapper '$name''s footer has already been defined.", $lineno);
            }
            self::$wrappers[] = $name;
    
            $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
            $body = $this->parser->subparse(array($this, 'decideWrapperFooterEnd'), true);
            $this->parser->getStream()->expect(\Twig_Token::BLOCK_END_TYPE);
            return new WrapperFooterNode($name, $body, $token->getLine(), $this->getTag());
        }
    
        public function decideWrapperFooterEnd(\Twig_Token $token)
        {
            return $token->test('endwrapperfooter');
        }
    
        public function getTag()
        {
            return 'wrapperfooter';
        }
    
    }
    

    token 解析器检索所有必需的信息,我们现在需要将这些信息编译为PHP。该PHP代码将由Twig_Template实现内的twig引擎生成(您可以在缓存目录中找到生成的类)。它在一种方法中生成代码,并且所包含文件的上下文不可用(因为上下文数组不是由引用给出的)。这样,如果没有全局上下文,就不可能访问包含文件中的内容。这就是为什么我在这里使用静态属性...一点都不好,但是我不知道如何避免使用它们(如果您有想法,请让我知道!:)。

    包装标签的编译器:Twig\Nodes\WrapperNode.php
    <?php
    
    // src/Fuz/ToolsBundle/Twig/Node/WrapperNode.php
    
    namespace Fuz\ToolsBundle\Twig\Node;
    
    class WrapperNode extends \Twig_Node
    {
    
        public function __construct($name, $body, $lineno = 0, $tag = null)
        {
            parent::__construct(array ('body' => $body), array ('name' => $name), $lineno, $tag);
        }
    
        public function compile(\Twig_Compiler $compiler)
        {
            $compiler
               ->addDebugInfo($this)
               ->write('if (isset(\\')
               ->raw(__NAMESPACE__)
               ->raw('\WrapperHeaderNode::$headers[')
               ->repr($this->getAttribute('name'))
               ->raw('])) {')
               ->raw("\n")
               ->indent()
               ->write('echo \\')
               ->raw(__NAMESPACE__)
               ->raw('\WrapperHeaderNode::$headers[')
               ->repr($this->getAttribute('name'))
               ->raw('];')
               ->raw("\n")
               ->outdent()
               ->write('}')
               ->raw("\n");
    
            $compiler
               ->addDebugInfo($this)
               ->subcompile($this->getNode('body'));
    
            $compiler
               ->addDebugInfo($this)
               ->write('if (isset(\\')
               ->raw(__NAMESPACE__)
               ->raw('\WrapperFooterNode::$footers[')
               ->repr($this->getAttribute('name'))
               ->raw('])) {')
               ->raw("\n")
               ->indent()
               ->write('echo \\')
               ->raw(__NAMESPACE__)
               ->raw('\WrapperFooterNode::$footers[')
               ->repr($this->getAttribute('name'))
               ->raw('];')
               ->raw("\n")
               ->outdent()
               ->write('}')
               ->raw("\n");
        }
    
    }
    

    wrapperheader标记的编译器:Twig\Nodes\WrapperHeaderNode.php
    <?php
    
    // src/Fuz/ToolsBundle/Twig/Node/WrapperHeaderNode.php
    
    namespace Fuz\ToolsBundle\Twig\Node;
    
    /**
     * @author alain tiemblo
     */
    class WrapperHeaderNode extends \Twig_Node
    {
    
        static public $headers = array();
    
        public function __construct($name, $body, $lineno = 0, $tag = null)
        {
            parent::__construct(array ('body' => $body), array ('name' => $name), $lineno, $tag);
        }
    
        public function compile(\Twig_Compiler $compiler)
        {
            $compiler
               ->write("ob_start();")
               ->raw("\n")
               ->subcompile($this->getNode('body'))
               ->write(__CLASS__)
               ->raw('::$headers[')
               ->repr($this->getAttribute('name'))
               ->raw('] = ob_get_clean();')
               ->raw("\n");
        }
    
    }
    

    wrapperfooter标签的编译器:Twig\Nodes\WrapperFooterNode.php
    <?php
    
    // src/Fuz/ToolsBundle/Twig/Node/WrapperFooterNode.php
    
    namespace Fuz\ToolsBundle\Twig\Node;
    
    class WrapperFooterNode extends \Twig_Node
    {
    
        static public $footers = array();
    
        public function __construct($name, $body, $lineno = 0, $tag = null)
        {
            parent::__construct(array ('body' => $body), array ('name' => $name), $lineno, $tag);
        }
    
        public function compile(\Twig_Compiler $compiler)
        {
            $compiler
               ->write("ob_start();")
               ->raw("\n")
               ->subcompile($this->getNode('body'))
               ->write(__CLASS__)
               ->raw('::$footers[')
               ->repr($this->getAttribute('name'))
               ->raw('] = ob_get_clean();')
               ->raw("\n");
        }
    
    }
    

    现在可以执行了。试试吧!

    创建一个名为wrappers.html.twig的 View :
    {# src/Fuz/LayoutBundle/Resources/views/Default/wrappers.html.twig #}
    
    {% wrapperheader demo %}
    HEAD
    {% endwrapperheader %}
    
    {% wrapperfooter demo %}
    FOOT
    {% endwrapperfooter %}
    

    创建一个名为您想要的 View 。html.twig:
    {# src/Fuz/HomeBundle/Resources/views/Default/index.html.twig #}
    
    {% include 'FuzLayoutBundle:Default:wrappers.html.twig' %}
    
    {% wrapper demo %}
    O YEAH
    {% endwrapper %}
    

    这显示:

    HEAD O YEAH FOOT

    关于php - 如何包装HTML代码而不在Twig中包含新文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15997320/

    有关php - 如何包装HTML代码而不在Twig中包含新文件?的更多相关文章

    1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

      我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

    2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

      总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

    3. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

      我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

    4. ruby - 其他文件中的 Rake 任务 - 2

      我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

    5. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

      我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

    6. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

      关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

    7. ruby-on-rails - Rails 3 中的多个路由文件 - 2

      Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

    8. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

      给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

    9. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

      我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

    10. ruby - 将差异补丁应用于字符串/文件 - 2

      对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

    随机推荐