jwiese Posted October 11, 2016 Posted October 11, 2016 Hello, lets say i use something like: $p = wire('pages')->get('/'); foreach($p->getLanguages() as $lang){ echo($p->localHttpUrl($lang)); } I am working on the site-languages installation. At a template, it works great. But in a Module it fails with Error: Exception: Method Page::localHttpUrl does not exist or is not callable in this context Interestingly it does not crash at getLanguages(). What do i miss? Thanks for your help, keksmampfer *Update: for to foreach
kixe Posted October 11, 2016 Posted October 11, 2016 @keksmampfer Welcome to the forum. You are using wrong syntax for PHP for() which is: for (expr1; expr2; expr3) Assuming you are talking about foreach(). Using foreach, your code should work within a module too. If you would post the context or function from where you call this loop within the modules class, it would be easier to help. 3
jwiese Posted October 11, 2016 Author Posted October 11, 2016 Sorry! yes i am talking about foreach. <?php namespace ProcessWire; class MarkupSitemapXMLmin extends WireData implements Module { private $multilang; /** * Provide information about this module to ProcessWire * */ public static function getModuleInfo() { return array( 'title' => 'Markup Sitemap XMLmin', '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' => 126, 'permanent' => false, 'autoload' => true, 'singular' => true, ); } /** * Add the hook * */ public function init() { $urlParams = ''; $this->multilang = false; // Intercept a request for an URL ending in sitemap.xml and output if (isset($_SERVER['REQUEST_URI']) && strlen($_SERVER['REQUEST_URI']) - strlen('/sitemap.xml' . $urlParams) === strrpos($_SERVER['REQUEST_URI'], '/sitemap.xml' . $urlParams)) { $this->addHookBefore("ProcessPageView::pageNotFound", $this, "renderSitemap"); } } public function renderSitemap(HookEvent $event) { $this->pageselector = ''; $startPage = str_ireplace(trim(wire('config')->urls->root, '/'), '', $this->sanitizer->path(dirname($_SERVER['REQUEST_URI']))); // 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("LanguageSupport")) { $this->multilang = true; } // Check for the cached sitemap, else generate and cache a fresh sitemap $startpagestr = $this->sanitizer->pageName($startPage); $output = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"; $output .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'; $output .= $this->sitemapListPage($this->wire('pages')->get($startPage)); $output .= "\n</urlset>"; header("Content-Type: text/xml", true, 200); echo $output; exit(); } private function renderSitemapEntry($url, $modified) { return "<url>\n" . "<loc>{$url}</loc>\n" . "<lastmod>{$modified}</lastmod>\n" . "</url>\n"; } 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); if (!$this->multilang) { $entry .= $this->renderSitemapEntry($page->httpUrl, $modified); } else { foreach ($page->getLanguages() as $lang) { $entry .= $this->renderSitemapEntry($page->localHttpUrl($lang), $modified); } } } // Fix #12 by FlipZoomMedia | David Karich $children = $page->children($this->pageselector); if (count($children)) { foreach ($children as $child) { $entry .= $this->sitemapListPage($child); } } return $entry; } }
BitPoet Posted October 11, 2016 Posted October 11, 2016 Just to close in on the cause: does placing this line in your module's init function help? $this->modules->get('LanguageSupportPageNames');
adrian Posted October 11, 2016 Posted October 11, 2016 Namespace issue? Is the template being processed by the file compiler, but this module isn't?
jwiese Posted October 11, 2016 Author Posted October 11, 2016 Setting 'requires' => array("LanguageSupport","LanguageSupportPageNames") does not help and this would break the compatibility to single language pages. Using $this->wire("pages")->get($startPage) or $this->pages->get($startPage) makes no difference. Okay i found it. The Page::localHttpUrl hook is defined at ready() and that is too late for this script. For test purpose moving the hook to init() makes the module work. So changing $this->addHookBefore("ProcessPageView::pageNotFound", $this, "renderSitemap"); to $this->addHook("ProcessPageView::pageNotFound", $this, "renderSitemap"); fixes it. Thank you for your time 3
adrian Posted October 11, 2016 Posted October 11, 2016 Just for your own clarity, it might be better to use addHookAfter, because addHook can actually be used to add your own method to a class. https://processwire.com/api/hooks/ 1
jwiese Posted October 11, 2016 Author Posted October 11, 2016 Okay, thank you. If someone is interested, I have updated the MarkupSitemapXML plugin to ProcressWire 3+ https://github.com/keksmampfer/ProcessWire3-MarkupSitemapXML 4
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now