WordPress / gutenberg

The Block Editor project for WordPress and beyond. Plugin is available from the official repository.
https://wordpress.org/gutenberg/
Other
10.51k stars 4.2k forks source link

Add .wp-element-button class to Login/out form button output #50466

Open bgardner opened 1 year ago

bgardner commented 1 year ago

Description

To remain consistent and provide theme authors the ability to style all types of buttons in theme.json elements, I recommend adding the .wp-element-button class to the output of the Login/out block. When that block is placed onto a page, and the Settings > Display login as form is selected, the output of the button is:

<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary" value="Log In">

Ideally it would have .wp-element-button class applied like the output of the button on the Post Comments block:

<input name="submit" type="submit" id="submit" class="wp-block-button__link wp-element-button" value="Post Comment">

Resulting in something like this:

<input type="submit" name="wp-submit" id="wp-submit" class="button button-primary wp-element-button" value="Log In">

Additionally, the name/ids in both blocks might want to be consistent. Either "submit" or "wp-submit".

Step-by-step reproduction instructions

  1. Go to page editor, add Login/out form block.
  2. See output of button class.

Screenshots, screen recording, code snippet

No response

Environment info

WordPress 6.2, Gutenberg not active.

Please confirm that you have searched existing issues in the repo.

Yes

Please confirm that you have tested with all plugins deactivated except Gutenberg.

Yes

richtabor commented 1 year ago

Yikes, this form is rough all around. But yes, I agree with you here.

CleanShot 2023-05-09 at 15 52 03
t-hamano commented 1 year ago

I am wondering if it would be possible to apply the basic style to the input fields as well as the comment form, as shown below:

after

justintadlock commented 1 year ago

Was just coming here to report this. Aside from recreating the button styles, I copied over this code from the default comments form inputs and applied it:

.wp-block-loginout form input:not([type=submit]):not([type=checkbox]):not([type=hidden]) {
    box-sizing: border-box;
    display: block;
    width: 100%;
}
richtabor commented 1 year ago

We'd need to be able to add a class to the submit in wp_login_form(), then use wp_theme_get_element_class_name( 'button' ) like the post-comments-form does (but that's not possible in core).

You can currently set an ID, but not a class. I don't think we'd want to write to login_form_bottom, right?

justintadlock commented 1 year ago

It looks like login_form_bottom just appends HTML to the bottom of the form. The other consideration would be the HTML tag processor, but it doesn't currently support nested tags.

We probably need a default $args parameter we can pass in to avoid trying to hack it in via regex.

justintadlock commented 9 months ago

Had some time to tinker with this today and came up with a solution for adding the .wp-element-button class to the submit input/button.

Note that this is running on WP 6.5/trunk and Gutenberg 17.7, and I haven't tested down to WP 6.4:

add_filter('render_block_core/loginout', 'prefix_render_loginout', 10, 2);

function prefix_render_loginout(string $content, array $block): string
{
    if (
        empty($block['attrs']['displayLoginAsForm'])
        || is_user_logged_in()
    ) {
        return $content;
    }

    $processor = new WP_HTML_Tag_Processor($content);

    if (
        $processor->next_tag([ 'class_name'=> 'login-submit'])
        && $processor->next_tag('input')
    ) {
        $processor->add_class(wp_theme_get_element_class_name('button'));
    }

    return $processor->get_updated_html();
}

I don't think the tag processor can target something like the name or id attributes of an <input> element, so my code attempts to find the wrapping <p class="login-submit"> first. Then, targets the first <input>. I wouldn't normally like targeting the first <input> there, but it doesn't look like the wp_login_form() final output can be filtered before it gets to the block, so I feel like it should be reliable. Could definitely use some testing.

justintadlock commented 8 months ago

Updated solution (props to @dmsnell for showing me how to do an advanced query here):

add_filter('render_block_core/loginout', 'prefix_render_loginout', 10, 2);

function prefix_render_loginout(string $content, array $block): string
{
    if (
        empty($block['attrs']['displayLoginAsForm'])
        || is_user_logged_in()
    ) {
        return $content;
    }

    $processor = new WP_HTML_Tag_Processor($content);

    while ($processor->next_tag()) {
        if (
            'INPUT' === $processor->get_tag()
            && 'wp-submit' === $processor->get_attribute('name')
        ) {
            $processor->add_class(wp_theme_get_element_class_name('button'));
            break;
        }
    }

    return $processor->get_updated_html();
}
carolinan commented 3 months ago

Is anything blocking this from being submitted as a PR? or is there an unlinked PR already?

t-hamano commented 3 months ago

I don't think there is a PR linked to this issue, but I think we need to look into how to solve this problem.

The fundamental problem is that this block uses the wp_login_form() function for rendering, and the wp_login_form() function does not have an option to assign a class name to the submit button.

I think a few approaches could be:

carolinan commented 3 months ago

I don't mind the HTML tag processor suggestion, but in my opinion the most flexible solution for theme developers would be

carolinan commented 3 months ago

This trac ticket feels relevant for adding an option for a class name https://core.trac.wordpress.org/ticket/39927

carolinan commented 3 months ago

Using the form blocks for the login form is not an option until these are stabilized.

t-hamano commented 3 months ago

In this issue, is it expected that the wp-element-button class will be added to classic themes as well? In other words, should the wp-element-button class be applied to the Submit button by default when the wp_login_form() function is used in a theme template?

Don't use the wp_login_form() function, create our own HTML for the block

I don't intend to use the form blocks for the Login/out block. I intend to output the exact same HTML that the wp_login_form() function would output, via the render_callback function.

A little off topic, but I thought it would be nice to have an option to temporarily switch the logged-in state on the block editor. Currently, only the text "Log out" is displayed and it is not possible to switch to a form:

image