Page MenuHomePhabricator

[Story] Put identifiers into separate section in the UI
Closed, ResolvedPublic

Description

Identifiers are currently mixed with other statements. This makes it harder to scan the statement section and find relevant information. As a reader I want to be able to scan an item page more easily.

  • We will achieve this by putting identifiers into a separate section below the statements section.
  • The separation happens based on the datatype.
  • The identifiers section is only shown when an identifier exists. The statement section is always shown.
  • Separation should also happen on property pages but based on the property of a statement there potentially.
  • It is possible to add an identifier in the statement section or vice versa. It will jump to the "right" section on page reload.
  • In the future suggestions based on correlation (the initial suggestions) should be tailored to the section. It should still be possible to type in a particular property's label and add it in whatever section. This is not part of the initial version and we will need to see what the feedback is like before moving forward.
  • All statements need to be shown somewhere in an item. The statements section is the catch-all. Each statement is only shown in one section. The first section in the config wins.

Related Objects

Event Timeline

Tobi_WMDE_SW raised the priority of this task from to Medium.
Tobi_WMDE_SW updated the task description. (Show Details)
Tobi_WMDE_SW set Security to None.
Tobi_WMDE_SW added subscribers: Zolo, Agabi10, DSGalaktos and 23 others.

I have some questions (@Lydia_Pintscher):

  • Does this apply for items and properties?
  • Where is this configured? I think this is very Wikidata-specific, and, as I mention frequently, such things should not go into Wikibase. Instead, Wikibase should be flexible enough to be configured properly.
  • Does this apply for items and properties?

It is really important for items because they are so convoluted. What do others think?

  • Where is this configured? I think this is very Wikidata-specific, and, as I mention frequently, such things should not go into Wikibase. Instead, Wikibase should be flexible enough to be configured properly.

Where is what configured? That this section exists? Or what it contains? We could show it only if statements with the identifier datatype exist?

Where is what configured? That this section exists? Or what it contains? We could show it only if statements with the identifier datatype exist?

Where is configured which statement sections exist and by which criteria statements are sorted into these sections?

Also, should you be able to add a new statement to both / all statement sections? With which properties?

As we distinguish identifier statements from "normal" ones, I guess we also need the entity suggester for properties to distinguish between those and support non-identifier data types in the normal section and only properties with the identifier data type in the identifier section.

@ items vs properties: do we actually have identifiers on properties? Anyways, I think doing this everywhere avoids special case handling and makes the whole thing more consistent.

do we actually have identifiers on properties?

I think so; for example, I would consider P​31’s equivalent property and source website for the property to be identifiers.

As we distinguish identifier statements from "normal" ones, I guess we also need the entity suggester for properties to distinguish between those and support non-identifier data types in the normal section and only properties with the identifier data type in the identifier section.

If we want to support adding statements to all sections (see my question above). Note that this would only apply to the property used in main snaks.

Notes taken during todays discussion

Will we ever have other sections? Possibly yes. Potential ideas for other statements sections:

  • All numeric values in a section.
  • All external references (Commons, URLs, item links) in a section.
  • Biographic data (born when and where and so on).
  • Meta information.

Sections based on what information?

  • Data type, e.g. "identifier". Warning, do not encode this as a string but as an array to allow, for example, ["url", "commonsMedia"].
  • A section based on a list of property ids.
  • Qualifiers, e.g. a section for "current" information. Warning, this means a property could be in multiple sections. Currently grouping by property is non-optional.

Note: The group configurations must have a defined order. The first group definition that matches a statement wins. The statement goes to this group. If no grouper matches the statement goes to the top default group.

UX implications are a bit scary:

  • When both suggesters are the same, you can add a property to the "wrong" section. It will stay there and "jump" to the other section when the page is reloaded.
  • What if each suggester only allows properties that belong to this section? This could cause major confusion, because the two sections are (in the current state where they are both in the left main column) almost identical.
  • What if there is no suggester in the identifiers section? No, there are to many properties, this needs a suggester.
  • What if there is only 1 add button (somewhere). Or an add button in each section headline that focuses a single "new statement" editor below all statement sections. The moment the new property is selected or the moment the new statement is saved the new statement could jump to the correct section. Or it could stay in it's "new statements" section and is reordered on reload.

Updated the description based on today's discussion.

What if each suggester only allows properties that belong to this section? This could cause major confusion, because the two sections are (in the current state where they are both in the left main column) almost identical.

I don't think this will cause lots of confusion as the two sections are clearly separated by a heading. It's rather intuitive that one can only add properties of the right type to a section, so I think this is the best approach for now. The property suggestion api would then need a parameter to filter which properties it should show.

I don't think this will cause lots of confusion as the two sections are clearly separated by a heading. It's rather intuitive that one can only add properties of the right type to a section, so I think this is the best approach for now. The property suggestion api would then need a parameter to filter which properties it should show.

If the sections are very long you might overlook that you skipped into another section. I'd especially expect people to just scroll to the bottom to add a statement. As for the property suggester change, this would not help if we would start grouping by anything else than property (data types).

I tried to break this down into tasks. Part 1 and Part 2 can be done in parallel, Part 3 needs all tasks from both Part 1 and Part 2 finished, Part 4 needs Part 3 done.

Part 1 (Preparation of Wikibase\View and Wikibase\DataModel\Services)

  • [Task] [PHP, view] Implement trivial Wikibase\View\StatementSectionsView sitting between PropertyView or ItemView and StatementGroupListView
    • [Task] [PHP, view] Pass section heading info from Wikibase\View\StatementSectionsView to Wikibase\View\StatementGroupListView
  • [Task] [PHP, datamodel services?] Implement StatementGrouper (StatementGrouper::groupStatements( StatementList ) -> StatementList[]) interface and trivial implementation SingleGroupStatementGrouper
    • [Task] [PHP, datamodel services?] Implement FilteringStatementGrouper( defaultGroup, StatementFilter[] )
    • [Task] [PHP, view] Use trivial StatementGrouper in StatementSectionsView (Also depends on StatementSectionsView)
  • [Task] [PHP, datamodel services?] Implement ByMainSnakPropertyDataTypeStatementFilter

Part 2 (Preparation of wikibase.view and jQuery.wikibase)

  • [Task] [JS, view] Implement wikibase.view.StatementSectionsView sitting between jquery.wikibase.propertyview or jquery.wikibase.itemview and jquery.wikibase.statementgrouplistview
    • [Task] [JS, view] Use wb-section-heading template in wikibase.view.StatementSectionsView
    • [Task] [JS, view or new datamodel-javascript-services] Implement StatementGrouper (StatementGrouper::groupStatements( StatementList ) -> StatementList[]) interface and trivial implementation SingleGroupStatementGrouper
      • [Task] [JS, view or new datamodel-javascript-services] Implement StaticStatementGrouper( defaultGroup, statementGuidToGroupHash )
      • [Task] [JS, view] Use trivial StatementGrouper in StatementSectionsView (Also depends on StatementSectionsView)

Part 3 (Tie stuff together)

  • [Task] [PHP and HTML, view] Adapt template so that it contains a list of statement sections (initially containing only one section, so that it won't break JS)
  • [Task] [PHP, repo] Pass section grouping of current statements in a JS config variable (wbStatementSections = [ { sectionKey: 'statements', statements: [ 'guid1', 'guid2', 'guid3' ] }, { sectionKey: 'identifiers', statements: [ 'guid4', 'guid5' ] } ])
  • [Task] [PHP and JS, view and repo] Inject StatementGrouper into StatementSectionsView through EntityViewFactory (PHP) / ViewFactory (JS)

Part 4 (Make stuff work)

  • [Task] [PHP, repo] Make the StatementGrouper passed into EntityViewFactory configurable
    • [Task] [PHP, operations/mediawiki-config] Configure StatementGrouper
  • [Task] [JSON, WikimediaMessages] Add wikibase-statementgroup-identifiers message so that it gets translated before deploying

Oh. I just realized that "statement group" is a fixed term in our code base, describing a set of one or more statements with the same property. Using this as an identifier for what @adrianheine calls "statement section" is confusing. Can you please edit your breakdown accordingly?

We are not sure why all the infrastructure is necessary in JavaScript. It seems redundant.

I think we could re-use and generalize that ›statement group‹ term if we would want to. It's only used in Wikibase view, Wikibase datamodel JavaScript and one location in Wikibase client. I have a hard time coming up with a better name for the general concept instead. We could use ›partition‹ instead, making the service class interface something like StatementListPartitioner, but that feels really awkward compared to StatementGrouper, considering that the latter is just a special case of the former.

As for the infrastructure in JS, it seems necessary for the approach I would take. The problem we need to solve in JS is that our views basically need two inputs: The data model object they are representing (this.options.value) and the DOM element they are working on (this.element[0]). These must match, obviously. Currently, we traverse the entity and the DOM and expect both to match. That's not completely wrong, but it's not so great either. Introducing multiple statement sections would be reflected in the DOM, but not in data model entity. So we need a way to order and group the data model data so that it matches the DOM. My proposal would be to do that in wikibase.view.StatementSectionsView using a StatementGrouper. So, StatementSectionsView would get the wikibase.datamodel.StatementGroupSet (basically a hash map from propertyId to StatementList) and build a list of StatementGroupSets using the StatementGrouper.

Another approach would be to ditch wbEntity, just follow the structure of the DOM and pass the editable data model objects in a flat structure, i. e. wbEntityStatements = { guid: wb.datamodel.Statement }. The statementview would then either fetch its Statement object from a store it got passed in using the guid that's represented somewhere in the DOM or some factory would inspect the DOM, grab the guid, fetch the Statement object and give it to the statementview. That's a quite some work to implement, would probably be a lot nicer, but would probably also mean that we won't be able to easily construct an entityview without DOM. Something we don't do anyway, currently. I'd prefer to not tie identifier sections to that change, if we actually want to do it, though.

What's wrong with StatementSectionView (singular, because it's for one section only), as already suggested? I suggest to simply stick to that.

The interface can be a general StatementGrouper, sure. If it's designed in a way that it could also support "group by property id" in the future, I do not have a problem with that.

(basically a hash map from propertyId to StatementList)

Isn't this, the "group statements by property id" part, a solved problem?

Another approach would be to ditch wbEntity, just follow the structure of the DOM

I would not like this for one reason: It will then be impossible (or at least much harder) to have statements in the JS view that are not in the PHP view (for example, deprecated statements could be hidden behind a "more" button).

After looking at https://gerrit.wikimedia.org/r/#/c/253912, I had the following thought:

I'm a bit unsure about the names and where the section title is rendered. In PHP, that's all pretty simple, but I would like PHP and JS to be consistent, and in JS things will be not so trivial.

In JS, an entityview will have a statementsectionsview which gets the whole statements dom and all the statements (currently a StatementGroupSet) from the entity. We could also call this view statementsview, since it does not matter to the entityview whether the statements are in sections or whatever. To the entityview, it's just the view handling the statements. I think I would like that.

The statementsview would group the statements and pass each (section) group to a statementsectionview, which would have the heading and a statementgrouplistview. All the statementsectionviews would be in a listview.

With that approach, StatementSectionsView should indeed be called StatementSectionView, and get only one section (key and statements) per getHtml call. I would then like to have a StatementsView in PHP, too, though. That StatementsView would do the grouping that's currently done in both ItemView and PropertyView and call out to the StatementSectionView.

What's wrong with StatementSectionView (singular, because it's for one section only), as already suggested? I suggest to simply stick to that.

The interface can be a general StatementGrouper, sure. If it's designed in a way that it could also support "group by property id" in the future, I do not have a problem with that.

It's a bit unclear to me what you are reacting to with this. I suppose it's about the naming problem with ›statement group‹ being used already? From my point of view, ›section‹ is a UI concept and not a data model concept. In the JS data model, we currently have StatementList, StatementGroup and StatementGroupSet. In PHP, we only have StatementList afaik. What we need to do now is grouping on two levels, so we will have a Set mapping from string to StatementGroupSet that in turn maps from string to StatementGroup, which is just a StatementList.

My proposal is that we introduce a StatementGrouper that takes a StatementList and returns a lot of StatementLists (mapped by string). As you pointed out, it would be a bit awkward to have an interface called StatementGrouper that doesn't use a StatementGroup, though. But since StatementGroup is currently limited to use the main snak's property id, we cannot just use it. So we either have to ignore the awkwardness I mentioned, or we change StatementGroup, or we use a different name. I wouldn't like the latter approach.

(basically a hash map from propertyId to StatementList)

Isn't this, the "group statements by property id" part, a solved problem?

Sure, that's a StatementGroupSet and StatementGroup. I didn't imply otherwise.

Another approach would be to ditch wbEntity, just follow the structure of the DOM

I would not like this for one reason: It will then be impossible (or at least much harder) to have statements in the JS view that are not in the PHP view (for example, deprecated statements could be hidden behind a "more" button).

I'm fundamentally opposed to removing things from PHP's HTML output. I'm happy to hide stuff using a CSS and JS combination, but I don't want to remove anything.

  • I was also thinking about a StatementsView just as you described, but it would be so simple (only two or three lines of code) that I decided to inline it into ItemView and PropertyView.
  • I do not really understand why a series of StatementSectionViews needs to be wrapped in an other view ("listview" in your comment). What does this give us? A StatementSectionView is a headline plus a StatementGroupListView. A series of StatementSectionViews is a series of alternating headings and StatementGroupListViews. Done. Please do not over-complicate straight structures.

Everything else in T117421#1820286 sounds fine to me.

What you write in T117421#1820306 confuses me or should not be discussed in this ticket. We all know that delivering 10 MB HTML to mobile devices is a problem. Hiding parts of it does not solve that.

  • I think the StatementsView will become a bit more complex as soon as it actually does the grouping. I'd like those (then) 5-10 lines not duplicated. That can be follow-up step, though.
  • The listview is a JS concept. I wouldn't use that in PHP. In PHP, StatementsView will do a simple foreach and call StatementSectionView::getHtml. In JS, we need a bit to do more with the list than just concatenate it, so we need to use the existing listview concept here.

Discussion between @Jonas and me led to taking another approach for the JS implementation. The idea is to remove explicit knowledge of ordering and grouping of statements from the JS code. Instead, for each statementview the GUID is taken from the DOM and used for fetching the wikibase.datamodel.Statement.

For the record, here's the outcome of some discussion we just had (Jonas, Thiemo, Lydia, Daniel, prompted by Adrian's comment on I5facc55342d):

  • Statement sections should be configurable.
  • Statement sections should be configurable per entity type.
  • Configuration should not contain PHP code, such as callback functions.

Proposed structure for the configuration:

	array( // entity types
		'item' => array( // sections
			'other' => null,
			'identifiers' => array(
					'type' => 'data-type',
					'data-types' => array( 'identifier' ),
			),
		),
		'property' => array(  // sections
			'constraints' => array(
				'type' => 'property-list',
				'properties' => array( 'P111' ),
			),
			'more' => null,
		),
	)
  • Statement sections should be configurable per entity type.

That seems to be unnecessarily arbitrary. People could also want to configure per namespace or whatever.

  • Configuration should not contain PHP code, such as callback functions.

That would mean that this is not actually configurable, since you can only use what your factory knows about. Also, it makes stuff hard to understand, since you have to use a format that's used nowhere else, has arbitrary limits on flexibility and is probably not going to be documented too well.

If we were to go with that configuration style, I'd want it to be in WikibaseRepo and not WikibaseView.

This is now fully implemented, but not yet live. Config patch is pending review: https://gerrit.wikimedia.org/r/#/c/263046/

Hi,

not sure if this is the right place, hopefully yes!

When I install a wikibase instance using the docker containers then the identifiers are not separated from the other statements. Is there some configuration needed? Why is this not automatic?

Thank you
D063520

The defaults include no statement sections, as they have not been requested for the default settings.
If you think a default wikibase install should some default sections then please file a separate ticket

The config you need is:

$wgWBRepoSettings['statementSections']

Which apparently is not well documented / documented at all in the options readme in the git repo.
I have created T240189: Document $wgWBRepoSettings['statementSections'] in /docs/options in Wikibase to add this documentation.

Some example config snippets can be seen at T123112
If you search for "wmgWikibaseRepoStatementSections" in https://noc.wikimedia.org/conf/InitialiseSettings.php.txt you can find the settings for production.