justintadlock / content-type-standards

WordPress community-curated standards for common post types, taxonomies, and metadata.
303 stars 28 forks source link

Locations standard #25

Open NateWr opened 9 years ago

NateWr commented 9 years ago

I'd like to open a discussion on the standards for a location post type. This post type would represent a physical location of some kind and would cater for business locations, outlets or venues (rather than, say, tracking the locations of incidents).

It would be intended for multi-location use-cases, where data is stored in post types, rather than a single-location use-case, where data might be stored in wp_options, for example.

I would suggest that data should as much as possible be designed with Schema.org markup strategies in mind. Where appropriate, metadata should conform to its parameters.

Post Type

location

Taxonomies

None specified at this time.

Metadata

Address

This meta key represents a human-readable postal address for the location and matches the WordPress standard. It may or may not contain line breaks (\r\b or <br>).

This meta key represents a latitude value which matches location_address and matches the WordPress standard. Google's geomapping API encourages you to store these values, rather than perform the lat/lon lookup on every request.

This meta key represents a longitude value which matches location_address and matches the WordPress standard. Google's geomapping API encourages you to store these values, rather than perform the lat/lon lookup on every request.

This meta key represents a human-readable phone number for the location.

This meta key represents a post ID where a visitor will find further details to contact the location, such as a contact form.

This meta key represents an email address for the location.

This meta key represents the hours of availability for the location.

This meta key represents a Schema type appropriate for this location.

NateWr commented 9 years ago

Above is a first-pass. I have a few questions I'd like to discuss and I'd like to hear from others on needs and use-cases this might or might not fit.

  1. I've noticed that other standards never serialize data in the post meta database. Is it a bad idea to do so? For instance, I've put the Latitude/Longitude into an array above. Should these instead be separate post meta values?
  2. What about searching? Since post meta is not very performant for lookups, we might want to store some data as taxonomies. _location_schema_type could be a good example of this. But I also imagine some important use-cases for efficient latitude/longitude lookups.
  3. The Opening Hours are the trickiest piece of data we have. Schema.org can only handle a weekly schedule so I suggest the standard impose the same limitation. What's the best way to store this information? Should it be an associative array with individual timing specifications, so that Schema.org openingHours can be quickly printed? Or should we store it differently and let plugins convert to their desired format at run-time? My one big concern is that it needs to support more than just a start and end time for each day of the week. A lot of businesses have split hours (open for lunch, then closed, then open for dinner) and this needs to be accounted for. I've found the following format works well for my [Business Profile]() plugin. It can accommodate very complex opening hours rules but is not that complex to work with and compile into a human-readable format.
Array
(
    [0] => Array
        (
            [weekdays] => Array
                (
                    [monday] => 1
                    [tuesday] => 1
                    [wednesday] => 1
                    [thursday] => 1
                    [friday] => 1
                )

            [time] => Array
                (
                    [start] => 11:00 AM
                    [end] => 9:00 PM
                )

        )

    [1] => Array
        (
            [weekdays] => Array
                (
                    [saturday] => 1
                )

            [time] => Array
                (
                    [start] => 6:00 PM
                    [end] => 10:00 PM
                )

        )

)
dmseaton commented 9 years ago

Serialising data is tempting because of the convenience but is horrendously inefficient to query and can open a can of worms if the data model changes down the line. Near enough every time I've used it it's come back to haunt me. Seems to me that storing individual values where possible is a cleaner and more practical way to handle things.

robneu commented 9 years ago

+1 for not serializing. I think most people who need this kind of functionality are going to want to be able to group locations based on their physical location, so getting the lat/long portion of this right is probably going to be one of if not the most important things to consider. The data should be easy to query to allow for complex templating and search indexing.

I also like the idea of taxonomies based on schema types, but I'm not sure how many types of websites would have a need for something like that. It could be useful in certain situations such as directory-style websites, although they've become a lot less common in recent years.

justintadlock commented 9 years ago

In terms of opening hours, don't worry about Schema markup. That's the markup, not the data. With properly-stored dates/times, you can output it however you need.

See this for a starting point when dealing with dates/times: https://github.com/justintadlock/content-type-standards/wiki/Post-Metadata:-Date-Time

AlchemyUnited commented 9 years ago

Shouldn't hours be tied to day of week. That is, Mon's hours are X to Y. And, depending on how far you want to take this there could be multiple time rows per day of week. For example, Lunch = 11am to 1.30 pm, Dinner = 4.30 pm to 8.30 pm; Bar Open at... Well you get the point.

While I don't want to derail things some might argue that time is it's own type / schema and should just be a partial (if you will) of this parent type.

AlchemyUnited commented 9 years ago

Phone is probably similar...

Catering: Justin T 911 555-1212 x123

Reservations: Bill 911 555-1212 x456

And so on.

AlchemyUnited commented 9 years ago

I'd also like to suggest adding image(s).

And is there a reason why Address is a single string?

What Address Notes? For example, an address in a city will sometimes have additional "between 1st and 2nd.." details.

NateWr commented 9 years ago

Thanks for the feedback on serialization. That makes sense. I've updated the specification above to separate latitude and longitude.

I think most people who need this kind of functionality are going to want to be able to group locations based on their physical location, so getting the lat/long portion of this right is probably going to be one of if not the most important things to consider. The data should be easy to query to allow for complex templating and search indexing.

It's my understanding that all postmeta is stored as a string so SQL > and < queries (for "nearby" queries) won't work. Is that right? I'm not sure if there is any solution to the query performance issue that doesn't require a custom database implementation, which I think is beyond the scope of this project. I would think that individual plugins could maintain a custom database table if they really needed high-performance lat/lon lookups. Although I'm certainly open to hearing creative solutions within the WP database schema.

I also like the idea of taxonomies based on schema types, but I'm not sure how many types of websites would have a need for something like that. It could be useful in certain situations such as directory-style websites, although they've become a lot less common in recent years.

Every local business (restaurants, hairdressers, tax accountants, etc) need the Local SEO benefits of schema markup for their locations, don't they?

See this for a starting point when dealing with dates/times

Thanks for the link @justintadlock . I'm definitely open to better solutions for storing the opening hours in the database. But as @AlchemyUnited, opening hours need to be tied to days of the week. Would you recommend a set of post meta like _location_opening_hours_monday, _location_opening_hours_tuesday, etc? We could then have multiple rows with the same meta_name for split opening hours (eg - Lunch/Dinner times).

Catering: Justin T 911 555-1212 x123 Reservations: Bill 911 555-1212 x456

I feel like a single phone number is sufficient for 95% of cases and so would make sense for definining the content standard. Each plugin can extend the standard however they'd like to support these kinds of special cases.

And is there a reason why Address is a single string?

IMHO, from an end user's perspective, I strongly favor a single, textarea input for human-readable addresses. There's just too much diversity in address norms across countries and end-users want to be able to describe their address in the terms they see fit.

I appreciate that there are some use-cases where a machine-readable address is worth the extra burden on the user. I'd suggest that the standard perhaps specify both a single human-readable address (string) and an option for machine-readable addresses. Each plugin can then implement one or both, and the standard makes it easier for compliant plugins to import data from one to the other (although of course it's easier to go in one direction than the other).

For machine-readable addresses, we'd need a set of post meta that was suitably international in scope. Not an easy task. We could take some inspiration from Schema.org's PostalAddress type. We should also keep in mind that some components of a machine-readable address (city, country) probably deserve to be taxonomies rather than post meta.

AlchemyUnited commented 9 years ago

In general I would think serialization would / could be optional. That is, it's only an issue when you need to query against values that are serialized.

i'd have to think about the _location_opening_hours_monday, _location_opening_hours_tuesday, etc but my gut first impression is probably not. These don't feel like something that should be hardcoded in that way.

re: "IMHO, from an end user's perspective, I strongly favor a single, textarea input for human-readable addresses. There's just too much diversity in address norms across countries and end-users want to be able to describe their address in the terms they see fit."

I understand but address is a fairly common sub-type (?). For example, it comes up on e-comm, etc. Much like hours/ times perhaps this needs to be addressed on its own. I do agree that it's a PITA. But that's all the more reason to tackle it. I mean, there has to be some work already done somewhere. My guess is there are types (e.g. USA) and that a location by definition would / could be tied to some address type, as needed.

I think it's more a validation issue than a raw meta data issue, yes?

NateWr commented 9 years ago

I see what you're saying, @AlchemyUnited, but I think eCommerce represents its own particular problem, where addresses are used for credit card verification, compliance with legal rules (ie - VATMOSS), and shipping. The majority of locations do not need this kind of specificity and it's sometimes in direct conflict with human-friendly locations. Think of locations which reference landmarks, like "City Mall", or countries where addresses do not exist, like Dubai.

As I said before, I'm still in favor of the content type standard declaring standards for both a human-readable string and a machine-readable set of strings, and letting plugins decide what they will support. If we use Schema.org's PostalAddress type we will gain from whatever international research they've done. It's more work than I want to do, personally.

kraftner commented 9 years ago

+1 one for having both. Just see the free-from field as

Seeing it like a "display as" field for the location I also see how this can be useful for example to just display stuff differently while still having clean data for automated use cases e.g. this:

A local shop in a small town with local clients that might list a location as location name: Market Stall address free-form field: the main square address: streetname 1 / town / country

Like this you can display "on the main square" while still putting the proper address in another field so you can display it on a map via a map API.

AlchemyUnited commented 9 years ago

The simple problem I see with the freeform field is layout out. Sure you can probably parse it with some js and say add
s but that's kinda not why there's this standards ideal, yes? :)

I do understand that there are multiple address standards but they are finite. What we need is a standard process for incorporating them in that particular definition. I still think this is mostly a validation issue than a schema one.

NateWr commented 9 years ago

I'm not sure what I was thinking, but obviously _location_name should not exist as post meta. It should just be the post_title. I've updated the working schema at the top.

AlchemyUnited commented 9 years ago

@NateWr - Well, maybe :) There are times (read: majority) where for tables that populate other tables (e.g. Location) I've relegated the Title to "for internal use only". Mainly, that tends to see to happen when I feel the slug / name for that post doesn't really matter (i.e., SEO).

I then think it's easier to say clients, "I don't care what you put there. But once you get to these fields down here, that's that stuff that we'll be using in public." I've also, at times, for such key fields had two inputs say Full Name and Short Name.

Please just ignore me if you don't think such examples apply here. Sorry?

NateWr commented 9 years ago

I've updated the draft standard to comply with the change to remove underscores from post meta in #24. I also actually separated the lat/lon values as I said I'd do before but apparently forgot to do.

peterwilsoncc commented 9 years ago

WordPress has an existing standard for GeoData https://codex.wordpress.org/Geodata

geo_latitude
geo_longitude
geo_public (show publicly - 0/1 boolean)
geo_address
AlchemyUnited commented 9 years ago

re: separated the lat/lon values

the issue i ran into with this is, often they're paired. so that if you're doing a copy / paste kinda data entry workflow, they're in the same c&p. i'm not sure if this observation helps in the context of this effort but i thought it was worth mentioning.

perhaps a bool flag similar to geo_public that determines which storage system to use. i know, can of worms :)

p.s. geo_public for me raises another question...is permissions (e.g., who can edit field X) part of this effort or too far out of scope? that is, while there standards are great - kudos to all - they're only what to store. but is that enough? does how they'll be implemented / used matter as well?

kraftner commented 9 years ago

I'd say this project only cares about data storage. The fact that data is stored in separate fields also doesn't enforce anything on the UI side. If you feel like you're plugin is more usable if the input happens via one text-input field go ahead. Nothing keeps you from splitting this up before saving behind the scenes.

Concerning the switch on how to store data: Not having one agreed-upon standard doesn't make sense as that is exactly what we're doing here. Also: Decisions not Options

And permissions is a different issue that is actually already nicely covered in the Wiki

NateWr commented 9 years ago

Thanks @peterwilsoncc. Lovely little treat there. I've updated the spec appropriately. I've left geo_public out just because I think visibility is out-of-scope here, as @kraftner pointed out. But nice to know it exists!

AlchemyUnited commented 9 years ago

re: "The fact that data is stored in separate fields also doesn't enforce anything on the UI side. "

@kraftner - Agreed. I'm just not so sure its best to totally divorce implemented / usage from spec. fwiw, for me, i read these threads and envision a library of classes (for e.g., CMB2, etc.). I mean, at some point the spec has to become real, and support the limitations (?) of reality, yes? That is, if it's all theory and no practicality "stuff" is gonna happen. In fact, the bigger that delta, the more friction. The more friction, the less traction. imho, of course ;)

So in the case of one field vs two. I do hear ya. I'm just thinking out loud - sorry? - that it might be easier said than done.

p.s. re: link to wiki. cheers!

kraftner commented 9 years ago

@AlchemyUnited In any case I think that would be a general issue and only adds noise to this issue. There already is this: https://github.com/justintadlock/content-type-standards/issues/22 or just open a new issue to discuss, but it isn't really an issue specific to the location standard.

NateWr commented 9 years ago

So in the case of one field vs two. I do hear ya. I'm just thinking out loud - sorry? - that it might be easier said than done.

I think it's much more likely that lat/lon coordinates would be received as two distinct numbers from a computer source already. Most of the time people won't be copy-pasting these in, but they'll be generated from human-readable addresses or by clicking on a map.

And in terms of practicality, I am building a plugin which will implement this standard for business locations. I think third party libraries are less important than the fact that, if I build to this standard, and you build to this standard, a user can swap my plugin for yours and still retain most of their data. Using common standards means we won't need big all-in-one frameworks/libraries.

AlchemyUnited commented 9 years ago

@NateWr - Yup. Agreed. It was simply an example we ran into a couple months ago that I thought was worth mentioning. Thanks.

NateWr commented 9 years ago

Updated post meta slugs to not include the post type slug, as discussed here.

franz-josef-kaiser commented 9 years ago

Some issues:

Naming

Instead of having geo_latitude/_longitude, I'd suggest to use geo_lat and geo_lng instead. Shortening the key value by 5/6 chars imo is a win both in DB size as well as in writing this in templates (line length).

Also, I'd change either the post type name to geo or geo_location, or just change the key names to a prefix of loc_ instead of geo_ to make it easier to understand what meta data belongs to what post type. Remove post type from the meta name.

Regarding the Codex article: It's the only article that tries to set any sort of post type standard – see for yourself. From this point of view I would consider it a nice try to fix a standard in a corner of the Codex where no one will ever look.

The meta of meta…

Looking at Contact Phone and Page ID, Opening Hours, etc., I can read very specific use cases. Why should a geo location have a contact page or a phone number? Consider building a map of nature places. I don't know a single rock in my phones contact list and I would have never thought about having to look up the opening hours for a tree. Please drop everything that is not absolutely required for a standard. Standards must be slim and not cover every exception (read: Decorators are optional parts of a structure/concept).

FAQ

I've noticed that other standards never serialize data in the post meta database. Is it a bad idea to do so? For instance, I've put the Latitude/Longitude into an array above. Should these instead be separate post meta values?

If you want to search something, it needs to be a single, non-serialized entry. Every non-searchable part can be mashed together in a single meta field/row.

What about searching? Since post meta is not very performant for lookups, we might want to store some data as taxonomies. _location_schema_type could be a good example of this. But I also imagine some important use-cases for efficient latitude/longitude lookups.

With MySQL 5.5, there's now the possibility for geospatial search. WP sadly requires 5.0 while recommends 5.5. This means that anyone having not MySQL 5.5 or 5.6 available, will go with a separate table for lat/lng with an increased size of entries anyway (or a completely separate DB like Solar or Elasticsearch).

NateWr commented 9 years ago

Instead of having geo_latitude/_longitude, I'd suggest to use geo_lat and geo_lng instead. Shortening the key value by 5/6 chars imo is a win both in DB size as well as in writing this in templates (line length).

Also, I'd change either the post type name to geo or geolocation, or just change the key names to a prefix of loc instead of geo_ to make it easier to understand what meta data belongs to what post type.

This wouldn't conform with the naming patterns of other standards in this project.

Looking at Contact Phone and Page ID, Opening Hours, etc., I can read very specific use cases. Why should a geo location have a contact page or a phone number? Consider building a map of nature places.

This is not a content standard for all geolocation data. From the beginning it was intended to "represent a physical location of some kind and would cater for business locations, outlets or venues (rather than, say, tracking the locations of incidents)." (from the first post in this issue).

The main purpose of the content standards project is to improve data portability between plugin solutions, to reduce the friction of moving from one platform to another. To be useful, I believe a standard must balance any generalizability against a reasonably specific use case. Otherwise there's really no meaning to data portability.

justintadlock commented 9 years ago

Instead of having geo_latitude/_longitude, I'd suggest to use geo_lat and geo_lng instead. Shortening the key value by 5/6 chars imo is a win both in DB size as well as in writing this in templates (line length).

Also, I'd change either the post type name to geo or geolocation, or just change the key names to a prefix of loc instead of geo_ to make it easier to understand what meta data belongs to what post type.

This wouldn't conform with the naming patterns of other standards in this project.

I think I'd be OK with that. As long as it makes sense and is consistent, we should keep names as short as possible.

Whatever everyone thinks is OK though. Best to just decide on something and go with it.

franz-josef-kaiser commented 9 years ago

From the beginning it was intended to "represent a physical location of some kind and would cater for business locations, outlets or venues (rather than, say, tracking the locations of incidents)." (from the first post in this issue).

Then I'd suggest to change the title to "Physical Location/Store". Also, I'd suggest to change the name from the very general location to something that represents

business locations, outlets or venues

About…

This wouldn't conform with the naming patterns of other standards in this project.

There're currently just two standards and lat, lng is used pretty much everywhere else (all maps APIs, packages that work with geo data, etc.). Using the long version would imo be confusing as well.

AlchemyUnited commented 9 years ago

I think - and perhaps I mis-skimmed - it was implied somewhere above that there could be (at least in theory) multiple lat+lng per post. Makes sense? Has this been addressed?

Along the same lines this seems like a good time to mention that while the standardization certainly does help to make switching plugins easiers, it also means that when testing they share data. Do we test on production? Of course not. Might others? Yeah, I'd say that's quite possible.

Maybe this is a non-issue? But something tells me that two (or more) applications sharing the same variable names could lead to unanticipated results. Just me?

franz-josef-kaiser commented 8 years ago

it also means that when testing they share data

What do you mean by testing in that case?

NateWr commented 8 years ago

An update to Business Profile was released today with multi-location support that conforms to the proposed spec here.