-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathMarkupSitemapXML.module
More file actions
137 lines (122 loc) · 5.02 KB
/
MarkupSitemapXML.module
File metadata and controls
137 lines (122 loc) · 5.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<?php
class MarkupSitemapXML extends WireData implements Module {
/**
* Provide information about this module to ProcessWire
*
*/
public static function getModuleInfo() {
return array(
'title' => 'Markup Sitemap XML',
'summary' => 'Generates an XML sitemap at yoursite.com/sitemap.xml for use with Google Webmaster Tools etc.',
'href' => 'http://processwire.com/talk/index.php/topic,867.0.html',
'version' => 110,
'permanent' => false,
'autoload' => true,
'singular' => true,
);
}
/**
* Add the hook
*
*/
public function init() {
// Intercept a request for an URL ending in sitemap.xml and output
if (isset($_SERVER['REQUEST_URI']) && strlen($_SERVER['REQUEST_URI']) - strlen('/sitemap.xml') === strrpos($_SERVER['REQUEST_URI'], '/sitemap.xml')) {
$this->addHookBefore("ProcessPageView::pageNotFound",$this,"renderSitemap");
}
}
public function renderSitemap(HookEvent $event){
//$event->replace = true;
$lang = '';
$this->pageselector = '';
$langname = ''; // for LanguageLocalizedUrl
$subdomain = ''; // for Multisite
// set startpage according to request (sitemap.xml spec says that sitemap
// should only contain pages below it's root page in page tree)
// Fix #11 by FlipZoomMedia | David Karich
$startpage = str_ireplace(trim(wire('config')->urls->root, '/'), '', $this->sanitizer->path(dirname($_SERVER['REQUEST_URI'])));
// Multisite requires minor URL-related tweak
if (wire("modules")->isInstalled("Multisite")) {
$multisite = wire("modules")->get("Multisite");
if ($multisite->subdomain) {
$startpage = "/".$multisite->subdomain.$startpage;
}
}
// make sure that page used as root for sitemap actually exists
if ($this->pages->get($startpage) instanceof NullPage) return;
// support for LanguageLocalizedURL language module
if(wire("modules")->isInstalled("LanguageLocalizedURL")) {
$llu = wire("modules")->get("LanguageLocalizedURL");
$langname = $this->page->name;
$lang = ($llu->defaultLang == $langname) ? 'default' : $langname;
$langpage = $this->page;
// get the field name for published language from the modules settings
$publishedfield_name = $llu->publishedPageField ? $llu->publishedPageField : 'language_published';
// add a selector to find children pages when generating sitemap list
$this->pageselector = "$publishedfield_name=$langpage->id";
//set user language so the module will spit out language localized urls
$this->user->language = $this->languages->get($lang);
}
// Check for the cached sitemap, else generate and cache a fresh sitemap
$startpagestr = $this->sanitizer->pageName($startpage);
$cache = wire('modules')->get("MarkupCache");
if(!$output = $cache->get("MarkupSitemapXML$startpagestr$langname", 3600)) {
$output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
$output .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
$output .= $this->sitemapListPage(wire('pages')->get($startpage));
$output .= "\n</urlset>";
$cache->save($output);
}
header("Content-Type: text/xml", true, 200);
echo $output;
exit();
}
public function sitemapListPage($page) {
$entry = "";
if ($page->viewable() && ($page->sitemap_ignore == 0 || $page->path == '/')) { // $page->path part added so that it ignores hiding the homepage, else you wouldn't have ANY pages returned
$modified = date ('Y-m-d', $page->modified);
$entry = "\n <url>\n";
$entry .= " <loc>{$page->httpUrl}</loc>\n";
$entry .= " <lastmod>{$modified}</lastmod>\n";
$entry .= " </url>";
}
// Fix #12 by FlipZoomMedia | David Karich
$children = $page->children($this->pageselector);
if(count($children)) {
foreach($children as $child) {
$entry .= $this->sitemapListPage($child);
}
}
return $entry;
}
/**
* Install the module
*
*/
public function ___install() {
if($this->fields->get('sitemap_ignore')) {
$this->error("You already have a 'sitemap_ignore' field.");
return;
}
wire('modules')->get('MarkupCache');
$field = new Field();
$field->type = $this->modules->get("FieldtypeCheckbox");
$field->name = 'sitemap_ignore';
$field->label = 'Hide page from XML sitemap';
$field->description = 'Hide this page and its children from the XML sitemap';
$field->save();
$this->message("Added field 'sitemap_ignore'. Add this field to any templates where you want to prevent inclusion in the XML sitemap.");
}
/**
* Uninstall the module
*
*/
public function ___uninstall() {
// only do the following if you want to uninstall the fields that were installed
// this may be one thing that's safe to leave to the user
$field = wire('fields')->get('sitemap_ignore');
if($field && $field->numFieldgroups() > 0)
throw new WireException("Can't uninstall because field sitemap_ignore is still being used. Please remove it from any templates.");
wire('fields')->delete($field);
}
}