Saving locations using Google Maps without violating T&Cs - web-services

I am currently working on an app (not live yet) that will allow users to create projects and set the location of each.
I originally added an autocomplete field that worked with the Google maps lookup to help the user type in the location and also it would find the latitude and longitude of the place/location and show it on a map.
At this point I was saving the location, latitude and longitude to database fields.
This made the user experience quite straight forward.
However, I now think this idea of storing the autocompleted location violates 10.1.3 of Google Maps T&Cs.
I need to include the locations in my list page and Google allows short term caching for performance purposes but surely that would mean I would need to update the cache or something for each entry at least every 30 days which isn't really an option.
This would also mean that the location data belongs to Google which limits any future use of this data (an API on my site for instance).
I wondered if it would be an option to use openstreetmap data to get the full location (although I'm not sure if it can be used to provide an autocomplete facility) and then pass that to the google maps lookup so that the location provided by the openstreetmap autocomplete with looser restrictions can be saved to the database. However, even if that was all possible it could be confusing for the user if the openstreetmap autocomplete failed to find a location/place that exists on google or it was labelled differently.
I'm not sure if that's an option or not.
I am currently tending towards a plain text box with an example location shown alongside it so the user can see the extent that the location needs to be typed (ie a full address) so that when it is used to lookup the location via Google it will bring back the correct latitude and longitude but will also be informative to users when they see it on the list page.
This does mean that the location field content is ok to store in the database then but it puts more reliance on the user typing the address in correctly and if they don't type it in properly the auto lookup may fail to locate it and/or it may not be viewer-friendly on the list page.
Can anyone offer any better ways that I could help users to type in an accurate location (which could be a place with address or just an address) so that it doesn't violate the terms and conditions and allows my site to have ownership of the location?
Thanks

Related

Where to create the Articles in Sitecore?

I'm trying to understand the best approach to create article items in my sitecore 7.2 project.
Basically I'm considering 2 options:
1 - Create an article as a page;
2 - Create an article as a Site Data Item.
1 - Create article pages under a given page (i.e. My Articles). This way each article would have a specific URL out of the box, easier to understand in Content Authors' point of view;
2 - Have a specific folder (i.e. Article Folder) under Site Data. This way we don't need to have a page for each article - I was thinking to have a single Article page that would render the article fields. However this would require more work in terms of URLs, navigation, etc.
Is there any other ideas? Am I missing something? I was also having a look at Buckets...
Thank you
I'm going to disagree with Marek and recommend you opt for option 2.
Storing your articles in folder under a Data node allows those items to be datasourced. This is the principle Sitecore was built on. You can then surface those articles in a number of interesting ways via Widgets such as Promo Panels, prompting the user to click through to read about the article without duplicating its data and requiring Content Editors to manage data multiple times.
It even supports multiple sites, so the Articles can be used in other sites you may add to your Sitecore instance in the future.
As you state it will require extra work in terms of Urls and Navigation but it can be achieved via Sitecore's Wild Card Item and you an even use a great open sourced Module from Sitecore's Marketplace to complete 90% of the work for you. See links below for more information.
You can still implement Marek's point of applying Presentation Details once on the Standard Values of the Wild Cart Item you create. If you are using Sitecore 7 and above you can store all your articles in a Bucket so if you have lots of articles they are stored and searchable in a meaningful way.
http://www.sitecore.net/learn/blogs/technical-blogs/getting-to-know-sitecore/posts/2011/09/wildcards-and-data-driven-urls.aspx
https://marketplace.sitecore.net/en/Modules/Wildcard_module.aspx
In a standard one instance setup the easiest implementation is to create articles as pages.
In Sitecore you want to limit the items in a folder to 100 or less which is best practice to keep the content editors experience optimal.
This then leads you needing a folder structure and a couple options:
Manually maintain a folder structure for your articles. For example articles/year/month/day. This gives your editors the most control over the folder structure and allow them to navigate the articles in a more traditional way via a visible folder structure.
Use a bucket which automatically generates the folder structure and hides this complexity from the content editor. This takes the manual folder creation and maintenance away from the content editor and are automatically generated based on the configuration you set out for your bucket. The folders wont be visible to the content editor so they will be forced to search in the bucket for any articles rather then navigate the folders.
Use the shared source News mover module (https://marketplace.sitecore.net/en/Modules/News_mover.aspx). This takes a different approach to the above. It works via a traditional folder structure however it generates folders and moves the item on save based on the date field in the article. So the news mover handles the generation of folders however you will still need to check your not exceeding 100 items per folder again for performance when opening folders with large amounts of items.
With all solutions you must still consider the URLs for your articles as they will include the folder structure by default. This is not always acceptable. I prefer to remove the folder structure from the URL. For this you need to create a custom linkProvider and a custom HttpRequestProcessor. Firstly the linkprovider allows you to ensure the new URL is always created and displayed in your site as you want. Next the HttpRequestProcessor ensures that when navigating to the shortened URL Sitecore recognises it as a valid URL and presents the correct page.
By excluding the folder structure from the URL it also adds the additional benefit that the URL is not dependent on the structure. This means editors can change that folder structure and not need to create redirect items to ensure SEO rankings or users bookmarks are not lost.
The cleaner data model is to use the wildcard approach for the URLs and centralize the storage of articles data in a bucket of datasources. This will give you optimum performance and reuse of the data.
However, this isn't how an author thinks about their website. When they use the system, they tend to navigate to the area where they would view articles and try to create a new one there. Authors tend to think in 'pages', so try to hide whatever data model you are using from them and give them the ability to edit the page with Experience Editor.
Some developers try to optimize too far and forget that the authoring experience is likely the most important piece of the delivered solution. The author doesn't care how efficiently you stored the data, only that they can edit it easily and publish efficiently. Whatever model supports that for your author base is how you should implement it.
My recommendation is a page-based approach where the author creates the URL structure with folders and items, something they understand. Then, if you really need to, you can have the primary article data be a datasource-driven component on the page. The user gets to use all the tools they are familiar with (Experience Editor,preview navigation) but you can still store the raw data in a centralized folder. You could then theoretically swap out the article data using DMS rules, or hide information based on authentication or membership status.
Go with approach 1: article is a page.
Define all your presentation details on Article Page template __Standard Values. All new articles will get them. And you can change some of the presentation details for your chosen articles if you want.
If you know that you'll have lot of articles, think about year/month/day folder structure, e.g. articles/2015/06/12.
Approach 2 doesn't give you anything - you still need to have an item for every article. And as you wrote, it would require additional coding which is not required.

How to accept user input with Sitecore DMS report/filter?

With the Sitecore OMS, it was possible to create custom report filters that used the Sitecore rules engine to accept user input. This was useful for filtering by ItemId, URL, IP Address, etc. Here is an example of a custom filter for the OMS.
How does one go about accepting user input with the Sitecore DMS? It appears that the old filter methodology has been scrapped in lieu of "Predefined Filters", which are hard-coded values that get injected into the SQL Statement's WHERE clause.
You are aware that every item in Sitecore has the Analyze tab in which there is a "Reports" option where the user can see reports specific to the item? I realize that these are really "canned" reports, but it's not too difficult to create new ones or adapt the existing ones to give you what you want to see. If the reports aren't specific enough, you can always create your own reports and then just simply drop them into the item reports folder here: /sitecore/system/Settings/Analytics/Reports/Item Reports/. Also, keep in mind that all the SQL queries are located in items here: /sitecore/system/Settings/Analytics/Reports SQL Queries and it's not difficult to add a parameter (i.e. the date parameter for example).
I know that it has a bit of a learning curve, but creating your own queries and reports capable of taking some user input isn't out of the question. Please let me know if you have something specific or if you need further help. I've spent a good amount of time doing custom reports and I'd be happy to answer any questions.

Django - URL design and best practices for identify one object

Im actually working in a django project and I'm not sure about the best format of the URL to access into one particular object page.
I was thinking about these alternatives:
1) Using the autoincremental ID => .com/object/15
This is the simplest and well known way of do that. "id_object" is the autoincremental ID generated by the database engine while saving the object. The problem I find in this way is that the URLs are simple iterable. So we can make an simple script and visit all the pages by incrementing the ID in the URL. Maybe a security problem.
2) Using a <hash_id> => .com/object/c30204225d8311e185c3002219f52617
The "hash_id" should be some alphanumeric string value, generated for example with uuid functions. Its a good idea because it is not iterable. But generate "random" uniques IDs may cause some problems.
3) Using a Slug => .com/object/some-slug-generated-with-the-object
Django comes with a "slug" field for models, and it can be used to identify an object in the URL. The problem I find in this case is that the slug may change in the time, generating broken URLs. If some search engine like Google had indexed this broken URL, users may be guided to "not found" pages and our page rank can decrease. Freezing the Slug can be a solution. I mean, save the slug only on "Add" action, and not in the "Update" one. But the slug can now represent something old or incorrect.
All the options have advantages and disadvantages. May be using some combination of them can some the problems.
What do you think about that?
I think the best option is this:
.com/object/AUTOINCREMENT_ID/SLUG_FIELD
Why?
First reason: the AUTOINCREMENT_ID is simple for the users to identify an object. For example, in an ecommerce site, If the user want to visit several times the page (becouse he's not sure of buying the product) he will recognize the URL.
Second reason: The slug field will prevent the problem of someone iterating over the webpage and will make the URL more clear to people.
This .com/object/10/ford-munstang-2010 is clearer than .com/object/c30204225d8311e185c3002219f52617
IDs are not strictly "iterable". Things get deleted, added back, etc. Over time, there's very rarely a straight linear progression of IDs from 1-1000. From a security perspective, it doesn't really matter. If views need to be protected for some reason, you use logins and only show what each user is allowed to see to each user.
There's upsides and downsides with every approach, but I find slugs to be the best option overall. They're descriptive, they help users know where there at and at a glance enable them to tell where they're going when they click a URL. And, the downsides (404s if slugs change) can be mitigated by 1) don't change slugs, ever 2) set up proper redirects when a slug does need to change for some reason. Django even has a redirects framework baked-in to make that even easier.
The idea of combine an id and a slug is just crazy from where I'm sitting. You still rely on either the id or the slug part of the URL, so it's inherently no different that using one or the other exclusively. Or, you rely on both and compound your problems and introduce additional points of failure. Using both simply provides no meaningful benefit and seems like nothing more than a great way to introduce headaches.
Nobody talked about the UUID field (django model field reference page) which can be a good implementation of the "hash id". I think you can have an url like:
.com/object/UUID/slug
It prevents from showing an order in the URL if this order is not relevant.
Other alternatives could be:
.com/object/yyyy-mm-dd/ID/slug
.com/object/kind/ID/slug
depending of the relevant information you want to have in the url

Multiple Parameters in Graph User query/search?

The FB Graph API shows how I can search for all users named "Mark" anywhere in the world:
https://graph.facebook.com/search?q=mark&type=user
but I would like to be able to search, for example, by location and interest, like all users in Los Angeles who like Soccer.
I looked through the API documentation, and forums, but although I imagine this would be a common question (whether it's possible or not), I couldn't find anything.
Thanks for any help.
The current implementation of the Graph API makes these types of searches impossible.
First, the search query structure is dependent on the type of resource being searched. It is not coincidence that the majority of search queries in the documentation only include one search term and do not allow you to restrict the fields being searched. Outside of a limited subset of types (like Places), it is not possible to use multiple terms and it may not be possible to get results for the fields you want to search (e.g. you can't search for Pages by location).
Second, all methods of the Graph API follow Facebook's permissions. If you look at the documentation on User objects, you will note that both the location field and the likes connection require extended permissions (user_location and user_likes respectively) in order to access them. Since both of these fields are private by default, there is no way to find users with a location in Los Angeles, or who like soccer.
I suspect that this is because the Graph API's purpose is not to allow programmers to do granular searches over Facebook's userbase, but to "promote rich social applications".

Is it Possible to Filter Graph Feed using Location?

We have a worldwide brand page that posts brand messages and filtered by country, for example: "This is visible in the US" (visible to United States), and "This is visible to Russia" (only visible to Russia).
Main Question: Is it possible to retrieve posts on the page wall filtered by country or other location parameters? For example: https://graph.facebook.com/[userID]/feed?access_token=[accessToken]&locale=en_US
Side Question: Currently when using the URL above (without &locale...) returns only the posts available worldwide, and all targeted posts are not returned. This could potentially be due to the access token being used as I am able to return info for page feeds (that I own) for all locales using a different access token. Is there a correlation between application tokens and locales that are returned?
Forget about it - it's impossible. They never thought about providing us any interface to this.
What you must do is:
Download the entire graph object (awesome especially on mobile),
Remember to download all pages (since facebook is paging long responses),
Merge and filter them on your side (or in client's browser|phone),
VoilĂ  you're good to go ;) .
PS. I know you asked this looong time ago, but it's still one of the first Google results for related queries, so I'm writing here so others can quickly find out. Cheers!