WordPress.org

Make WordPress Core

Opened 3 years ago

Closed 8 months ago

Last modified 3 months ago

#18285 closed feature request (maybelater)

New Settings API and workflow

Reported by: nacin Owned by:
Milestone: Priority: normal
Severity: normal Version:
Component: Plugins Keywords: settings-api needs-patch
Focuses: Cc:

Description

A new Settings API should ideally be less painful.

That includes registration of options, creating fields and forms, and handling errors.

Quick suggestions, which Ryan and others can elaborate on, as well as offer justification for:

  • Stop using options.php as a POST handler.
  • Object-oriented approach, rather than passing handles around everywhere.
  • Should be flexible enough to leverage the new Settings API in the Network and User admins.
  • Form/field construction should be easy, and core should use it.
  • Core should also show/hide relevant fields based on the UI, perhaps with some sort of caps integration. Likewise, authorization for saving options should be incorporated beyond the sanitization callback.

Table markup should also be moved to CSS, which requires #16413 and core leveraging the fields API.

Anything that is not done, can be moved to 3.4. We should not rush this API, and we should be absolutely satisfied with it.

Attachments (10)

16413.class-wp-settings-page.diff (8.5 KB) - added by scribu 3 years ago.
Basic wrapper class + media settings page rework, as an example
18285.diff (18.4 KB) - added by ryan 3 years ago.
18285.2.diff (11.1 KB) - added by ryan 3 years ago.
options-media.php using existing core API
18285.3.diff (14.8 KB) - added by ryan 3 years ago.
options-media.php with no options.php, no options-head.php, and registering its own options.
options-media.php (7.9 KB) - added by ryan 3 years ago.
options-media.php using core API
extra-args.18285.diff (496 bytes) - added by scribu 3 years ago.
extra-args.18285.2.diff (1.3 KB) - added by scribu 3 years ago.
18356.2.diff (1.6 KB) - added by prettyboymp 3 years ago.
18285.4.diff (14.6 KB) - added by prettyboymp 3 years ago.
updates to current settings api to simplify field creation
test-settings.php (5.1 KB) - added by prettyboymp 3 years ago.
simple plugin to test the settings api changes

Download all attachments as: .zip

Change History (120)

scribu3 years ago

Basic wrapper class + media settings page rework, as an example

comment:2 aaroncampbell3 years ago

  • Cc aaroncampbell added

comment:3 prettyboymp3 years ago

  • Cc mpretty@… added

Here is a wrapper I wrote to simplify the headache of creating settings: https://github.com/prettyboymp/voce-settings-api. It isn't written in the usual way WordPress does things, and isn't a complete integration as it updates it calls update_option() directly, but I thought it may offer some useful insight.

One feature that is really helpful is that it allows for different plugins to share a page or even group (section) without interfering with each other. This allows us to add/remove/share modules without having dependencies or having to have multiple option pages.

Below is an example of how pages/groups/settings are added:

Voce_Settings_API::add_page( 'Blog Settings', 'Blog Settings', 'blog-settings' )
	->add_group( 'Related Story Feeds', 'related-story-feeds' )
		->add_setting( 'Related Videos Feed', 'related-videos', array('sanitize_callbacks' => array('plugin_sanitize_url_setting')) )
	->group
		->add_setting( 'Related Stories Feed', 'related-stories', array('sanitize_callbacks' => array('plugin_sanitize_url_setting')) );
Last edited 3 years ago by prettyboymp (previous) (diff)

comment:4 scribu3 years ago

Regarding form field construction, I have a class that does it, which looks like this:

scbForms::input( array(
  'type' => 'select',
  'name' => 'color',
  'values' => array(
    'white' => __( 'White' ),
    'green' => __( 'Green' ),
    ...
  )
) );

It can also generate radio buttons and checkbox groups, for multiple choice options.

More Examples | Source code

comment:5 follow-ups: nacin3 years ago

I'm only referring to field callbacks as they exist now. I strongly dislike form *field* construction. The best API for constructing fields is HTML.

comment:6 in reply to: ↑ 5 ; follow-up: prettyboymp3 years ago

Replying to nacin:

I'm only referring to field callbacks as they exist now. I strongly dislike form *field* construction. The best API for constructing fields is HTML.

While I agree with that, having simple built in form field callbacks helps save a lot of duplicate code across plugins. At the very least, a text input would be very helpful.

comment:7 WraithKenny3 years ago

  • Cc Ken@… added

comment:8 in reply to: ↑ 6 ; follow-up: scribu3 years ago

Replying to prettyboymp:

While I agree with that, having simple built in form field callbacks helps save a lot of duplicate code across plugins. At the very least, a text input would be very helpful.

It's a slippery slope. Even for a text input, you would still want to add a description, which would require a variable.

comment:9 in reply to: ↑ 8 prettyboymp3 years ago

Replying to scribu:

It's a slippery slope. Even for a text input, you would still want to add a description, which would require a variable.

That reminds me of another issue I have with the current settings API, which is the inability to pass any extra arguments back to the sanitize or display callbacks for registered settings, making it nearly impossible to reuse callback functions.

comment:10 scribu3 years ago

Good point. The callbacks should receive the appropriate data, even if we go the OO route.

comment:11 andrewryno3 years ago

  • Cc andrewryno@… added

comment:12 sabreuse3 years ago

  • Cc sabreuse@… added

comment:13 lumpysimon3 years ago

  • Cc piemanek@… added

comment:14 in reply to: ↑ 5 mikeschinkel3 years ago

Replying to nacin:

I strongly dislike form *field* construction. The best API for constructing fields is HTML.

In general I agree that creating PHP wrappers for HTML just makes implement HTML forms complicated, but there is usually a lot more to managing data entry fields than just their HTML layout.

FWIW, I've been working on exactly this problem on and off for the past 6+ months, and it's a rather hard problem to tackle. I'll be releasing what I'm working on to beta hopefully within 30 days with a goal of launching as a community plugin within 90-120 days. I can give anyone interested access to it in alpha now. Because of the scope of doing this in a manner than is flexible enough for most needs I doubt anything substantial and robust could be built in time for 3.3, or even 3.4. Maybe the core team can learn from any architecture errors I may make that are uncovered over the next year?

Last edited 3 years ago by mikeschinkel (previous) (diff)

comment:15 mikeschinkel3 years ago

  • Cc mikeschinkel@… added

comment:16 jjeaton3 years ago

  • Cc jjeaton added

comment:17 chipbennett3 years ago

  • Cc chip@… added

ryan3 years ago

comment:18 follow-up: ryan3 years ago

Just to see what it looks like, I took prettyboymp's API and made options-media.php work with it. I had to s/admin_init/admin_head/ to get it working, which won't play nicely with plugins.

comment:19 in reply to: ↑ 18 westi3 years ago

Replying to ryan:

Just to see what it looks like, I took prettyboymp's API and made options-media.php work with it. I had to s/admin_init/admin_head/ to get it working, which won't play nicely with plugins.

Interesting.

I don't particularly like how this works :)

I think the first step here should be to take our current procedural api and flesh our a design for how we could extend it to provide the functionality we need.

Then we can look at implementation choices (OO/Globals/...) that make the best sense.

I think we can have a strong API which allows you to build flexible settings pages without overloading our memory usage with large objects or overly populates globals.

comment:20 westi3 years ago

Also to me both patches on this ticket seem to completely miss the issue here and put a lot of effort into wrapping the current api in something "Easier" to use rather than actually improving the API itself.

comment:21 ryan3 years ago

Easy is part of the point. The current API is fairly abominable to use.

That said, I think some of these other APIs try to do too much. Part of that is because the current core API sucks so much. Things we should consider up front:

Don't run code on every admin page load that doesn't need to be run. The only thing that needs to run on init/admin_init is the registration of the sanitize callback (and cap callback if we add that). We need to separate registering these callbacks from registering UI related stuff. A single "setting" in the UI is often multiple options in the db. Some of these APIs don't offer this flexibility.

Move away from options.php. Make it easy for pages to handle their own posts. We could possibly get rid of the whole notion of registering which options a page can handle if we do this. Each page knows what options it should handle. This might allow us to un-API some things.

comment:22 follow-up: ryan3 years ago

We need register_option(). This would look much like register_meta() and live in wp-includes/functions.php with the other *_option() functions. Plugins would call this during init so that their options always have sanitization registered in case XML-RPC or other places manipulate the option.

If we lose options.php there is no need to keep a big list of what is registered for each page. Each page will have their own POST and XHR handlers and will know what options it deals with.

This leaves Sections and Settings within the Sections. Something like prettyboymp's API seems fine for this. I would probably lose the *_menu_page() level stuff. I think that should be done separately and section and settings should be registered in response to the page load hook for the desired page being fired.

comment:23 in reply to: ↑ 22 scribu3 years ago

Replying to ryan:

I would probably lose the *_menu_page() level stuff. I think that should be done separately and section and settings should be registered in response to the page load hook for the desired page being fired.

The thing is that *_menu_page() is exactly the function that returns the name of the hook that could later be used to register the settings and sections for that specific page.

comment:24 ctsttom3 years ago

  • Cc me@… added

comment:25 kovshenin3 years ago

  • Cc kovshenin@… added

comment:26 rzen3 years ago

  • Cc rzen added

Hey Guys, I'm really excited about the direction this is taking! I hear nacin saying he doesn't want to handle field generation, but I think standardizing that (while still allowing for custom callback registration) is a very smart way to go.

I'm lazy, so last year I built an Options API for StartBox that leverages the Settings API and handles option registration, sanitization, builds the form element, and saves the option. In it's current form, like scribu's class, it can register a whole slew of field types and uses the admin.css.

Currently, all options in the page get stored to a single serialized array, and there are helper functions to interact with that data as though it were a stand-alone option in the options table. There are functions for adding/removing an entire metabox of options and adding/removing individual options as well. It even allows you to register the metabox to other pages (but they'll only work on my admin page currently).

I don't think it's a perfect solution for this yet, but I think it would serve as a great launching point. I'd love to help however I can to roll this idea into core (even if this code is irrelevant). Ptah's WPFramework does some similar things, maybe better, so maybe even a hybrid of the methods could be a good route.

You can Download StartBox from Github -- all the Options API stuff lives in /includes/functions/admin_settings.php, and gets put to work in /includes/functions/admin/...

Looking forward to what you guys think.

comment:27 Mordof3 years ago

  • Cc Mordof added

Really interested to see where this goes. Will check it out soon - I had to use the Settings API recently and was not happy with it. I made a class which, like the other simple ones that were mentioned, just takes care of things and makes it easier.

Just throwing out there how I had done it quickly in case it might help anyone. register_section is also available with an id and description field, then under register_option another optional argument is the section id so they can be grouped.

It's very very basic, doesn't include styling options.. Anyway It may not help much or at all, but whatever comes from this ticket I'm sure will be worth the wait :)

$args=array(
	"page_title"=>"Theme Options",
	"menu_title"=>"Theme Options",
	"settings_description"=>"Options specific to the Home Page"
);

$ops=new Settings('homepage_options', $args);

$ops->register_option('homepage_slide_count',"Homepage Slide Count",
  "<input id='%id%' name='%name%' size='2' type='text' value='%value%' />");

comment:28 Bueltge3 years ago

  • Cc frank@… added

ryan3 years ago

options-media.php using existing core API

ryan3 years ago

options-media.php with no options.php, no options-head.php, and registering its own options.

ryan3 years ago

options-media.php using core API

comment:29 ryan3 years ago

That's what options-media.php looks like when it uses all of the core settings API and does its own POST and error handling instead of using options.php and options-head.php. _admin_init() is a special function that core admin files can define before loading admin.php so that they can queue up actions on admin_init like plugins can. options-media.php uses this to make sure the core settings sections and fields are registered before plugins.

Last edited 3 years ago by ryan (previous) (diff)

comment:30 hameedullah3 years ago

  • Cc hameedullah added

comment:31 F J Kaiser3 years ago

  • Cc 24-7@… added

comment:32 Tyrun3 years ago

  • Cc Tyrun added

comment:33 nerrad3 years ago

  • Cc nerrad added

comment:34 swissspidy3 years ago

  • Cc hello@… added

comment:35 destastic3 years ago

  • Cc dcox@… added

comment:36 simonlawrence3 years ago

  • Cc simonlawrence added

comment:37 alex-ye3 years ago

  • Cc nashwanco_001@… added

comment:38 kurtpayne3 years ago

  • Cc kurtpayne added

comment:39 jamalorg3 years ago

  • Cc jmlworld@… added

comment:40 garinungkadol3 years ago

  • Cc garinungkadol added

scribu3 years ago

comment:41 scribu3 years ago

extra-args.18285.diff is a very simple patch that passes $section and $page to the callback, allowing for greater re-usability.

Note that the callback already receives a list of args that can be set using add_settings_field().

scribu3 years ago

comment:42 scribu3 years ago

extra-args.18285.2.diff also passes the field id, which is actually the most interesting.

comment:43 goto103 years ago

  • Cc dromsey@… added

comment:44 jkudish3 years ago

  • Cc joachim.kudish@… added

prettyboymp3 years ago

comment:45 prettyboymp3 years ago

Sorry, 18356.2.diff is from a different ticket I was working on.

prettyboymp3 years ago

updates to current settings api to simplify field creation

prettyboymp3 years ago

simple plugin to test the settings api changes

comment:46 prettyboymp3 years ago

attachment:18285.4.diff contains changes to the current settings to help simplify settings field creation.
attachment:test-settings.php is an example plugin that uses the altered API.

It hasn't been tested much for backwards compatibility at this point. I wanted to get something up to work from.

It adds the ability for different plugins to re-use pages, sections, and fields without interfering with each other, allows plugin pages to handle their own post backs and simplifies the ability to reuse field creation and sanitation functions.

comment:47 ciobi3 years ago

  • Cc ciobi added

comment:48 GaryJ3 years ago

  • Cc gary@… added

comment:49 WraithKenny3 years ago

A major short coming of the old api was that you can pass a only single capability, say unfiltered_html, to the add_*_page functions, but that wouldn't matter (or make sense) since it posted to options.php with a hard-coded manage_options check (plus an is_super_admin for multisite). These API's should work together.

It might be nice to do capabilities checks in save_settings_page() based on what's passed to add_*_page for plugins. (Separate issue: add_*_page functions could be enhanced to handle an array of capabilities rather then just a single capability.) The options-media example doesn't register pages in the same way as a plugin would, so perhaps call a function that handles this, and have save_settings_page call it too.

As another test case, we could look at custom-background.php and custom-header.php as examples closer to how plugins and themes would use the API and what it's short comings (if any) are, as well as a good future in-core code example of how to use it.

comment:50 WraithKenny3 years ago

I'd like to make a case for some default, generic form element generation. A few optional "template tags" for option pages would be cool. The templates could live in a file somewhere by itself to be included if wanted.

As a theme/plugin developer, sometimes I just want to use what ever flavor of markup and style core is currently using for the admin. Hunting down class-names and such in Firebug aside, this markup and style may change in future versions, and as long as the default markup/style was optional/over-writable, I don't see it as a problem.

Additionally, generic tags for simple text fields could have some safe easy optional default sanitation callbacks and output escaping. Remember, no one has to use them if they'd rather do it themselves. (If it's too hard, no one uses sanitation/escaping, and that's no good.)

Potential list could include things like the new HTML5 types: email, url, number, range, date, color, time, etc., as well as other typical ones like Name, Phone Number, Address, Post-like Content (textareas which uses the appropriate kses automatically), and the generic ones, Select, Checkbox, Radio, etc. These functions could create the markup and style to match the standard admin uniformly, as well as apply a fallback sanitation callback and escaping appropriate for each one.

These things would make it easier on everyone, but no one would be required to use them. If you have a special use-case, by all means, roll your own! But they'd be great to have and maintained somewhere central.

We can't cover all cases. These functions could also provide a code example for developers attempting to write their own.

To summarize:

  1. markup and style uniformity with core
  2. default data sanitation, validation and/or escaping handled
  3. template/example for rolling custom ones
  4. really convenient.

comment:51 F J Kaiser3 years ago

@WraithKenny +1 for template tags and template-able option pages. One imo important thing would be that those template tags could have an additional callback parameter to override their behavior (like if the callback would hook into a filter). Another thing I want to mention are "shared" option pages. In detail: In some cases you don't have hundreds of options and therefore you don't need 10 option pages, but only a single one - with let's say 15 options. Now 5 of those options are better off when they are only viewable by the developer and the other 10 are meant to get set by the owner/client who wants - of course - have an administrator account. If we would have a capability per field, we could use custom capabilities to show all fields only to the developer and the rest to the "public" majority. Sure, we can still do this in for example an options template, but having the capability check built in right into the field the process would be much more seamless.

comment:52 danielbachhuber3 years ago

  • Cc wordpress@… added

comment:53 ctsttom3 years ago

Is this ticket still active?

comment:54 nacin3 years ago

  • Keywords 3.4-early added
  • Milestone changed from 3.3 to Future Release
  • Type changed from task (blessed) to feature request

Not for 3.3. Moving to 3.4.

comment:55 ctsttom3 years ago

I'm not being funny here but what features have made it to 3.3 as it seems like there isn't much on first look?

I hope I am wrong.

comment:56 andrewryno3 years ago

Nothing from this ticket made it into 3.3.

comment:58 johnbillion3 years ago

  • Cc johnbillion@… added

comment:59 Tyrun3 years ago

  • Cc Tyrun removed

comment:60 holizz3 years ago

  • Cc tom@… added

comment:61 studiograsshopper3 years ago

  • Cc studiograsshopper added

comment:62 azizur3 years ago

  • Cc azizur added

comment:63 deanmarktaylor2 years ago

  • Cc deanmarktaylor added

comment:64 pauldewouters2 years ago

  • Cc pauldewouters added

comment:65 marfarma2 years ago

  • Cc pauli.price@… added

comment:66 casben792 years ago

  • Cc bcasey@… added

comment:67 johnnytee2 years ago

  • Cc johnnytee added

comment:68 mercime2 years ago

  • Cc mercijavier@… added

comment:69 jeremyclarke2 years ago

  • Cc jer@… added

comment:70 bluesplinter2 years ago

  • Cc steve@… added

comment:71 CaptainN21 months ago

HTML is the best place to define forms, and with HTML5, it's a pretty good place to set basic validation as well.

I've been playing with this idea, where we'd spec out a form in HTML tags, and then create the corresponding PHP form elements from parsing that, and even wire up the _POST handler to do the basic validation (ranges, email, color picker, etc.) A system like that could validate any HTML5 form field type marked as required automatically when the form comes back to the server, eliminating a huge pain point for forms handling in general (and a pain point WordPress's Setting's API passes on to plugin and theme developers). Using HTML5 form spec provides a nice predefined scope, so we don't have to go crazy. WordPress could seemingly also be wired up automatically from that.

This would involve the overhead of parsing HTML on the server, but we could probably minimize that by only parsing single fields (except with select boxes).

Here's a quick example, of what this could look like as an implemented form:

<?php
// This would actually call `myForm` function and capture the output, and parse the HTML
// before passing the HTML right into the output. Each tag call is a chance to register
// and validate the form data and type, and set necessary data, like filtering the
// value attribute to prefill submitted data, and overwrite the default value, etc..

// could be extended with WP API stuff
$form1 = new Form( 'myForm', 'my_wp_setting' );

if ( $form1->isSubmitted )
{
	if ( $form1->isValid ) {
		// Store the validated form data, or maybe do nothing!
		// WordPress could actually do the saving automatically.
	}
	else {
		// might not have to do anything!!
		// wordpress could also wire up the settings errors
	}
}
?>
<html>
<head>
<title>Example Form</title>
</head>

<body>
<?php

function myform() { ?>
<?php tag( '<form action="./" method="post" name="form1">' ); ?>

<div>
<?php tag(' <input type="email" name="user_email" required placeholder="Enter your email address"> ') ?>
</div>

<div>
<?php tag(' <input type="email" name="some_field_name" placeholder="Enter your email address"> ') ?>
</div>

<?php tag(' </form> ') ?>

<?php } // myform

$form1->output();

?>
</body>
</html>

With this there is no limitation on how you structure your own HTML - it's all just plain old HTML (well, mostly). There may be other ways to encapsulate the HTML - for example - parsing an entire form all at once instead, or by using a similar function trick for each tag, but this seemed like a nice light way to go.

What's cool about that, is you can define the form as HTML, in place in the document. PHP functions are hoisted, so you can register the form in the head, and do the input validation there. This ends up being pretty DRY - you define your form, your input types, and your validation all inside the form (without limiting your layout options) just the one time, and then all the wiring can be done automatically. WordPress setting registration, section and field registration, error handling, can also all be wired up automatically from the form spec.

(Separate note: It would be nice to add to the setting API support for arrays of data - maybe a register_setting_group method or something. Registering a separate setting for each field seems like too much in many cases, where serialized array data would be enough.)

Maybe this could be useful enough even outside of WordPress to go ahead and make it work - maybe wrap Scribu's lib. :-)

comment:72 scribu21 months ago

Implementing an HTML parser instead of using explicit parameters doesn't seem like a good idea.

Anyway, a more nimble approach: #21488

comment:73 CaptainN21 months ago

Even if a parser already exists: http://code.google.com/p/ganon/

It even seems to preserve my source formatting to an extent.

comment:74 CaptainN21 months ago

  • Cc CaptainN added

I made a proof of concept (check out the examples/BasicForm.php page):

https://github.com/adcSTUDIO/OnceForm

Personally, I think that's pretty spiffy. I'll probably build off of this further to throw some proofs together that can automatically wire up settings, custom post types, or other meta data stuff in WordPress.

I should be able to replace the boilerplate for almost the full turnaround - start by defining the fields as HTML5 (with requirements and validation), set some variables for metadata names (and groupings), and then just let the WPOnceForm handle the form postback, the sanity/security/validation, and store the data - all of that almost completely automatic, driven off of an HTML5 form template.

comment:75 CaptainN21 months ago

I just added a DynamicForm.php example file, which shows how to make a OnceForm from a string. This enables existing functions like add_settings_fields and whatnot to be used to construct a form, and then pass that through OnceForm to get the automatic request handling. With some imagination, you can see how WPOnceForm (no proof yet) could automatically save changes to settings from these forms without piles of boilerplate.

https://github.com/adcSTUDIO/OnceForm/blob/master/examples/DynamicForm.php

comment:76 unknowndomain20 months ago

  • Cc unknowndomain added

Hey folks,

I know a lot of people follow this ticket, I have been a regular proponent for this issue for over a year now. I am keen to see this worked on but a lot of the issues at the core of this haven't been resolved, such as whether to use a HTML parser or not, this issue is also holding up implementation of the API but also implementation of the API in the back end (wp-admin).

I'd like to help, I can't program all that well however perhaps I can help to coordinate some how? In that mindset, please could folks reply to show interest in helping with the development, and perhaps we can organise a meeting to discuss this, also would be nice to have someone who knows the community better than I who can suggest how we reach consensus and move this ticket on.

I look forward to everyones replies.

Tom

comment:77 bpetty20 months ago

  • Cc bpetty added
  • Keywords needs-patch added

Related: #9296 (in reference to lack of flexible API for custom permalink settings)

Leaving "needs-patch" since this appears to be an approved feature/improvement that needs to be done at some point, but no final/production patches have been attached for review.

comment:78 mordauk20 months ago

  • Cc pippin@… added

comment:79 CaptainN20 months ago

Quick update if anyone is interested - I added a WP_OnceForm base to the repo:
https://github.com/adcSTUDIO/OnceForm/blob/master/WP_OnceForm.php

This automatically adds an nonce field to any form, and validates the request. I also reduced the PHP requirements (I was relying on ganon's use of php's magic invoke method, which only works on php 5.3 previously, but I changed it so it works on WP's target php version).

Last edited 20 months ago by CaptainN (previous) (diff)

comment:80 ctsttom20 months ago

  • Keywords 3.4-early removed

Would be nice of someone could mark this with keyword 3.6-early.

Last edited 20 months ago by ctsttom (previous) (diff)

comment:81 jaredatch19 months ago

  • Cc jared@… added

comment:82 CaptainN18 months ago

Quick update: I changed the parser for OnceForm from Ganon to DOMDocument, which uses 1/5 the memory, and substantially reduces the code base.

comment:83 maor18 months ago

  • Cc maorhaz@… added

comment:84 nvwd18 months ago

  • Cc nowell@… added

comment:85 sennza18 months ago

  • Cc bronson@… added

comment:86 alexmansfield17 months ago

  • Cc alex@… added

comment:87 maxmaeteling17 months ago

  • Cc maxmaeteling added

comment:88 emzo17 months ago

  • Cc wordpress@… added

comment:89 knutsp17 months ago

  • Cc knut@… added

comment:90 unknowndomain17 months ago

  • Keywords settings-3.6 added; needs-patch removed

comment:91 SergeyBiryukov16 months ago

  • Keywords settings-api added; settings-3.6 removed

comment:92 bpetty16 months ago

  • Keywords needs-patch added

comment:93 unknowndomain15 months ago

I think #15691 should be built into this to allow a setting to have a scope, i.e. where it's preferred storage is, network level or blog level. This way it solves #15691 and keeps plugin code simple, removing all the is_multisite() calls and duplicate code for handling storage of settings for network pages.

comment:94 slbmeh14 months ago

  • Cc steve@… added

comment:95 zamoose14 months ago

  • Cc zamoose@… added

comment:96 toscho11 months ago

  • Cc info@… added

comment:97 sunnyratilal11 months ago

  • Cc sunnyratilal5@… added

comment:98 dway11 months ago

  • Cc nicolasderambure@… added

comment:99 atimmer9 months ago

  • Cc atimmermans@… added

comment:100 wycks9 months ago

  • Cc bob.ellison@… added

comment:101 sunnyratilal9 months ago

  • Cc sunny@… added

comment:102 cfoellmann8 months ago

  • Cc foellmann@… added

comment:103 nacin8 months ago

  • Milestone Future Release deleted
  • Resolution set to maybelater
  • Status changed from new to closed

This ticket has been dragging on for a long time. Ultimately, Trac is best for implementation of things, not for having a ticket rot until someone proposes a great API for something we're not even sold on replacing, or with what. Thanks prettyboymp and others for contributing some ideas here. While there is some clear support in a better API, we don't know what that looks like yet. And that's OK — maybe in a few months we can revisit this and start with an API design brainstorming session or something.

I do like ericlewis's WP_Meta_Box work in #18179, which I think could actually be adapted in such a way to bridge (to some extent, in terms of authorization/sanitization/saving given register_setting() and register_meta()) these two form-building APIs. Something else to look into would be the API surrounding the customizer, which was brought into core back in 3.4 (back when this ticket was first proposed). Maybe there is even a way for all of these settings-related pieces to have some kind of unified foundation. Without bringing some sanity to all of these related areas, I'm not sure a rewrite is worth the headache.

Closing as maybelater. If there is any future activity on this on make.wordpress.org/core or elsewhere, can someone please cross-post here in order to update the many, many people CC'd here.

comment:104 ericlewis7 months ago

I made WP_Settings_Page the other day. Obviously nothing new, really just an OOP wrapper for dealing with the Settings API, but a step forward.

comment:105 CaptainN7 months ago

I know this ticket is old. Here is a quick example of what WP_MetaForm can do:

<?php
$post_type = 'my_cpt';
$post_meta_prefix = '_my_cpt_';

add_action('init', function () use ( $post_type, $post_meta_prefix ) {

        $metaform = new WP_MetaForm(
                array(
                        'prefix'    => $post_meta_prefix,
                        'label'     => 'Discount Info',
                        'post_type' => $post_type
                ), 'My_Form_Callable'
        );

        $post_args = array(
                'label'       => 'My CPT',
                'labels'      => array(
                        'name'               => _x('My CPTs', 'Terminal Design My CPTs'),
                        'singular_name'      => _x('My CPT', 'post type singular name'),
                        'add_new'            => _x('Add New', 'book'),
                        'add_new_item'       => __('Add New My CPT'),
                        'edit_item'          => __('Edit My CPT'),
                        'new_item'           => __('New My CPT'),
                        'all_items'          => __('My CPTs'),
                        'view_item'          => __('View My CPT'),
                        'search_items'       => __('Search My CPTs'),
                        'not_found'          => __('No My CPTs found'),
                        'not_found_in_trash' => __('No My CPTs found in Trash'),
                        'parent_item_colon'  => 'My CPT: ',
                        'menu_name'          => 'My CPTs'
                ),
                'description'  => '',
                'public'       => false,
                'show_ui'      => true,
                'show_in_menu' => true,
                'hierarchical' => false,
                'supports'     => array( 'title' ),
                'rewrite'      => array( 'slug' => 'my-cpt' ),
                'register_meta_box_cb' => array( &$metaform, 'metabox' )
        );

        register_post_type( $post_type, $post_args );
});

function My_Form_Callable() { ?>
<div method="post">
<label>Enter a custom value
<input type="text" name="custom_key" required></label>
<label>Enter another custom value
<input type="text" name="another_custom_key"></label>
</div>
<?php
}

That's all it takes to create a custom post type with a custom form in a meta box. The form defines the meta keys (one per input), and defines which fields are required, validates all the post data according to the declared validation rules (as much as is supported by OnceForm) and sanitizes the inputs (at least that's the idea - I don't have test coverage on that yet), and saves everything in to the appropriate place in the database without having to write a ton of boilerplate. IT also prefixes the meta keys if you want to use a prefix.

That's a meta box demo, but I'd guess a Settings page could be done as easily.

A big part of what it seems the Settings API does is just puts together HTML that matches the admin - but my sense is that would be much easier to just grab a template, edit in the fields you want, and then throw it at OnceForm. No need for complicated layout code, just write the HTML - much easier.

If interested:
https://github.com/adcSTUDIO/WP-OnceForm

comment:106 Messenlehner5 months ago

  • Cc Messenlehner added

comment:107 rachelbaker5 months ago

  • Cc rachel@… added

comment:108 tott5 months ago

  • Cc thorsten@… added

comment:109 nofearinc5 months ago

  • Cc mario@… added

comment:110 ircbot3 months ago

This ticket was mentioned in IRC in #wordpress-dev by dabar. View the logs.

Note: See TracTickets for help on using tickets.