WordPress.org

Make WordPress Core

Opened 5 years ago

Closed 4 years ago

#11517 closed enhancement (maybelater)

Make Admin more MVC-like

Reported by: filosofo Owned by: filosofo
Milestone: Priority: normal
Severity: normal Version: 3.0
Component: Administration Keywords:
Focuses: Cc:

Description

I brought this up in the October 15, 2009 #wordpress-dev IRC chat as a 3.0 feature I'd like to see implemented.

Current Problems

Currently, most of the admin markup is hard-coded, with controller, model, and view all tangled up. Functionality used in multiple places is replicated in each of those places. And there's no API for plugins to generate admin-theme-specific markup, such as tables of data: for most cases plugins are forced to replicate markup based on observation.

My General Proposal

Instead, WordPress would be improved if:

  • Admin functionality were not unnecessarily duplicated. This is a long-standing principle of software development known as "DRY" or "Don't repeat yourself."
  • Plugins could be agnostic about the particular markup of their admin pages. By using an API for displaying their data or settings forms, plugins wouldn't have to make admin markup and style changes to match different WP admin environments.
  • Admin markup were more "themeable." It would be helpful if plugins or themes were able to generate their own markup for common admin elements.

This would involve a massive change in the WP admin pages, so I'm not sure what the best approach is to getting something like this implemented. Creating a patch would be a waste of time as it would grow stale almost immediately.

How I think we should approach this

My idea currently is to implement this as a plugin, a plugin that provides a parallel admin framework to the current admin system. Then it would still be of use even without being committed to core and yet still demonstrate the main ideas.

Concerns voiced during the IRC chat

Here are some of the concerns that were raised in the dev IRC chat, followed by my responses:


making the admin area truely themable would add a TON of code

Yes, there's no doubt about it. However, in the end there would be less code to maintain, because less functionality would be duplicated.


we still need to be as light and fast as possible and avoid over engineering

True. I have a couple of thoughts about this:

  • First, the admin is currently very slow. Not because of the PHP but because of all the CSS and JavaScript being loaded and processed. A themeable admin would allow people to develop admin "themes" that, for example, don't use certain CPU-hogging JS libraries.
  • Second, the time difference between printing hard-coded markup in the admin and using an API instead is negligible. And with a decent caching system, it's possible that the API route would be faster, because e.g. one function for printing tables would be stored in memory instead of a dozen different approaches.


Wouldn't abstracting the html creation make it a lot harder to change the UI in the future?

No. In fact the opposite is true. For example, if someone wanted to change the markup of those tables displaying data, currently she would have to grep through the code looking for every place it's used. With my approach, the markup would be changed in only one place.


[It] Would mean we have to stay back-compat with tons of stuff ... and what happens when the admin UI replaces that table with a list for example?

This is a reasonable concern, because something like this could happen were the themeable admin done in the wrong way.

For example:

wrong approach:

function print_table_of_data($data) {

better approach:

function print_data($data) {

The problem with the "wrong" approach is that it provides a public API method for a particular markup result. The second approach is a better name for a public API method because it allows those calling it to be agnostic about the particular markup that implements it. So the concern I'm responding to here would be in play only if we don't decouple the markup from the public API.


well... think it would add a lot of back-compat work in most cases

For core, there would be very little back-compat work, if any. If---as the core currently does---you fail to have a public API, you don't have to worry about supporting that API in the future. :)

For plugins that want to support older versions of WP, it would be as simple as checking for the existence of the API objects.


how hard is it to write few table rows when needed ?

If, for example, I want a table of data that is similar in markup and styling to the edit posts table, I have to apply class names like "alternate," "status-draft," "iedit", "check-column," "post-title," "column-title," and I have to add attributes such as "valign" and child elements such as <span>, <strong>, and <div> in the right places.

And there's no guarantee that any of it will be similar in the next major WP release; to work nicely across versions I have to figure out all the different approaches in past versions of WP.

As a plugin author I would rather not have to parse any of that.


I think the problem will come when someone creates options, and WP_Forms drops them in a table, then the author includes a bit of JS, to make things fancy, which queues off the table. If we switch to a list in the future their JS doesn't work. As it is, if the admin section moves options to lists this authors plugin just still uses a table and still works

If the plugin's JavaScript is tightly coupled to the markup, then the plugin author should probably not use a markup-agnostic way of generating that markup.

So my questions for you, dear ticket readers:

  • What are the objections, if any, that you have to the idea?
  • Do you have any particular recommendations for implementing it? For example, is there some sort of framework you've used to decouple data and presentation that you think would be a helpful model here?
  • Would anyone be interested in helping me write the code that implements this?

Change History (36)

comment:1 @scribu5 years ago

  • Type changed from defect (bug) to enhancement

I like the ideea. The only concern that seems valid to me is the last one, related to JavaScript enhanced elements.

The closest example of something like this that I know of is the form generator in Habari.

I would be willing to help write the code for this.

PS: How would this work in a plugin?

comment:2 @demetris5 years ago

  • Cc dkikizas@… added

One thought and one suggestion from me:

First, if something like the proposed API is an improvement, then core will benefit from it too. (That is, the benefit will not accrue only to theme/plugin authors.) In that case, it should not be built as a plugin, but be part of the core.

(And if it’s not a good idea, it should not be built at all.)

Second, I suspect there are experienced plugin developers that would be willing to help, but I don’t know if these developers follow trac tickets. So, if it is decided to put the idea into practice, maybe an announcement on some other channels would be helpful.

Personally, I like the idea (I’m writing this as I’m taxing my eyes and my brain trying to figure out how to build a very simple options page), and I would be happy to help with testing.

comment:3 @hakre5 years ago

Just some stuff for the theme (view) part:

  • Pager to be used for Info and error messages #11515
  • Lists
  • Paginators / Page 1 2 3 >
  • Formular Manager for all those forms
  • Screen-Options (Drop-Down Panes on Top) #9657
  • The Menu
  • Tabs on admin pages (No concept here until today; Many Plugins / Theme Config-Pages need that)

Where to find code for this? I think partially in plugins maybe, yes. But. If you want this already solved, just checkout some of the more popular PHP Frameworks, they ship with all such stuff. You find multiple APIs not only for MVC but you can checkout various concepts for Formular Managers as well.

comment:4 @hakre5 years ago

Related: #11545

comment:5 @hakre5 years ago

Related: #11474 - Add validation error reporting system to Settings API (ticket looks like a concept paper as well)

comment:6 follow-up: @jeremyclarke5 years ago

  • Cc jer@… added

I really like this idea in general and think its the right direction for the admin going forward. It would have the effect of forcing core devs to clean up their act when they add stuff, using/augmenting existing output functions as needed and adding new ones when they are missing. Having the core devs think of plugin authors when creating UI is good both so they can be leaders in all WP UI development and so that the value of their work can be multiplied when used by people extending WP. Lets face it: Most people don't have the time/skill/enthusiasm for UI that leads to beautiful useful easy-to-use tools. Making a beautiful table just a function and a few paremeters away greatly increases the likelihood of plugins having a good tabular interface.

I'm not sure I understand the backwards-compatibility problems except for the obvious hump of initial pickup. All existing plugins that duplicate admin functionality would continue to work with the current setup. Of course as the admin changes those old plugins that don't use the proposed API would slowly get uglier and less useful, but that would happen anyway. If this API is available the authors will convert to the new system and hopefully their problems will go away from there on. The net difference of switching to a system like this is that some people will be able to avoid UI rot while those who enjoy reverse-engineering HTML using Firebug will still be able to do so. The only difference for the reverse-engineers, whethey they do it cause they dont' know any better or because they have special needs, will be that the tables/lists etc they copy will be more consistent with each other than ever.

Also this example of switching from a table to a list seems like it might be off-base. If the display of some particular kind of data by core changed then it would just use the display function for the new display type without affecting plugin uses of the old display function.

If you were showing a list of link categories as a table :

wp_admin_table($link_categories, $args);

Then you'd switch it to the list function instead (while also modifying the $args to be whatever the list function requires to display the link_categories to your satisfaction):

wp_admin_list($link_categories, $args);

It seems to me this wouldn't break any existing uses of wp_admin_table() by plugins.

If a plugin is writing js/css targeted at core uses of these functions (like the table that lists posts) then the current system is certainly no better for them than the proposed API. Either way if the system changes the css/js will need to be updated.

comment:7 @hakre5 years ago

Already existing admin skin / theme scenario: #11232

comment:8 @Denis-de-Bernardy5 years ago

  • Cc Denis-de-Bernardy added
  • Keywords needs-patch added

comment:9 @mikeschinkel5 years ago

Big +1 on this idea.

I just spent tons (really, tons) of time writing an admin interface that copied the UI for link categories and it was a huge pain. I'd be happy to provide some refactored code if you think my code will be usable albeit I fear I don't yet know enough of the structure that you'd prefer, but if so let me know.

Also I have several thoughts regarding the admin that comes to mind:

1.) Would it be possible to refactor the menu and submenu function to receive only one parameter being an associative array of the items needed by the functions rather than six ordinal parameters? It currently very hard to remember what parameters go in what order and makes the code very hard to follow. I think this could be done backwards compatibly.

2.) I found that admin pages in plugins behaved differently than admin pages in core. The problem is the core plugins get to run within their own php file under /wp-admin/%admin-page%.php whereas admin pages from plugins typically execute under /wp-content/plugins/%plugin%/%admin-page%.php or as /wp-admin/admin.php?page=%admin-page%. The flow of the former is very different and the flow of the latter is subtly different. Addressing this so it's not different would be a huge help.

3.) Which brings me to admin URL routing. I think item 2 could be resolved by routing clean URLs. I think routing clean URLs would also be helpful for more advanced users to be able to go directly to pages by selecting the URL from auto-complete (which I did frequently and really appreciated when I worked in Drupal.) For example, envision admin URLs like these:

http://example.com/wp-admin/posts/add-new/
http://example.com/wp-admin/appearance/themes/
http://example.com/wp-admin/users/your-profile/
http://example.com/wp-admin/tools/export/
http://example.com/wp-admin/settings/general/


comment:10 @mikeschinkel5 years ago

  • Cc mikeschinkel@… added

comment:11 @voyagerfan57615 years ago

  • Cc WordPress@… added

comment:12 @jfarthing845 years ago

  • Cc jfarthing84@… added

+1.

I don't care for creating custom admin themes, but an API to integrate into the existing admin design would be more than great. I have spent countless hours developing plugins that have to duplicate admin sections (which change frequently). Although time is money for me (and I an get paid more if it takes longer), I hate repeating myself and I like simplicity and consistency. Let's get this done!

comment:13 @jfarthing845 years ago

  • Cc jfarthing84@… removed

comment:14 @jfarthing845 years ago

  • Cc jeff@… added

comment:15 @nacin5 years ago

  • Milestone changed from 3.0 to Future Release

comment:16 @d6veteran5 years ago

Big +1. Would really help efficiency as a WP developer in order to supply the growing demand for custom admin themes and options.

comment:17 @hakre5 years ago

Another Admin Element worth of getting more modularized / "plugable": #9657

comment:18 @rspindel5 years ago

  • Cc rspindel added

comment:19 follow-up: @hakre5 years ago

Another one, "paging" missing on Links as well: #13849

Looks like it would save us a _lot_ of coding if all that could be streamlined.

comment:20 in reply to: ↑ 19 ; follow-up: @scribu5 years ago

Replying to hakre:

Another one, "paging" missing on Links as well: #13849

Looks like it would save us a _lot_ of coding if all that could be streamlined.

I'm in the process of streamlining all the list-type screens, as part of my GSoC project:

http://gsoc.trac.wordpress.org/log/2010/scribu

comment:21 in reply to: ↑ 20 @hakre5 years ago

Replying to scribu:

I'm in the process of streamlining all the list-type screens, as part of my GSoC project: http://gsoc.trac.wordpress.org/log/2010/scribu

Nice. It just came to my attention that there ain't no quickedit available for links as well. But I assume then you have that already on your list.

comment:22 @hakre5 years ago

Related: #14579

comment:23 in reply to: ↑ 6 @scribu5 years ago

  • Milestone changed from Future Release to 3.1

Current Problems

Currently, most of the admin markup is hard-coded, with controller, model, and view all tangled up. Functionality used in multiple places is replicated in each of those places. And there's no API for plugins to generate admin-theme-specific markup, such as tables of data: for most cases plugins are forced to replicate markup based on observation.

I've cleaned up most of that in #14579. Each list-type screen now has it's own class for displaying the table and related elements. All the classes descend from WP_Admin_Table, which can also be used by plugin authors to make their own screens.

So, I'm going to call this fixed.

comment:24 @scribu5 years ago

  • Resolution set to fixed
  • Status changed from new to closed

comment:25 @Denis-de-Bernardy5 years ago

I'm not entirely sure we can call this fixed. There's a huge difference between what we're currently doing in WP, and what one would do with a php framework. Literally copying what's functioning on my localhost:

*** config.php

Router::connect('/{:controller}/{:action}/{:id:[0-9]+}.{:type}', array('id' => null));

*** models/Post.php

class Post extends Model {
	public $validates = array(
		'title' => array(
			array('notEmpty', 'message' => 'Title cannot be empty'),
			),
	);
}

*** controllers/PostsController.php

class PostsController extends Controller {
	public function edit($id = null) {
		$id = (int)$id;
		$post = Post::find($id);

		if (empty($post)) {
			$this->redirect(array('controller' => 'posts', 'action' => 'manage'));
		}

		if ($this->request->data) {
			if ($post->save($this->request->data)) {
				$this->redirect(array('controller' => 'posts', 'action' => 'manage'));
			}
		}

		$title = 'Edit post';

		return compact('post', 'title');
	}
}

*** view/posts/edit.html.php (uses layout.default.php)

<?=$this->form->create($post, array('method' => 'post')); ?>
	<?=$this->form->hidden('id'); ?>
	<?=$this->form->field('title');?>
	<?=$this->form->field('body', array('type' => 'textarea'));?>
	<?=$this->form->submit('Edit Post'); ?>
<?=$this->form->end(); ?>

comment:26 @filosofo5 years ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

The phrase "such as tables of data" refers to one example. WP is nowhere near the general goal of this ticket.

Perhaps it should be closed as "won't fix," but it's nothing like "fixed."

comment:27 @filosofo5 years ago

  • Milestone changed from 3.1 to Future Release

comment:28 @scribu5 years ago

  • Keywords needs-patch admin-theme removed

I highly doubt the general goal of this ticket will ever be achieved either in a single version or as a plugin, since it would effectively mean rewriting half of WordPress.

It can remain open as a meta-ticket if you will, for tracking progress over time.

comment:29 @mikeschinkel5 years ago

+1 to leaving it open.

comment:30 @hakre5 years ago

There is not only traction into the direction to make the admin more modular, there is also movement against it. Features like #14696 do not remove but add complexity to the file-structure by introducing new directories and compexity to the URL layout for the same reason. Just for the note.

comment:31 follow-up: @johnjamesjacoby4 years ago

IMO the entire admin area is bad enough where the easiest way to accomplish this task would be to make a modular API and then work backwards into making each screen fit into it. Jane dones a great job at keeping the UI looking amazing and fresh but there are too many unique UI elements and too much custom CSS for specific screens to make this doable in 1 or even two release cycles.

If anyone wanted to take this on, in theory you could even start this as a plugin replacement for wp-admin, just as a proof of concept. All of the functions are in place to restrict access, build settings pages, and dynamically grab template files for on screen display. I'm sure if something got started that worked well, more people would invest time into it.

comment:32 in reply to: ↑ 31 @mikeschinkel4 years ago

Replying to johnjamesjacoby:

IMO the entire admin area is bad enough where the easiest way to accomplish this task would be to make a modular API and then work backwards into making each screen fit into it. Jane dones a great job at keeping the UI looking amazing and fresh but there are too many unique UI elements and too much custom CSS for specific screens to make this doable in 1 or even two release cycles.

+1

If anyone wanted to take this on, in theory you could even start this as a plugin replacement for wp-admin, just as a proof of concept. All of the functions are in place to restrict access, build settings pages, and dynamically grab template files for on screen display. I'm sure if something got started that worked well, more people would invest time into it.

I can't lead this but I'd be more than happy to help.

comment:33 @jltallon4 years ago

  • Cc jltallon added

Ok, I'll bite into the temptation.... trying to get something to scratch the itch with.
( related: #12718, #16342)

comment:34 @john316media4 years ago

  • Cc john316media added

+10 (can I do that?)

But seriously this would be perfect. To try to make my plugin admin screens looks WP-like I end up finding an existing admin screen that has the effect I'm looking for, such as the posts list for a table, then view that in a browser, copy the source into an HTML editor and try to clean out the header, footer, menu, then rename the columns and add the content, the code ends up looking like a frenkenstein mess but I get a WP-like layout at least. I would really like this but IMO this would literally take rewriting the entire admin interface. Start with developing the API framework then recreate each and every admin page using the framework. Much needed though IMO.

Version 0, edited 4 years ago by john316media (next)

comment:35 @scribu4 years ago

The list table API will hopefully be made public in WP 3.2.

Even before that, you still had some helper functions: get_column_headers(), print_column_headers() etc.

General comment (not particularly directed at john316media): If you're going to complain about the current implementation, at least take time to learn what's already there.

comment:36 @scribu4 years ago

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

Looking back at the comments made to this ticket, nothing useful has come out of it in 16 months.

Only impractical suggestions and a general disregard for existing APIs.

Closing.

Note: See TracTickets for help on using tickets.