extended GoolgeLinkGenerator to support generic map to define link attributes
This commit is contained in:
@@ -3,6 +3,7 @@ package com.redfin.sitemapgenerator;
|
||||
import java.io.File;
|
||||
import java.net.*;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
@@ -10,6 +11,7 @@ import java.util.Map.Entry;
|
||||
*
|
||||
* @author Sergio Vico
|
||||
* @see <a href="https://support.google.com/webmasters/answer/2620865">Creating alternate language pages Sitemaps</a>
|
||||
* @see <a href="https://developers.google.com/search/mobile-sites/mobile-seo/separate-urls?hl=en">Mobile SEO configurations | Separate URLs </a>
|
||||
*/
|
||||
public class GoogleLinkSitemapGenerator extends SitemapGenerator<GoogleLinkSitemapUrl, GoogleLinkSitemapGenerator> {
|
||||
|
||||
@@ -29,11 +31,13 @@ public class GoogleLinkSitemapGenerator extends SitemapGenerator<GoogleLinkSitem
|
||||
public void render(final GoogleLinkSitemapUrl url, final StringBuilder sb, final W3CDateFormat dateFormat) {
|
||||
|
||||
final StringBuilder tagSb = new StringBuilder();
|
||||
for (final Entry<Locale, URL> entry : url.getAlternates().entrySet()) {
|
||||
for (final Entry<URL, Map<String, String>> entry : url.getAlternates().entrySet()) {
|
||||
tagSb.append(" <xhtml:link\n");
|
||||
tagSb.append(" rel=\"alternate\"\n");
|
||||
tagSb.append(" hreflang=\"" + entry.getKey().toLanguageTag() + "\"\n");
|
||||
tagSb.append(" href=\"" + UrlUtils.escapeXml(entry.getValue().toString()) + "\"\n");
|
||||
for(final Entry<String, String> innerEntry : entry.getValue().entrySet()){
|
||||
tagSb.append(" " + innerEntry.getKey() + "=\"" + innerEntry.getValue() + "\"\n");
|
||||
}
|
||||
tagSb.append(" href=\"" + UrlUtils.escapeXml(entry.getKey().toString()) + "\"\n");
|
||||
tagSb.append(" />\n");
|
||||
}
|
||||
super.render(url, sb, dateFormat, tagSb.toString());
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.redfin.sitemapgenerator;
|
||||
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
/**
|
||||
@@ -10,55 +12,89 @@ import java.util.Map.Entry;
|
||||
* @author Sergio Vico
|
||||
* @see Options
|
||||
* @see <a href="https://support.google.com/webmasters/answer/2620865">Creating alternate language pages Sitemaps</a>
|
||||
* @see <a href="https://developers.google.com/search/mobile-sites/mobile-seo/separate-urls?hl=en">Mobile SEO configurations | Separate URLs </a>
|
||||
*/
|
||||
public class GoogleLinkSitemapUrl extends WebSitemapUrl {
|
||||
|
||||
/** Options to configure mobile URLs */
|
||||
/** Options to configure URLs with alternates */
|
||||
public static class Options extends AbstractSitemapUrlOptions<GoogleLinkSitemapUrl, Options> {
|
||||
private final Map<Locale, URL> alternates;
|
||||
private final Map<URL, Map<String, String>> alternates;
|
||||
|
||||
private static Map<Locale, URL> convertAlternates(final Map<String, String> alternates)
|
||||
private static Map<URL, Map<String, String>> convertAlternates(final Map<String, Map<String, String>> alternates)
|
||||
throws MalformedURLException {
|
||||
|
||||
final Map<Locale, URL> converted = new LinkedHashMap<Locale, URL>(alternates.size());
|
||||
for (final Entry<String, String> entry : alternates.entrySet()) {
|
||||
converted.put(Locale.forLanguageTag(entry.getKey()), new URL(entry.getValue()));
|
||||
final Map<URL, Map<String, String>> converted = new LinkedHashMap<URL, Map<String, String>>(alternates.size());
|
||||
for (final Entry<String, Map<String, String>> entry : alternates.entrySet()) {
|
||||
converted.put(new URL(entry.getKey()), entry.getValue());
|
||||
}
|
||||
return converted;
|
||||
}
|
||||
|
||||
/** Specifies the url */
|
||||
public Options(final String url, final Map<String, String> alternates) throws MalformedURLException {
|
||||
/**
|
||||
* Options constructor with the alternates configurations
|
||||
*
|
||||
* @param url Base URL into which we will be adding alternates
|
||||
* @param alternates Map<String, Map<String, String>> where the key is the href and
|
||||
* the value is a generic Map<String, String> holding the attributes of
|
||||
* the link (e.g. hreflang, media, ...)
|
||||
*/
|
||||
public Options(final String url, final Map<String, Map<String, String>> alternates) throws MalformedURLException {
|
||||
|
||||
this(new URL(url), convertAlternates(alternates));
|
||||
}
|
||||
|
||||
/** Specifies the url */
|
||||
public Options(final URL url, final Map<Locale, URL> alternates) {
|
||||
/**
|
||||
* Options constructor with the alternates configurations
|
||||
*
|
||||
* @param url Base URL into which we will be adding alternates
|
||||
* @param alternates Map<URL, Map<String, String>> where the key is the href and
|
||||
* the value is a generic Map<String, String> holding the attributes of
|
||||
* the link (e.g. hreflang, media, ...)
|
||||
*/
|
||||
public Options(final URL url, final Map<URL, Map<String, String>> alternates) {
|
||||
super(url, GoogleLinkSitemapUrl.class);
|
||||
this.alternates = new LinkedHashMap<Locale, URL>(alternates);
|
||||
this.alternates = new LinkedHashMap<URL, Map<String, String>>(alternates);
|
||||
}
|
||||
}
|
||||
|
||||
private final Map<Locale, URL> alternates;
|
||||
private final Map<URL, Map<String, String>> alternates;
|
||||
|
||||
/** Specifies configures url with options */
|
||||
/**
|
||||
* Constructor specifying the URL and the alternates configurations with Options object
|
||||
*
|
||||
* @param options Configuration object to initialize the GoogleLinkSitemapUrl with.
|
||||
* @see Options#Options(java.lang.String, java.util.Map)
|
||||
*/
|
||||
public GoogleLinkSitemapUrl(final Options options) {
|
||||
super(options);
|
||||
alternates = options.alternates;
|
||||
}
|
||||
|
||||
/** Specifies the url */
|
||||
public GoogleLinkSitemapUrl(final String url, final Map<String, String> alternates) throws MalformedURLException {
|
||||
/**
|
||||
* Constructor specifying the URL as a String and the alternates configurations
|
||||
*
|
||||
* @param url Base URL into which we will be adding alternates
|
||||
* @param alternates Map<String, Map<String, String>> where the key is the href and
|
||||
* the value is a generic Map<String, String> holding the attributes of
|
||||
* the link (e.g. hreflang, media, ...)
|
||||
*/
|
||||
public GoogleLinkSitemapUrl(final String url, final Map<String, Map<String, String>> alternates) throws MalformedURLException {
|
||||
this(new Options(url, alternates));
|
||||
}
|
||||
|
||||
/** Specifies the url */
|
||||
public GoogleLinkSitemapUrl(final URL url, final Map<Locale, URL> alternates) {
|
||||
/**
|
||||
* Constructor specifying the URL as a URL and the alternates configurations
|
||||
*
|
||||
* @param url Base URL into which we will be adding alternates
|
||||
* @param alternates Map<String, Map<String, String>> where the key is the href and
|
||||
* the value is a generic Map<String, String> holding the attributes of
|
||||
* the link (e.g. hreflang, media, ...)
|
||||
*/
|
||||
public GoogleLinkSitemapUrl(final URL url, final Map<URL, Map<String, String>> alternates) {
|
||||
this(new Options(url, alternates));
|
||||
}
|
||||
|
||||
public Map<Locale, URL> getAlternates() {
|
||||
public Map<URL, Map<String, String>> getAlternates() {
|
||||
|
||||
return this.alternates;
|
||||
}
|
||||
|
||||
@@ -31,13 +31,13 @@ public class GoogleLinkSitemapUrlTest extends TestCase {
|
||||
dir = null;
|
||||
}
|
||||
|
||||
public void testSimpleUrl() throws Exception {
|
||||
public void testSimpleUrlWithHrefLang() throws Exception {
|
||||
|
||||
wsg = new GoogleLinkSitemapGenerator("http://www.example.com", dir);
|
||||
final Map<String, String> alternates = new LinkedHashMap<String, String>();
|
||||
alternates.put("en-GB", "http://www.example/en/index.html");
|
||||
alternates.put("fr-FR", "http://www.example/fr/index.html");
|
||||
alternates.put("es-ES", "http://www.example/es/index.html");
|
||||
final Map<String, Map<String, String>> alternates = new LinkedHashMap<String, Map<String, String>>();
|
||||
alternates.put("http://www.example/en/index.html", Collections.singletonMap("hreflang", "en-GB"));
|
||||
alternates.put("http://www.example/fr/index.html", Collections.singletonMap("hreflang", "fr-FR"));
|
||||
alternates.put("http://www.example/es/index.html", Collections.singletonMap("hreflang", "es-ES"));
|
||||
|
||||
final GoogleLinkSitemapUrl url = new GoogleLinkSitemapUrl("http://www.example.com/index.html", alternates);
|
||||
wsg.addUrl(url);
|
||||
@@ -69,6 +69,44 @@ public class GoogleLinkSitemapUrlTest extends TestCase {
|
||||
assertEquals(expected, sitemap);
|
||||
}
|
||||
|
||||
public void testSimpleUrlWithMedia() throws Exception {
|
||||
|
||||
wsg = new GoogleLinkSitemapGenerator("http://www.example.com", dir);
|
||||
final Map<String, Map<String, String>> alternates = new LinkedHashMap<String, Map<String, String>>();
|
||||
alternates.put("http://www.example/en/index.html", Collections.singletonMap("media", "only screen and (max-width: 640px)"));
|
||||
alternates.put("http://www.example/fr/index.html", Collections.singletonMap("media", "only screen and (max-width: 640px)"));
|
||||
alternates.put("http://www.example/es/index.html", Collections.singletonMap("media", "only screen and (max-width: 640px)"));
|
||||
|
||||
final GoogleLinkSitemapUrl url = new GoogleLinkSitemapUrl("http://www.example.com/index.html", alternates);
|
||||
wsg.addUrl(url);
|
||||
//@formatter:off
|
||||
final String expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
+ "<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\" "
|
||||
+ "xmlns:xhtml=\"http://www.w3.org/1999/xhtml\" >\n"
|
||||
+ " <url>\n"
|
||||
+ " <loc>http://www.example.com/index.html</loc>\n"
|
||||
+ " <xhtml:link\n"
|
||||
+ " rel=\"alternate\"\n"
|
||||
+ " media=\"only screen and (max-width: 640px)\"\n"
|
||||
+ " href=\"http://www.example/en/index.html\"\n"
|
||||
+ " />\n"
|
||||
+ " <xhtml:link\n"
|
||||
+ " rel=\"alternate\"\n"
|
||||
+ " media=\"only screen and (max-width: 640px)\"\n"
|
||||
+ " href=\"http://www.example/fr/index.html\"\n"
|
||||
+ " />\n"
|
||||
+ " <xhtml:link\n"
|
||||
+ " rel=\"alternate\"\n"
|
||||
+ " media=\"only screen and (max-width: 640px)\"\n"
|
||||
+ " href=\"http://www.example/es/index.html\"\n"
|
||||
+ " />\n"
|
||||
+ " </url>\n"
|
||||
+ "</urlset>";
|
||||
//@formatter:on
|
||||
final String sitemap = writeSingleSiteMap(wsg);
|
||||
assertEquals(expected, sitemap);
|
||||
}
|
||||
|
||||
private String writeSingleSiteMap(final GoogleLinkSitemapGenerator wsg) {
|
||||
|
||||
final List<File> files = wsg.write();
|
||||
|
||||
Reference in New Issue
Block a user