forked from JohnSundell/Plot
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from SwiftPackageIndex/sitemapindex
Bring the sitemap index into the default branch
- Loading branch information
Showing
5 changed files
with
170 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
/** | ||
* Plot | ||
* Copyright (c) John Sundell 2019 | ||
* MIT license, see LICENSE file for details | ||
*/ | ||
|
||
import Foundation | ||
|
||
/// A representation of a site map index, used by search engines when a | ||
/// site map goes over the 50,000 entries or 50Mb maximum size. It is an | ||
/// index of references to other site maps. | ||
public struct SiteMapIndex: DocumentFormat { | ||
private let document: Document<SiteMapIndex> | ||
|
||
/// Create a site map index with a with a collection of site maps. | ||
/// - parameter nodes: All the `<sitemap>` elements in this site map index. | ||
public init(_ nodes: Node<SiteMapIndex.SiteMapIndexContext>...) { | ||
document = Document(elements: [ | ||
.xml(.version(1.0), .encoding(.utf8)), | ||
.sitemapindex(.group(nodes)) | ||
]) | ||
} | ||
} | ||
|
||
extension SiteMapIndex: NodeConvertible { | ||
public var node: Node<Self> { document.node } | ||
} | ||
|
||
public extension SiteMapIndex { | ||
/// The root context of a site map index document. | ||
enum RootContext: XMLRootContext {} | ||
/// The context within a `<sitemapindex>` element. | ||
enum SiteMapIndexContext {} | ||
/// The context within a `<sitemap>` element. | ||
enum SiteMapContext {} | ||
} | ||
|
||
internal extension SiteMapIndex { | ||
static var dateFormatter: DateFormatter { | ||
let formatter = DateFormatter() | ||
formatter.dateFormat = "yyyy-MM-dd" | ||
return formatter | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
/** | ||
* Plot | ||
* Copyright (c) John Sundell 2019 | ||
* MIT license, see LICENSE file for details | ||
*/ | ||
|
||
import Foundation | ||
|
||
// MARK: - Root | ||
|
||
public extension Element where Context == SiteMapIndex.RootContext { | ||
/// Add a `<sitemapindex>` element within the root context. | ||
/// - parameter nodes: The element's attributes and child elements. | ||
static func sitemapindex(_ nodes: Node<SiteMapIndex.SiteMapIndexContext>...) -> Element { | ||
return Element( | ||
name: "sitemapindex", | ||
nodes: [ Attribute<SiteMapIndex.SiteMapIndexContext>( | ||
name: "xmlns", | ||
value: "http://www.sitemaps.org/schemas/sitemap/0.9" | ||
).node ] + nodes | ||
) | ||
} | ||
} | ||
|
||
// MARK: - SiteMapIndex Context | ||
|
||
public extension Node where Context == SiteMapIndex.SiteMapIndexContext { | ||
/// Add a `<sitemap>` element within a `<sitemapindex>`. | ||
/// - parameter nodes: The element's child elements. | ||
static func sitemap(_ nodes: Node<SiteMapIndex.SiteMapContext>...) -> Node { | ||
.element(named: "sitemap", nodes: nodes) | ||
} | ||
} | ||
|
||
// MARK: - SiteMap Context | ||
|
||
public extension Node where Context == SiteMapIndex.SiteMapContext { | ||
/// Define the location of a site map with a `<loc>` element. | ||
/// - parameter url: The location of a site map in the index. | ||
static func loc(_ url: URLRepresentable) -> Node { | ||
.element(named: "loc", text: url.string) | ||
} | ||
|
||
/// Declare tha most recent modification date for any URLs in the linked site map. | ||
/// - parameter date: The most recent modification for any page in the linked site map. | ||
/// - parameter timeZone: The time zone of the given `Date` (default: `.current`). | ||
static func lastmod(_ date: Date, timeZone: TimeZone = .current) -> Node { | ||
let formatter = SiteMap.dateFormatter | ||
formatter.timeZone = timeZone | ||
let dateString = formatter.string(from: date) | ||
return .element(named: "lastmod", text: dateString) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/** | ||
* Plot | ||
* Copyright (c) John Sundell 2019 | ||
* MIT license, see LICENSE file for details | ||
*/ | ||
|
||
import XCTest | ||
import Plot | ||
|
||
final class SiteMapIndexTests: XCTestCase { | ||
func testEmptySiteMapIndex() { | ||
let map = SiteMapIndex() | ||
|
||
XCTAssertEqual(map.render(indentedBy: .spaces(4)), """ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></sitemapindex> | ||
""") | ||
} | ||
|
||
func testSiteMapIndex() { | ||
let map = SiteMapIndex( | ||
.sitemap( | ||
.loc("https://example.com/sitemap-one.xml") | ||
), | ||
.sitemap( | ||
.loc("https://example.com/sitemap-two.xml") | ||
) | ||
) | ||
|
||
XCTAssertEqual(map.render(indentedBy: .spaces(4)), """ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> | ||
<sitemap> | ||
<loc>https://example.com/sitemap-one.xml</loc> | ||
</sitemap> | ||
<sitemap> | ||
<loc>https://example.com/sitemap-two.xml</loc> | ||
</sitemap> | ||
</sitemapindex> | ||
""") | ||
} | ||
|
||
func testSiteMapIndexWithLastModifiedDate() throws { | ||
let dateStubs = try Date.makeStubs(withFormattingStyle: .siteMap) | ||
|
||
let map = SiteMapIndex( | ||
.sitemap( | ||
.loc("https://example.com/sitemap-one.xml") | ||
), | ||
.sitemap( | ||
.loc("https://example.com/sitemap-two.xml"), | ||
.lastmod(dateStubs.date) | ||
) | ||
) | ||
|
||
XCTAssertEqual(map.render(indentedBy: .spaces(4)), """ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> | ||
<sitemap> | ||
<loc>https://example.com/sitemap-one.xml</loc> | ||
</sitemap> | ||
<sitemap> | ||
<loc>https://example.com/sitemap-two.xml</loc> | ||
<lastmod>2019-10-17</lastmod> | ||
</sitemap> | ||
</sitemapindex> | ||
""") | ||
} | ||
} |