Commit 4379a6bb authored by Mike Rockétt's avatar Mike Rockétt

=0.2-beta changes, enhancements, and fixes

parent 775c4ee0
### SublimeText ###
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
......@@ -15,9 +14,6 @@ Package Control.user-ca-bundle
oscrypto-ca-bundle.crt
bh_unicode_properties.cache
GitHub.sublime-settings
.phpintel/
### Windows ###
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
......@@ -28,3 +24,4 @@ $RECYCLE.BIN/
*.msm
*.msp
*.lnk
.phpintel/
\ No newline at end of file
{
"title": "Sitemap",
"summary": "Renders a sitemap for your ProcessWire powered site. Supports multi-language and multi-site. Adapted from MarkupSitemapXML.",
"version": "0.1.2",
"version": "0.2",
"author": "Mike Rockett",
"summary": "Renders a sitemap for your ProcessWire powered site. Supports multi-language, multi-site, and image sub-elements. Adapted from MarkupSitemapXML.",
"href": "http://github.com/rockettpw/markup-sitemap",
"hrefsupport": "https://processwire.com/talk/topic/17068-markupsitemap/",
"license": "MIT",
"hreflicense": "http://mit-license.org/",
"permanent": false,
"autoload": true,
"singular": true
......
This diff is collapsed.
......@@ -20,22 +20,14 @@ class MarkupSitemapConfig extends ModuleConfig
{
return [
'sitemap_fieldset',
'sitemap_priority',
'sitemap_ignore_images',
'sitemap_ignore_page',
'sitemap_ignore_children',
'sitemap_fieldset_END',
];
}
/**
* Get default configuration, automatically passed to input fields.
* @return array
*/
public function getDefaults()
{
return [
];
}
/**
* Render input fields on config Page.
* @return string
......@@ -49,11 +41,8 @@ class MarkupSitemapConfig extends ModuleConfig
if ($template->flags & Template::flagSystem) {
continue;
}
// Also exclude the home template
if ($template->id !== $this->pages->get(1)->template->id) {
$templates[] = $template;
}
}
// If saving ...
if ($this->input->post->submit_save_module) {
......@@ -71,12 +60,18 @@ class MarkupSitemapConfig extends ModuleConfig
$sitemapFields = self::getDefaultFields();
unset($sitemapFields[count($sitemapFields) - 1]);
foreach ($this->fields as $sitemapField) {
if (preg_match('%^sitemap_(.*)%Uis', $sitemapField->name) && !in_array($sitemapField->name, self::getDefaultFields())) {
if (preg_match('%^sitemap_.*%Uis', $sitemapField->name)
&& !in_array($sitemapField->name, self::getDefaultFields())) {
array_push($sitemapFields, $sitemapField->name);
}
}
array_push($sitemapFields, 'sitemap_fieldset_END');
foreach ($sitemapFields as $templateField) {
if ($template->id === $this->pages->get(1)->template->id
&& in_array($templateField, ['sitemap_ignore_page',
'sitemap_ignore_children'])) {
continue;
}
$template->fields->add($this->fields->get($templateField));
}
$template->fields->save();
......@@ -100,11 +95,11 @@ class MarkupSitemapConfig extends ModuleConfig
$inputfields = parent::getInputfields();
// Add the template-selector field
$includeTemplatesField = $this->buildInputField('InputfieldAsmSelect', [
$includeTemplatesField = $this->buildInputField('AsmSelect', [
'name+id' => 'sitemap_include_templates',
'label' => 'Templates with sitemap-ignore options',
'description' => $this->_('Select which Templates (and, therefore, all Pages assigned to those templates) can have individual sitemap-ignore options. These options allow you to set which Pages and, optionally, their children should be excluded from the sitemap when it is rendered. In most common cases, you will not need to use this feature.'),
'notes' => 'If you remove any templates from this list, any sitemap-ignore options saved for Pages using those templates will be discarded when you save this configuration as the fields are completely removed from the assigned templates. **Please use with caution.**',
'label' => 'Templates with sitemap options',
'description' => $this->_('Select which templates (and, therefore, all pages assigned to those templates) can have individual sitemap options. These options allow you to set which pages and, optionally, their children should be excluded from the sitemap when it is rendered; define which page’s images should not be included in the sitemap (provided that image fields have been added below); and set an optional priority for each page.'),
'notes' => '**Please use with caution:** If you remove any templates from this list, any sitemap options saved for pages using those templates will be discarded when you save this configuration as the fields are completely removed from the assigned templates. Also note that the home page cannot be excluded from the sitemap. As such, the applicable options will not be available for the home page.',
'icon' => 'cubes',
'collapsed' => Inputfield::collapsedBlank,
]);
......@@ -114,10 +109,10 @@ class MarkupSitemapConfig extends ModuleConfig
$inputfields->add($includeTemplatesField);
// Add the image-field-selector field
$imageFieldsField = $this->buildInputField('InputfieldAsmSelect', [
$imageFieldsField = $this->buildInputField('AsmSelect', [
'name+id' => 'sitemap_image_fields',
'label' => $this->_('Image Fields'),
'description' => $this->_('If you’d like to include images in your sitemap (for somewhat enhanced Google Images support), specify the image fields you’d like MarkupSitemap to traverse and include. The sitemap will include images for every Page that uses the field(s) you select below.'),
'label' => $this->_('Image fields'),
'description' => $this->_('If you’d like to include images in your sitemap (for somewhat enhanced Google Images support), specify the image fields you’d like MarkupSitemap to traverse and include. The sitemap will include images for every page that uses the field(s) you select below, except for pages that are set to not have their images included.'),
'icon' => 'image',
'collapsed' => Inputfield::collapsedBlank,
]);
......@@ -129,6 +124,39 @@ class MarkupSitemapConfig extends ModuleConfig
}
$inputfields->add($imageFieldsField);
// Add the stylesheet checkbox
$inputfields->add($this->buildInputField('Checkbox', [
'name+id' => 'sitemap_stylesheet',
'label' => $this->_('Sitemap Stylesheet'),
'label2' => $this->_('Add a stylesheet to the sitemap'),
'icon' => 'css3',
]));
// Add the custom stylesheet text field
$inputfields->add($this->buildInputField('Text', [
'name+id' => 'sitemap_stylesheet_custom',
'label' => $this->_('Custom Stylesheet'),
'description' => $this->_('If you would like to use your own stylesheet, enter the absolute URL to its file here.'),
'placeholder' => $this->_('Example: https://example.tld/assets/sitemap-stylesheet.xsl'),
'showIf' => 'sitemap_stylesheet=1',
'notes' => $this->_('The default stylesheet is located at **assets/sitemap-stylesheet.xsl** in the module’s directory. If you leave this field blank or your input is not a valid URL, the default will be used.'),
'icon' => 'file-o',
'collapsed' => Inputfield::collapsedBlank,
]));
// Add the default-language iso text field
if ($this->siteUsesLanguageSupportPageNames()) {
$inputfields->add($this->buildInputField('Text', [
'name+id' => 'sitemap_default_iso',
'label' => $this->_('ISO code for default language'),
'description' => $this->_('If you’ve set your home page to not include a language ISO (default language name) **and** your home page’s default language name is empty, then you can set an ISO code here for the default language. This will prevent the sitemap from containing `hreflang="home"` for all default-language URLs.'),
'notes' => $this->_('Note that if your home page has a name for the default language, then this option will not take any effect.'),
'placeholder' => $this->_('en'),
'icon' => 'language',
'collapsed' => Inputfield::collapsedBlank,
]));
}
return $inputfields;
}
......@@ -140,8 +168,7 @@ class MarkupSitemapConfig extends ModuleConfig
*/
protected function buildInputField($fieldNameId, $meta)
{
$field = $this->modules->$fieldNameId;
$field = $this->modules->{"Inputfield{$fieldNameId}"};
foreach ($meta as $metaNames => $metaInfo) {
$metaNames = explode('+', $metaNames);
foreach ($metaNames as $metaName) {
......@@ -158,7 +185,7 @@ class MarkupSitemapConfig extends ModuleConfig
*/
protected function removeSitemapCache()
{
$cachePath = $this->config->paths->cache . MarkupSitemap::MARKUP_CACHE_MODULE . '/MarkupSitemap';
$cachePath = $this->config->paths->cache . 'MarkupCache/MarkupSitemap';
try {
$removed = (bool) CacheFile::removeAll($cachePath, true);
......@@ -168,4 +195,13 @@ class MarkupSitemapConfig extends ModuleConfig
return $removed;
}
/**
* Determine if the site uses the LanguageSupportPageNames module.
* @return bool
*/
protected function siteUsesLanguageSupportPageNames()
{
return $this->modules->isInstalled('LanguageSupportPageNames');
}
}
## Sitemap for ProcessWire
![Shield: Status = Beta](https://img.shields.io/badge/status-beta-orange.svg) ![Shield: Version = 0.1.2](https://img.shields.io/badge/version-0.1.2-blue.svg) ![Shield: License = MIT](https://img.shields.io/github/license/mikerockett/simpleforms.svg)
![Shield: Status = Beta](https://img.shields.io/badge/status-beta-orange.svg?style=flat-square)![Shield: Version = 0.2.0](https://img.shields.io/badge/version-0.2.0-blue.svg?style=flat-square)![Shield: License = MIT](https://img.shields.io/github/license/mikerockett/simpleforms.svg?style=flat-square)
MarkupSitemap is essentially an upgrade to MarkupSitemapXML by Pete. It adds multi-language support using the built-in LanguageSupportPageNames. Where multi-language pages are available, they are added to the sitemap by means of an alternate link in that page's `<url>`.
An upgrade to MarkupSitemapXML by Pete, MarkupSitemap adds multi-language support using the built-in LanguageSupportPageNames. Where multi-language pages are available, they are added to the sitemap by means of an alternate link in that page’s `<url>`. Support for listing images in the sitemap on a page-by-page basis and using a sitemap stylesheet are also added.
**Discussion:** https://processwire.com/talk/topic/17068-markupsitemap/
---
### Getting Started
In ProcessWire, install MarkupSitemap via the module installer. Enter `MarkupSitemap` into Modules > Install > New > Add Module from Directory.
### Usage
After installation, the sitemap will immediately be made available at `/sitemap.xml`.
If you’re looking for a basic sitemap, there’s nothing more you need to do. 🎇
---
### Configuration
If you’d like to fine-tune things a little, the module provides support for page-by-page configuration. If you’d like to make use of this, head to the module’s configuration page to get started.
#### Templates with sitemap options
With this option, you can select which templates (and, therefore, all pages assigned to those templates) can have individual sitemap options. These options allow you to —
- set which pages and, optionally, their children should be excluded from the sitemap (these options are independent of one another, so have the ability to hide a parent, but keep it’s children);
- define which page’s images should not be included in the sitemap (provided that image fields have been configured); and
- set an optional priority for each page.
When you add a template to the list and save, sitemap options will be added to the selected templates, and will be made available in the Settings tab of each page those templates use.
**Please use with caution:** If you remove any templates from the list, any sitemap options saved for pages using those templates will be discarded when you save the configuration as the fields are completely removed from the assigned templates.
Also note that the home page cannot be excluded from the sitemap. As such, the applicable options will not be available for the home page.
#### Image fields
If you’d like to include images in your sitemap (for somewhat enhanced Google Images support), you can specify the image fields you’d like MarkupSitemap to traverse and include. The sitemap will include images for every page that uses the field(s) you select, except for pages that are set to not have their images included (Settings tab).
#### Stylesheet
In the module’s configuration, you can also enable the default stylesheet. If you’d like to use your own, you’ll need to specify an absolute URL to it (also be sure to use one that has mult-language and sub-element features).
#### ISO code for default language
If you’ve set your home page to not include a language ISO (default language name) **and** your home page’s default language name is empty, then you can set an ISO code here for the default language. This will prevent the sitemap from containing `hreflang="home"` for all default-language URLs.
#### Page priority
On each page that has sitemap options, you can set a priority between 0.0 and 1.0. You may not need to use this any many cases, but you may wish to give emphasis to certain child pages over their parents. Search engines tend to use other factors in determining priority, and so this option is not guaranteed to make a difference to your rankings.
---
### Discussion & Support
Visit [processwire.com/talk/topic/17068-markupsitemap/](https://processwire.com/talk/topic/17068-markupsitemap/) to discuss the module and obtain support.
---
### Credits
### Tasklist
I’d like to thank [Mathew Davies](https://github.com/ThePixelDeveloper) for his [sitemap package](https://github.com/ThePixelDeveloper/Sitemap). It’s really great, sans a few bugs (which is why a local fork is maintained within this module).
- [ ] Do a little more work on multi-language support to avoid content duplication in the case that the default language and the first language have the same content.
---
......
This diff is collapsed.
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "16a2aed5d58589c937316b07035e0b31",
"packages": [
{
"name": "thepixeldeveloper/sitemap",
"version": "4.5.2",
"source": {
"type": "git",
"url": "https://github.com/ThePixelDeveloper/Sitemap.git",
"reference": "cde221cbd76035328dbcd35caaf000ad9f7d8174"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ThePixelDeveloper/Sitemap/zipball/cde221cbd76035328dbcd35caaf000ad9f7d8174",
"reference": "cde221cbd76035328dbcd35caaf000ad9f7d8174",
"shasum": ""
},
"require": {
"php": ">=5.6.0"
},
"require-dev": {
"phpspec/phpspec": "^2.4"
},
"type": "library",
"autoload": {
"psr-4": {
"Thepixeldeveloper\\Sitemap\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Mathew Davies",
"email": "[email protected]",
"homepage": "http://mathew-davies.co.uk",
"role": "Developer"
}
],
"description": "XML sitemap generation",
"keywords": [
"Sitemap",
"xml"
],
"time": "2017-07-26T13:35:41+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}
<?php
namespace Thepixeldeveloper\Sitemap;
/**
* Sitemap for PHP. Eloquent sitemap creation with sub-element support.
* https://github.com/ThePixelDeveloper/Sitemap/
* Local fork maintained by Mike Rockett for MarkupSitemap.
*
* @copyright 2013, Mathew Davies <[email protected]>
* @license MIT
*/
namespace Rockett\Sitemap\Contracts;
use XMLWriter;
/**
* Interface AppendAttributeInterface
*
* @package Thepixeldeveloper\Sitemap
* @package Rockett\Sitemap
*/
interface AppendAttributeInterface
interface AppendAttributeContract
{
/**
* Appends an attribute to the collection XML attributes.
*
* @param XMLWriter $XMLWriter
*
* @return void
*/
public function appendAttributeToCollectionXML(XMLWriter $XMLWriter);
......
<?php
namespace Thepixeldeveloper\Sitemap;
/**
* Sitemap for PHP. Eloquent sitemap creation with sub-element support.
* https://github.com/ThePixelDeveloper/Sitemap/
* Local fork maintained by Mike Rockett for MarkupSitemap.
*
* @copyright 2013, Mathew Davies <[email protected]>
* @license MIT
*/
namespace Rockett\Sitemap\Contracts;
use XMLWriter;
/**
* Interface OutputInterface
*
* @package Thepixeldeveloper\Sitemap
* @package Rockett\Sitemap
*/
interface OutputInterface
interface OutputContract
{
/**
* Generate the XML for a given element / sub-element.
*
* @param XMLWriter $XMLWriter
*
* @return void
*/
public function generateXML(XMLWriter $XMLWriter);
......
<?php
namespace Thepixeldeveloper\Sitemap;
/**
* Sitemap for PHP. Eloquent sitemap creation with sub-element support.
* https://github.com/ThePixelDeveloper/Sitemap/
* Local fork maintained by Mike Rockett for MarkupSitemap.
*
* @copyright 2013, Mathew Davies <[email protected]>
* @license MIT
*/
namespace Rockett\Sitemap\Elements;
use Rockett\Sitemap\Contracts\AppendAttributeContract;
use Rockett\Sitemap\Contracts\OutputContract;
use XMLWriter;
/**
* Class Url
*
* @package Thepixeldeveloper\Sitemap
* @package Rockett\Sitemap\Elements
*/
class Url implements OutputInterface
class Url implements OutputContract
{
/**
* Location (URL).
* Change frequency of the location.
*
* @var string
*/
protected $loc;
protected $changeFreq;
/**
* Last modified time.
......@@ -26,11 +37,11 @@ class Url implements OutputInterface
protected $lastMod;
/**
* Change frequency of the location.
* Location (URL).
*
* @var string
*/
protected $changeFreq;
protected $loc;
/**
* Priority of page importance.
......@@ -42,16 +53,16 @@ class Url implements OutputInterface
/**
* Array of sub-elements.
*
* @var OutputInterface[]
* @var OutputContract[]
*/
protected $subelements = [];
protected $subElements = [];
/**
* Sub-elements that append to the collection attributes.
*
* @var AppendAttributeInterface[]
* @var AppendAttributeContract[]
*/
protected $subelementsThatAppend = [];
protected $subElementsThatAppend = [];
/**
* Url constructor
......@@ -63,6 +74,23 @@ class Url implements OutputInterface
$this->loc = $loc;
}
/**
* Add a new sub element.
*
* @param OutputContract $subElement
* @return $this
*/
public function addSubElement(OutputContract $subElement)
{
$this->subElements[] = $subElement;
if ($this->isSubElementGoingToAppend($subElement)) {
$this->subElementsThatAppend[get_class($subElement)] = $subElement;
}
return $this;
}
/**
* @param XMLWriter $XMLWriter
*/
......@@ -75,31 +103,31 @@ class Url implements OutputInterface
$this->optionalWriteElement($XMLWriter, 'changefreq', $this->getChangeFreq());
$this->optionalWriteElement($XMLWriter, 'priority', $this->getPriority());
foreach ($this->getSubelements() as $subelement) {
$subelement->generateXML($XMLWriter);
foreach ($this->getSubElements() as $subElement) {
$subElement->generateXML($XMLWriter);
}
$XMLWriter->endElement();
}
/**
* Array of sub-elements.
* Get change frequency.
*
* @return OutputInterface[]
* @return null|string
*/
public function getSubelements()
public function getChangeFreq()
{
return $this->subelements;
return $this->changeFreq;
}
/**
* Array of sub-elements that append to the collections attributes.
* Get last modification time.
*
* @return AppendAttributeInterface[]
* @return null|string
*/
public function getSubelementsThatAppend()
public function getLastMod()
{
return $this->subelementsThatAppend;
return $this->lastMod;
}
/**
......@@ -113,58 +141,39 @@ class Url implements OutputInterface
}
/**
* Only write the XML element if it has a truthy value.
*
* @param XMLWriter $XMLWriter
* @param string $name
* @param string $value
*/
protected function optionalWriteElement(XMLWriter $XMLWriter, $name, $value)
{
if ($value) {
$XMLWriter->writeElement($name, $value);
}
}
/**
* Get last modification time.
* Url priority.
*
* @return null|string
*/
public function getLastMod()
public function getPriority()
{
return $this->lastMod;
return $this->priority;
}
/**
* Set last modification time.
*
* @param string $lastMod
* Array of sub-elements.
*
* @return $this
* @return OutputContract[]
*/
public function setLastMod($lastMod)
public function getSubElements()
{
$this->lastMod = $lastMod;
return $this;
return $this->subElements;
}
/**
* Get change frequency.
* Array of sub-elements that append to the collections attributes.
*
* @return null|string
* @return AppendAttributeContract[]
*/
public function getChangeFreq()
public function getSubElementsThatAppend()
{
return $this->changeFreq;
return $this->subElementsThatAppend;
}
/**
* Set change frequency.
*
* @param string $changeFreq
*
* @return $this
*/
public function setChangeFreq($changeFreq)
......@@ -175,20 +184,22 @@ class Url implements OutputInterface
}
/**
* Url priority.
* Set last modification time.
*
* @return null|string
* @param string $lastMod
* @return $this
*/
public function getPriority()
public function setLastMod($lastMod)
{
return $this->priority;
$this->lastMod = $lastMod;
return $this;
}
/**
* Set priority.
*
* @param string $priority
*
* @return $this
*/
public function setPriority($priority)
......@@ -199,36 +210,31 @@ class Url implements OutputInterface
}
/**
* Add a new sub element.
*
* @param OutputInterface $subElement
* Checks if the sub-element is going to append collection attributes.
*
* @return $this
* @param OutputContract $subElement
* @return boolean
*/
public function addSubElement(OutputInterface $subElement)
protected function isSubElementGoingToAppend(OutputContract $subElement)
{
$this->subelements[] = $subElement;
if ($this->isSubelementGoingToAppend($subElement)) {
$this->subelementsThatAppend[get_class($subElement)] = $subElement;
if (!$subElement instanceof AppendAttributeContract) {
return false;
}
return $this;
return !in_array(get_class($subElement), $this->subElementsThatAppend, false);
}
/**
* Checks if the sub-element is going to append collection attributes.
*
* @param OutputInterface $subelement
* Only write the XML element if it has a truthy value.
*
* @return boolean
* @param XMLWriter $XMLWriter
* @param string $name
* @param string $value