How to add a class to a html element using filters

2019-06-01 01:40发布

I am changing the current theme of my blog and I wish to add a class to all my input fields.

I am not well versed with regex codes, so I end up in a lot of trouble whenever I need to make things like these happen.

type="submit"

I want to add class btn needs to be added to <input type="submit">

Old Code

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

New Code

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

and

Similarly, I want the class input to be added to <input type="text"> and <input type="textarea">

Old Code

<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" />

New Code

<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" />

4条回答
闹够了就滚
2楼-- · 2019-06-01 01:59

I answered above, and I would simply edit that one but its already received votes, and this answer will be significantly different.

After some comments in my initial answer, I realized that the input fields @Aniket wants to change are not within the content, they are elements throughout the site, such as in widgets, and in the templates themselves.

There is no way through hooks, actions, or filters, to modify the code thats written within the theme templates. Filters can modify strings and values, but only if there is a hook already available to do so. You don't have this, so its not possible. Your only option for adding this class dynamically without editing the input fields is to use javascript. This however is pointless for two reasons.

  1. It would be simpler to just edit the input fields themselves
  2. You dont need to add these classes, because CSS lets you select those elements in other ways.

You dont need to add an 'input' class to input fields.

CSS allows you to select elements by the tag name, so for example if you wanted to select any div, you dont need add a ".div" class to every div. You can select all div's by simply using "div" without any class or ID notation.

The same applies to textareas. You said you wanted to add an input class to textareas, text fields, and submit buttons, but thats not necessary. You can select all those using CSS attribute selectors. In this case, were going to specify input fields with the attribute submit, and text, as well as textarea elements stead of the two classes you wanted to add.

Instead of adding a .btn class to submit buttons, use...

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

And instead of adding an .input class to text fields and textareas use...

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

Alternatively, if you just want all input fields, not just text areas and text fields use...

input {
   /* Your styles */
}

Even if you did this though javascript, you would end up having to select these elements using this kind of CSS selection anyway, and any regex you could possibly do would be significantly more complicated than these simple lines.

查看更多
爷的心禁止访问
3楼-- · 2019-06-01 02:04

If I understand your question correctly, you want to dynamically apply classes to input elements. What you need to use is a filter, or a series of filters.

First let me explain how filters work. Filters work with 'hooks' just like Actions. See the Actions and Filters codex page for details.

It sounds like you want to use hooks to add this btn class without needing to manually change each input. Thats not how hooks work. To use hooks for this you would use filters, which would mean you would need to write...

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

You would then be able to add a filter to the 'input_class' tag.

add_filter('input_class', 'btn_class_filter');

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

Whatever your function returns will replace the default value - in this case 'some-default-class' will be replaced with 'btn'.

However none of this eliminates the need to add code to each input field you want to add the class. The only way to do that, would be through javascript, most easily with jQuery. I know you said you didn't want to use jQuery, but if you dont want to edit markup, thats your only option.

The simplest thing to do would be to just add the btn class manually - if its a matter of access, the jQuery will be the way to go.

查看更多
▲ chillily
4楼-- · 2019-06-01 02:11

If you're just applying blanket style rules to these elements and don't care about IE6 support, why not just use attribute selectors in your CSS, eg

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

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

FYI, there is no <input type="textarea">, just <textarea>

To manipulate markup using a hook would be time consuming and clumsy. You'd need to grab all template output as well as plugin generated markup. I'd recommend not attempting this, Wordpress code is messy enough.

查看更多
Emotional °昔
5楼-- · 2019-06-01 02:17

Given your constraints, the cleanest way you can do what you want with PHP and stay within the Wordpress framework is to use DOMDocument. While it's POSSIBLE to rely on regular expressions, it's very sloppy and you can run into more problems than what you started with.

Place this in your functions.php file, and it should do everything you need:

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
}
查看更多
登录 后发表回答