【问题标题】:How to add a class to a html element using filters in WordPress?如何使用 WordPress 中的过滤器将类添加到 html 元素?
【发布时间】:2012-05-15 04:06:03
【问题描述】:

我正在更改我博客的当前主题,并希望在我的所有输入字段中添加一个类。

我不精通正则表达式代码,所以每当我需要让这些事情发生时,我都会遇到很多麻烦。

type="提交"

我要添加类btn需要添加到<input type="submit">

旧代码

<input type="submit" id="some_id" name="something" class="some_class" value="some_value" />

新代码

<input type="submit" id="some_id" name="something" class="btn some_class" value="some_value" />

同样,我希望将 input 类添加到 &lt;input type="text"&gt;&lt;input type="textarea"&gt;

旧代码

<input type="text" id="some_id" name="something" class="some_class" value="some_value" />
<textarea id="some_id" name="something" class="some_class" value="some_value" />

新代码

<input type="text" id="some_id" name="something" class="input some_class" value="some_value" />
<textarea id="some_id" name="something" class="input some_class" value="some_value" />

【问题讨论】:

  • @thecodeparadox jQuery 是最简单的解决方案。但我希望使用 WP Hooks 来完成这项工作。
  • 您希望钩子以何种方式参与其中。 jQuery 或 CSS 可用于根据您显示的内容选择这些元素,但您是在谈论想要创建自己的钩子,这将允许您使用该钩子动态地将类添加到任何元素?
  • @eddiemoya 你让我明白了。是的,我想为元素动态添加类。
  • @Aniket 当你添加了你想要的类后,你打算用它做什么?它是用于 CSS 还是您有其他用途?
  • @maiorano84 即使我同意你的想法。这对于客户端脚本来说是非常正确的。你不能相信它有很多责任。但他们肯定会来救援。就像他们说的 - “绝望的时代,绝望的措施”。

标签: php regex wordpress


【解决方案1】:

鉴于您的限制,您可以使用 PHP 做您想做的事情并保持在 Wordpress 框架内的最简洁的方法是使用 DOMDocument。虽然可能依赖正则表达式,但它非常草率,而且您可能会遇到比开始时更多的问题。

把它放在你的functions.php文件中,它应该会做你需要的一切:

add_filter('the_content', 'add_text_input_classes', 20);
function add_text_input_classes($content)
{
    $doc = new DOMDocument(); //Instantiate DOMDocument
    $doc->loadHTML($content); //Load the Post/Page Content as HTML
    $textareas = $doc->getElementsByTagName('textarea'); //Find all Textareas
    $inputs = $doc->getElementsByTagName('input'); //Find all Inputs
    foreach($textareas as $textarea)
    {
        append_attr_to_element($textarea, 'class', 'input');
    }
    foreach($inputs as $input)
    {
        $setClass = false;
        if($input->getAttribute('type') === 'submit') //Is the input of type submit?
            $setClass = 'btn';
        else if($input->getAttribute('type') === 'text') //Is the input of type text?
            $setClass = 'input';

        if($setClass)
            append_attr_to_element($input, 'class', $setClass);
    }
    return $doc->saveHTML(); //Return modified content as string
}
function append_attr_to_element(&$element, $attr, $value)
{
    if($element->hasAttribute($attr)) //If the element has the specified attribute
    {
        $attrs = explode(' ', $element->getAttribute($attr)); //Explode existing values
        if(!in_array($value, $attrs))
            $attrs[] = $value; //Append the new value
        $attrs = array_map('trim', array_filter($attrs)); //Clean existing values
        $element->setAttribute($attr, implode(' ', $attrs)); //Set cleaned attribute
    }
    else
        $element->setAttribute($attr, $value); //Set attribute
}

【讨论】:

  • 这是我想要的,但代码肯定是草率。我将使用 jQuery 来完成这项工作。感谢您的回答。这就是我一直在寻找的。​​span>
  • 正则表达式说得好。它们不应该用于它们不是为它们设计的东西! (比如这个)。
  • 这实际上并没有解决问题,他的问题有点模糊。他所说的更改元素不在 the_content 中,而是在他的模板和小部件中。没有过滤器,他只需要使用其他一些 CSS 选择器或编辑他的主题。
  • @eddiemoya Anika 在评论中表示(我相信你的回答)他想加入 the_content。此示例基于该语句,并表明总有一种更有效的方法来解析 HTML 而不使用 Regex。对于小部件,他想添加一个“widget_text”过滤器。对于他的模板,他必须手动添加它们。因此,正如他所说,这确实解决了他的问题,因为他希望看到一个基于 PHP 的示例,说明如何使用过滤器来完成。
  • 我明白了,我以为他看到了你的解决方案,然后问我。无论如何,他后来解释说,他的输入字段不是帖子的一部分,而是在模板和小部件本身中。如果它们是小部件内容的一部分,他可以使用 widget_text,但我怀疑它们可能只是嵌入到代码中的元素。无意冒犯@Aniket,但他似乎对“the_content”是什么以及钩子的一般工作方式有非常错误的理解。
【解决方案2】:

如果我正确理解您的问题,您希望将类动态应用于输入元素。您需要使用的是一个过滤器,或一系列过滤器。

首先让我解释一下过滤器的工作原理。过滤器与“钩子”一起使用,就像操作一样。有关详细信息,请参阅Actions and Filters 法典页面。

听起来您想使用挂钩来添加此btn 类,而无需手动更改每个输入。这不是钩子的工作方式。要为此使用钩子,您将使用过滤器,这意味着您需要编写...

<input type="submit" class="<?php echo apply_filters('input_class', 'some-default-class'); ?>" />

然后您就可以将过滤器添加到“input_class”标签。

add_filter('input_class', 'btn_class_filter');

function btn_class_filter($default){
    return 'btn';
}

无论您的函数返回什么都将替换默认值 - 在这种情况下,“some-default-class”将替换为“btn”。

但是,这一切都消除了向要添加类的每个输入字段添加代码的需要。做到这一点的唯一方法是通过 javascript,最容易使用 jQuery。我知道你说过你不想使用 jQuery,但如果你不想编辑标记,那是你唯一的选择。

最简单的做法是手动添加 btn 类 - 如果是访问问题,那么 jQuery 将是可行的方法。

【讨论】:

  • 所以不可能创建一个将使用the_content() 的正则表达式替换函数然后为我进行更改?
  • 是的,如果输入元素在帖子内容中,您可以过滤 the_content 并使用正则表达式添加 btn。您没有在上面指出输入字段在帖子中。是这样吗?
  • 输入字段不在帖子中,而是来自小部件和一些表单模板。
  • 除非您使用 jquery,否则您无法在不编辑模板和小部件的情况下执行此操作。动作/过滤器需要一个钩子。我建议你修改模板来做你需要的事情,如果这些小部件不是你自己的,我建议你使用 jquery 来完成其余的工作。最后,我不明白为什么您实际上需要添加这些类。只需使用“textarea”选择器就可以选择文本区域,对于提交按钮“input[type=submit]”将起作用,同样可以使用“input[type=text]”选择文本字段。你不需要 .或 # 因为 css 允许您按元素名称进行选择。
  • 另外,我应该解释一下,the_content 及其相关过滤器只影响帖子内容中的数据,而不是模板或小部件。您将需要编辑您的模板和小部件,或者只使用更智能的 CSS。
【解决方案3】:

如果您只是对这些元素应用一揽子样式规则而不关心 IE6 支持,为什么不在 CSS 中使用属性选择器,例如

.btn, input[type="submit"] {
    /* styles for buttons */
}

.input, input[type="text"], textarea {
    /* styles for text inputs and textareas */
}

仅供参考,没有&lt;input type="textarea"&gt;,只有&lt;textarea&gt;

使用钩子操作标记既耗时又笨拙。您需要获取所有模板输出以及插件生成的标记。我建议不要尝试这个,Wordpress 代码已经够乱了。

【讨论】:

  • 很抱歉使用type="textarea"。应该使用&lt;textarea&gt;。因此,即使您不推荐 PHP 解决方案。明白了。
【解决方案4】:

我在上面回答了,我会简单地编辑那个,但它已经收到投票,这个答案会有很大的不同。

在我最初回答了一些 cmets 之后,我意识到 @Aniket 想要更改的输入字段不在内容中,它们是整个网站的元素,例如小部件和模板本身。

无法通过挂钩、操作或过滤器来修改主题模板中编写的代码。过滤器可以修改字符串和值,但前提是已经有可用的挂钩。你没有这个,所以不可能。在不编辑输入字段的情况下动态添加此类的唯一选择是使用 javascript。然而,这毫无意义有两个原因。

  1. 自己编辑输入字段会更简单
  2. 您不需要添加这些类,因为 CSS 允许您以其他方式选择这些元素。

您无需在输入字段中添加'input' 类。

CSS 允许您通过标签名称选择元素,例如,如果您想选择任何 div,则不需要为每个 div 添加".div" 类。您可以通过简单地使用"div" 来选择所有 div,而无需任何类或 ID 表示法。

这同样适用于文本区域。你说你想为文本区域、文本字段和提交按钮添加一个input 类,但这不是必需的。您可以选择所有使用CSS attribute selectors 的人。在这种情况下,将使用属性 submit 和 text 以及 textarea 元素指定输入字段,而不是您要添加的两个类。

不要添加 .btn 类来提交按钮,而是使用...

input[type="submit"] {
   /* Your styles */
}

而不是向文本字段和文本区域添加 .input 类,而是使用...

textarea, input[type="text"] {
   /* Your styles */
}

或者,如果您只想要所有输入字段,而不仅仅是文本区域和文本字段使用...

input {
   /* Your styles */
}

即使您通过 javascript 执行此操作,您最终也将不得不使用这种 CSS 选择来选择这些元素,并且您可能执行的任何正则表达式都将比这些简单的行复杂得多。

【讨论】:

  • 我知道 CSS 选择器是如何工作的,但是当你有四种选择器样式相同的东西时,更好的选择是继续使用它们的类,这样我的处理时间就会减少。
  • 嗯,你真的没有那个选项,而且处理时间的减少并不是很多,事实上它是完全无法衡量的。它涉及的角色很少。您可能使用的任何正则表达式或钩子都比简单地使用 CSS 的性能要差得多。毕竟这就是 CSS 要做的事情。如果您坚持必须添加这些类,那么这样做的唯一方法(特别是如果您担心性能)就是编辑模板。就是这样,没有办法绕过这两个 - 使用更好的 CSS,或者编辑你的模板。
  • 这现在被否决了,因为它不是您想要的答案,而是正确的答案。不,您不能使用过滤器更改分配给模板中标记的类。您必须使用智能 CSS,或编辑这些模板。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-12
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 2019-06-19
  • 1970-01-01
相关资源
最近更新 更多