Search the Community
Showing results for 'runtime'.
-
PW will adapt wherever you put it, whether on a subdirectory, different domain, subdomain, etc. You don't have to tell it anything about where it's running because it figures it out at runtime. It's a little harder to design the CMS that way (which is why most CMSs don't do it), but I think it's well worth it. Likewise, it doesn't care whether it's being accessed by HTTPS or not unless you specify that you only want one or the other in your template settings. Because you are using a different domain for HTTPS, you'll want to skip using that template setting and instead do this: To detect if the request is coming from an HTTPS connection: <?php if($config->https) { // user is on an HTTPS connection } else { // regular HTTP } If you wanted to logged-in users to always redirect to the same page at a different domain, you'd do this: <?php if($user->isLoggedin && !$config->https) { // redirect to the same page at the alternate https domain $session->redirect("https://clientname-fi.pwire.fi" . $page->url); } else { // user is in the right place } You probably want to put that in some universal/header include file so that you don't have to code it in more than one spot.
-
Wiping the entire cache on every page save is a good idea to at least provide. In a system like PW, a given page might pull from several others that are determined at runtime. So there's no way the CMS can know all the possible interrelationships ahead of time. As a result, expiring the cache on every page save is the only way to know for sure that the site is delivering fully up-to-date pages. On the other hand, it's rare that I actually need the entire cache to expire on every save... and if I really need it for some reason, I go to Modules > Page Render > Clear Cache. But caching can be a difficult concept for a client to really understand sometimes, so having the entire cache expire on every page save can reduce the support burden. So in one of these near-term commits, I'm going to go ahead and add an option to the Template editor that says: When I save a page: 1. Expire the cache for the saved page only. 2. Expire the cache for all pages. Being able to specify that at the template level will provide a lot of flexibility.
-
Just running into a bit of trouble saving my page content via this module. I've set it to only run the module if the page's parent is the news page and with xDegug turned on on my XAMPP server it says it's stuck in a loop (without xDebug on it just crashes Apache). Here's a very stripped-down version of my module with the issue: <?php /** * ProcessWire 'Hello world' demonstration module * * Demonstrates the Module interface and how to add hooks. * * ProcessWire 2.x * Copyright (C) 2010 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * * http://www.processwire.com * http://www.ryancramer.com * */ class Newstopic extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( // The module's title, typically a little more descriptive than the class name 'title' => 'News Topic Create', // version: major, minor, revision, i.e. 100 = 1.0.0 'version' => 100, // summary is brief description of what this module is 'summary' => 'Creates a topic for each new news article that is saved. Checks none exists currently.', // Optional URL to more information about the module 'href' => 'http://www', // singular=true: indicates that only one instance of the module is allowed. // This is usually what you want for modules that attach hooks. 'singular' => true, // autoload=true: indicates the module should be started with ProcessWire. // This is necessary for any modules that attach runtime hooks, otherwise those // hooks won't get attached unless some other code calls the module on it's own. // Note that autoload modules are almost always also 'singular' (seen above). 'autoload' => true, ); } /** * Initialize the module * * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. * */ public function init() { // add a hook after the $pages->save, to issue a notice every time a page is saved $this->pages->addHookAfter('save', $this, 'createNewsTopic'); // add a hook after each page is rendered and modify the output //$this->addHookAfter('Page::render', $this, 'example2'); // add a 'hello' method to every page that returns "Hello World" //$this->addHook('Page::hello', $this, 'example3'); // add a 'hello_world' property to every page that returns "Hello [user]" //$this->addHookProperty('Page::hello_world', $this, 'example4'); } /** * Example1 hooks into the pages->save method and displays a notice every time a page is saved * */ public function createNewsTopic($event) { $page = $event->arguments[0]; // Check it's a news article if ($page->parent_id == 5831) { // If the hidden news_topic field for this article is empty, then we'll create a topic if (empty($page->news_topic)) { echo "It's empty"; $page->news_topic = 123; } else { echo "It's got a value"; $page->news_topic = ''; $page->save(); } exit; //$this->message("Hello World! You saved {$page->path}."); } } } and here's the debug info from xDebug: ( ! ) Fatal error: Maximum function nesting level of '100' reached, aborting! in C:\xampp\htdocs\sc11\wire\core\Wire.php on line 229 Call Stack # Time Memory Function Location 1 0.0035 392416 {main}( ) ..\index.php:0 2 0.2985 7064064 ProcessPageView->execute( ) ..\index.php:170 3 0.2985 7064216 Wire->__call( ) ..\Wire.php:0 4 0.2985 7064216 Wire->runHooks( ) ..\Wire.php:229 5 0.2985 7065264 call_user_func_array ( ) ..\Wire.php:267 6 0.2985 7065400 ProcessPageView->___execute( ) ..\Wire.php:0 7 0.3080 7109160 Page->render( ) ..\ProcessPageView.module:73 8 0.3080 7109312 Wire->__call( ) ..\Wire.php:0 9 0.3080 7109312 Wire->runHooks( ) ..\Wire.php:229 10 0.3082 7112336 PageRender->renderPage( ) ..\Wire.php:289 11 0.3082 7112536 Wire->__call( ) ..\Wire.php:0 12 0.3082 7112536 Wire->runHooks( ) ..\Wire.php:229 13 0.3082 7113584 call_user_func_array ( ) ..\Wire.php:267 14 0.3082 7113768 PageRender->___renderPage( ) ..\Wire.php:0 15 0.3102 7157328 TemplateFile->render( ) ..\PageRender.module:194 16 0.3102 7157480 Wire->__call( ) ..\Wire.php:0 17 0.3102 7157480 Wire->runHooks( ) ..\Wire.php:229 18 0.3103 7158528 call_user_func_array ( ) ..\Wire.php:267 19 0.3103 7158664 TemplateFile->___render( ) ..\Wire.php:0 20 0.3117 7204976 require( 'C:\xampp\htdocs\sc11\site\templates\admin.php' ) ..\TemplateFile.php:88 21 0.3122 7206648 require( 'C:\xampp\htdocs\sc11\wire\templates-admin\controller.php' ) ..\admin.php:13 22 0.3130 7239504 require( 'C:\xampp\htdocs\sc11\wire\core\admin.php' ) ..\controller.php:13 23 0.3264 7437216 ProcessController->execute( ) ..\admin.php:42 24 0.3264 7437368 Wire->__call( ) ..\Wire.php:0 25 0.3264 7437368 Wire->runHooks( ) ..\Wire.php:229 26 0.3265 7438416 call_user_func_array ( ) ..\Wire.php:267 27 0.3265 7438552 ProcessController->___execute( ) ..\Wire.php:0 28 0.3436 8017272 ProcessPageEdit->execute( ) ..\ProcessController.php:194 29 0.3436 8017424 Wire->__call( ) ..\Wire.php:0 30 0.3437 8017424 Wire->runHooks( ) ..\Wire.php:229 31 0.3437 8018472 call_user_func_array ( ) ..\Wire.php:267 32 0.3437 8018608 ProcessPageEdit->___execute( ) ..\Wire.php:0 33 0.4291 9419280 ProcessPageEdit->processSave( ) ..\ProcessPageEdit.module:94 34 0.4475 9558616 Page->save( ) ..\ProcessPageEdit.module:160 35 0.4475 9558784 Pages->save( ) ..\Page.php:791 36 0.4475 9558984 Wire->__call( ) ..\Wire.php:0 37 0.4475 9558984 Wire->runHooks( ) ..\Wire.php:229 38 0.4509 9545040 Newstopic->createNewsTopic( ) ..\Wire.php:289 39 0.6296 23635104 Page->save( ) ..\Newstopic.module:103 40 0.6296 23635272 Pages->save( ) ..\Page.php:791 41 0.6296 23635472 Wire->__call( ) ..\Wire.php:0 42 0.6296 23635472 Wire->runHooks( ) ..\Wire.php:229 43 0.6352 23644064 Newstopic->createNewsTopic( ) ..\Wire.php:289 44 0.6370 23644512 Page->save( ) ..\Newstopic.module:103 45 0.6370 23644680 Pages->save( ) ..\Page.php:791 46 0.6370 23644880 Wire->__call( ) ..\Wire.php:0 47 0.6370 23644880 Wire->runHooks( ) ..\Wire.php:229 48 0.6392 23648016 Newstopic->createNewsTopic( ) ..\Wire.php:289 49 0.6400 23648136 Page->save( ) ..\Newstopic.module:103 50 0.6400 23648304 Pages->save( ) ..\Page.php:791 51 0.6400 23648504 Wire->__call( ) ..\Wire.php:0 52 0.6400 23648504 Wire->runHooks( ) ..\Wire.php:229 53 0.6425 23651408 Newstopic->createNewsTopic( ) ..\Wire.php:289 54 0.6441 23651856 Page->save( ) ..\Newstopic.module:103 55 0.6441 23652024 Pages->save( ) ..\Page.php:791 56 0.6441 23652224 Wire->__call( ) ..\Wire.php:0 57 0.6441 23652224 Wire->runHooks( ) ..\Wire.php:229 58 0.6461 23655296 Newstopic->createNewsTopic( ) ..\Wire.php:289 59 0.6468 23655416 Page->save( ) ..\Newstopic.module:103 60 0.6468 23655584 Pages->save( ) ..\Page.php:791 61 0.6468 23655784 Wire->__call( ) ..\Wire.php:0 62 0.6468 23655784 Wire->runHooks( ) ..\Wire.php:229 63 0.6487 23658696 Newstopic->createNewsTopic( ) ..\Wire.php:289 64 0.6502 23659144 Page->save( ) ..\Newstopic.module:103 65 0.6503 23659312 Pages->save( ) ..\Page.php:791 66 0.6503 23659512 Wire->__call( ) ..\Wire.php:0 67 0.6503 23659512 Wire->runHooks( ) ..\Wire.php:229 68 0.6522 23662584 Newstopic->createNewsTopic( ) ..\Wire.php:289 69 0.6530 23662704 Page->save( ) ..\Newstopic.module:103 70 0.6530 23662872 Pages->save( ) ..\Page.php:791 71 0.6530 23663072 Wire->__call( ) ..\Wire.php:0 72 0.6530 23663072 Wire->runHooks( ) ..\Wire.php:229 73 0.6551 23665984 Newstopic->createNewsTopic( ) ..\Wire.php:289 74 0.6567 23666432 Page->save( ) ..\Newstopic.module:103 75 0.6567 23666600 Pages->save( ) ..\Page.php:791 76 0.6567 23666800 Wire->__call( ) ..\Wire.php:0 77 0.6567 23666800 Wire->runHooks( ) ..\Wire.php:229 78 0.6586 23669872 Newstopic->createNewsTopic( ) ..\Wire.php:289 79 0.6593 23669992 Page->save( ) ..\Newstopic.module:103 80 0.6593 23670160 Pages->save( ) ..\Page.php:791 81 0.6593 23670360 Wire->__call( ) ..\Wire.php:0 82 0.6593 23670360 Wire->runHooks( ) ..\Wire.php:229 83 0.6593 23671432 call_user_func_array ( ) ..\Wire.php:267 84 0.6593 23671616 Pages->___save( ) ..\Wire.php:0 85 0.6604 23673256 FieldtypeInteger->savePageField( ) ..\Pages.php:421 86 0.6604 23673504 Wire->__call( ) ..\Wire.php:0 87 0.6604 23673504 Wire->runHooks( ) ..\Wire.php:229 88 0.6604 23674560 call_user_func_array ( ) ..\Wire.php:267 89 0.6604 23674792 Fieldtype->___savePageField( ) ..\Wire.php:0 90 0.6605 23674952 FieldtypeInteger->deletePageField( ) ..\Fieldtype.php:504 91 0.6605 23675200 Wire->__call( ) ..\Wire.php:0 92 0.6605 23675200 Wire->runHooks( ) ..\Wire.php:229 93 0.6605 23676256 call_user_func_array ( ) ..\Wire.php:267 94 0.6606 23676488 Fieldtype->___deletePageField( ) ..\Wire.php:0 95 0.6606 23676520 WireData->__unset( ) ..\Data.php:0 96 0.6606 23676520 WireData->remove( ) ..\Data.php:169 97 0.6606 23676480 Wire->trackChange( ) ..\Data.php:133 98 0.6606 23676632 Page->changed( ) ..\Wire.php:504 99 0.6606 23676832 Wire->__call( ) ..\Wire.php:0 This error message was shown because the site is in DEBUG mode. Any ideas why it might be going crazy nesting functions like that?
-
If the page in question actually has a field called 'process', then checking $page->process is going to return the value of that field. But $this->process [or wire('process')] is a runtime property that is made available to the system and represents the process that is currently running. My guess is that you probably don't want to be looking at the $page->process.
-
Ok, this helped a lot. &modal=1 is added by AdminBar (line 280): <?php /** * Hook to take place right before a redirect occurs * * We intercept the redirect URL and modify it to add 'modal=1' to the query string * */ public function sessionRedirect($event) { if(!$this->page || $this->page->template != 'admin') return; if(!$this->input->get->modal) return; $url = $event->arguments(0); if(preg_match('/[?&]modal=/', $url)) return; $url .= (count($this->input->get) ? '&' : '?') . "modal=1"; $event->arguments(0, $url); } If I comment $url .=... line out, then it redirects to admin page, but there is "you are logged in" notification in place. Same happens if I go directly to /processwire/adminbar/ab-sitemap/. But if I go to setup -> templates and set that "adminbar" template manages it's access and set it to go 404 page when there is no access, then I go to 404 page. So this is definitely some kind of access problem. Maybe in page create? <?php // create /adminbar/ page under admin $abPage = new Page(); $abPage->template = $abTemplate; $abPage->parent = $this->pages->get($this->config->adminRootPageID); $abPage->name = $abName; $abPage->status = 1031; // hidden & locked $abPage->save(); // after that create /adminbar/sitemap/ $abSitemapPage = new Page(); $abSitemapPage->template = $abTemplate; $abSitemapPage->parent = $abPage; $abSitemapPage->name = 'ab-sitemap'; $abSitemapPage->status = 1031; return $abSitemapPage->save(); There is no view button on adminbar pages when browsing page tree, but this must be because there is no actual template file (we set that at runtime): <?php // We change the filepath of adminbar template file public function beforePageRender($event) { $page = $event->object; if($page->template == 'adminbar') { $page->template->filename = $this->config->paths->AdminBar . "templates/sitemap.php"; } } And I get this working when I copy /site/modules/AdminBar/templates/sitemap.php to /site/templates/sitemap.php and after that edit template "adminbar" and "advanced" tab, and set it to use sitemap.php template. So this is pretty minor issue, but not sure if I understand where the real problem lies?
-
This is one of the potential problems with using the WireSaveableItems, because the default behavior is that they load an entire table and all it's rows in memory at runtime. This is desirable for things like templates and fields because we need all this stuff in memory to build pages, and don't necessarily know what we'll need ahead of time. But for large inventories of information, there might be memory or speed issues as the number of items increases. To account for this, you can specify a selector to the load() function to tell it what you want with a selector string: $this->load($this->videosArray, "limit=10, sort=id"); That selector string can have both "start" and "limit" and "sort" options for pagination. You can also have it match any given field name in your table. For operators, you are limited to: =, <, >, !=. With those limitations in mind, they work like selectors on pages in all other respects. I also want to mention that ProcessWire does not currently use this feature of the WireSaveableItems class, so if you use it, you are the first to test it. Let me know if you run into any issues and we'll get them fixed. That's correct, but that pagination is only specific to pages. You can certainly use pagination with your module, but you'll need to specify the "start" and "limit" options to your load function manually. (When it comes to paginating actual pages, ProcessWire takes care of the "start" part for you.) When working in a database client (like PHPMyAdmin) it's true that your view of the data will be in a traditional single-table format, unlike pages where fields occupy their own table. But within ProcessWire, the view is just a manner of how you use the API code. The way you work with items coming from a WireSaveableItems class and items coming from pages is going to be the same. For example, in this part of your code: <?php $table = $this->modules->get("MarkupVideoDataTable"); $table->headerRow(array( 'Volume', 'Name', 'Description', 'Event Date', 'Price', )); foreach($videos as $video) { $volume = 'Vol. '.$video->volume; $table->row(array( $volume => "edit?id={$video->id}", $video->name, $video->description, $video->eventDate, $video->price, )); } ...$videos could just as easily be a PageArray (like from $pages->find(...) or $page->children(...), etc.), and it could be substituted without any changes. So while there is a difference in the view at the database table level, there isn't any difference at the ProcessWire API level. I don't want to talk you out of the approach you are taking, because I like what you are doing and am thrilled to see some of these classes get used outside the core -- so stick with it, and I'll be here to help. But I also want to make sure I communicate that the data you are working with is exactly what pages were designed for. Pages are data containers of a defined type (template) with defined fields... they may or may not represent an actual page on your web site, that's up to you. But pages are really useful for building huge inventories of data and making it easy to view, search and manipulate, and even change it's structure without changing your code. Think of pages like you would a node in Drupal... they may represent a page on your site, but their intended use is much more abstract than that. You can! Lets say that Users were pages. Here is how you would load an filter them by role at the same time: <?php $users = $this->pages->find("template=user, role=superuser"); foreach($users as $user) { ... } // output them in the same manner as ProcessUser.module This approach has an advantage over what's being done in ProcessUser.module right now, because it only loads the users that match the filter. The way ProcessUser works right now is that it iterates through all the users and skips the iteration if the filter doesn't match. Here's another example more specific to your case, filtering by volume number: <?php $videos = $this->pages->find("template=video, volume=123"); forech($videos as $video { ... } ...or... <?php $videos = $this->pages->get("/path/to/videos/")->children("volume=123"); foreach($video as $video) { ... } Of course, ProcessWire does this filtering at the database level (not in memory). That makes sense, and there are very good reasons for having something completely separate from a storage standpoint. From an organization standpoint, the main difference would be that the videos don't appear anywhere in the page structure. But I think your ProcessVideo.module would be equally useful whether videos are pages or WireSaveableItems (and the code behind it would likely be very much the same). Each page is assigned a template that defines it's data structure, and optionally provides a file where you can produce output for the page's URL. But that part is totally optional. If you choose to display them in some other way, the manner in which you do it should be the same. I built pages for this purpose, so that's the approach I would take myself. But I also think you have good reasons for the approach you've taken and there's nothing wrong with it. There are both tradeoffs and benefits which only you can evaluate what is best for your needs. If I'm understanding it all correctly, here are a few of the pros for your approach: 1) it can be more efficient if you are careful about how much data you load at once; 2) the data relates directly to a table, making it a simpler matter if you like to work directly in SQL; 3) it's compartmentalized, not relying upon prerequisite fieldtypes or templates (which may make for simpler portability if you distribute the module). I think in your case it is a good approach because you have PHP knowledge and know your way around code, and I am glad to see you doing it ... it also helps me to make a better product when people push the utility of these core classes. Thanks, Ryan
-
In your /site/config.php there is a setting in there called: $config->loginPageID = 23; Change 23 to the ID of the page you want to be the login page. If you want to use a given login page only in some instances, I believe you can also change that $config item at runtime. For example, you might put this in some main template for your site: $config->loginPageID = $pages->get("/tools/login/")->id; I haven't tried this, so let me know if it doesn't work and I can find another way to do it or make it part of the template config as you suggested.
-
I think it might be better to just override the template rather than putting one in the /templates/ dir (unless you want to encourage them to edit it). I've modified the Template class so that you can change the target filename at runtime, so you'll want to grab the latest commit. https://github.com/ryancramerdesign/ProcessWire/commit/0c8dc7d8e62c9a6a110791e00111c463ff00b01c Next, move that template to the same directory as your module (/site/modules/AdminBar/adminbar.php). Then in your AdminBar.module, add a new "before" page render hook. It will check to see if the page template is "adminbar", and if it is, it'll change the template filename to the one in your /site/modules/AdminBar/ dir. <?php public function beforePageRender($event) { $page = $event->object; if($page->template == 'adminbar') { $page->template->filename = $this->config->paths->AdminBar . "adminbar.php"; } } Also, add this to your init() function in AdminBar.module: $this->addHookBefore('Page::render', $this, 'beforePageRender'); If you do decide you want it to check if the file is in your /site/templates/ first, then just add that check to your beforePageRender method. Now it should work exactly the same as before, except that it'll use the template file in your /site/modules/AdminBar/ dir rather than expecting one to be in /site/templates/.
-
Is there way to get information about current user in templates?
ryan replied to apeisa's topic in API & Templates
I'll be happy to get you started with a "blank" module that you can build it on top of. What I recommend is that we hook into the Page::render method, grab it's output, and insert your js and css markup file links right before a page's closing </head> tag. That way, when someone installs the module, it'll just start working without them having to do anything on their own. Of course there will be those that want to control the placement of those things, so I'll show you how to make that configurable. The PHP code that is in your .inc will become the module code. Let me know if this sounds like a good plan to you, and I'll follow up with posts showing you how. There are definitely merits to inline editing, depending on the site. I view the needs of page viewing and page editing as fundamentally different, and prefer to have an interface that is designed for one or the other (though the 'overlay', like in Drupal, and in your example, is a nice compromise). But there are many cases where it is really handy to be able to edit inline, if the site design supports it. As an example, I like to make moderated comment approval inline, so that I can just click "approve" or "spam" while viewing the comments (though Akismet mostly does that for me now). There are plenty of other cases, and I'm betting that Aloha Editor will provide some good opportunities. I think you'll find ProcessWire works well when you want something to be editable inline. On the front end, you would just need to make sure that the page is editable before including the inline editors, i.e. if($page->editable()) { ... }. Then you'll need for your template, include or module to look for when they've clicked 'save', i.e. <?php if($input->post->submit_save && $page->editable()) { // turn off runtime formatters (like entities, markdown, date formats, etc). $page->setOutputFormatting(false); // go through all the submitted fields and set those that are applicable foreach($input->post as $field => $value) { if($page->fields->has($field)) $page->set($field, $value); } // if the above resulted in a change, then save the page if($page->isChanged()) $page->save(); // turn output formatting back on so it's in the proper state for viewing $page->setOutputFormatting(true); } Note that if the "save" button is just attached to individual fields, and you'll only be saving one field at a time (possibly ajax driven), then you may want to just save the field rather than the whole page, i.e. $page->save('field name'); -
Publish/Unpublish by date or by manual means.
ryan replied to moondawgy's topic in Wishlist & Roadmap
I will add this to the roadmap as a module (most likely a Fieldtype). But also wanted to follow up with the strategy that I use, and the reason why the need for a publish/unpublish by date has not come up before. It's because this is so easily accomplished with the API. It also gives you more control over how you want to react to such dates. Here's how: Lets say I added a datetime field for publish date and/or expire date to the page's template. That template checks it's dates before it outputs anything. For example, lets assume we added a datetime field to the job_advert template called "expire_date". When we edited a job advert, we selected an expire_date of February 1, 2011. The job_advert template might have code like this: <?php if(time() > $page->getUnformatted('expire_date')) { throw new PageNotFoundException(); // or print "sorry this posting has expired" if you don't want a 404 } // print the job advert Note that the getUnformatted() function above is necessary because ProcessWire will return a formatted date according to the format you specified when you created the field, "January 21, 2011" as an example. So using getUnformatted() is a way to ensure it returns a timestamp that you can use for comparison with other timestamps (like that returned by PHP's time() function). (Btw, that getUnformatted() function works with any field, returning text fields without entities or runtime markup, etc.) Lets say that you also wanted to move the job advert to the trash since we now know it's expired: <?php if(time() > $page->getUnformatted('expire_date')) { $pages->trash($page); // move it to the trash throw new PageNotFoundException(); } // print the job advert Next lets assume that you didn't move the page to the trash, but you are just leaving it where it is and not disabling it or anything. If that's the case, you'll want to check that it's not expired when you links to your job adverts. So here's what your list_job_adverts template might look like: <?php $now = time(); $jobs = $page->children("expire_date>$now"); foreach($jobs as $job) { // print the job listing, being confident that it's not expired } If you had both expire_date and publish_date fields, then you'd find those jobs with something like this: <?php $now = time(); $jobs = $page->children("expire_date>$now, publish_date<=$now"); -
Good question. You can use the built-in append() and/or prepend() functions, i.e. $menu_items->prepend($home); I believe the unshift syntax will also work: $menu_items->unshift($home); You don't have to worry about modifying the site tree because you would have to actually save a $page in order to modify the site tree. In addition, none of what you are trying to do here is modifying any pages, so even if you did save a page, it wouldn't modify anything. PageArrays are runtime dynamic arrays, and aren't saved anywhere unless they are attached to something like the result of a Page reference Fieldtype. See /wire/core/Array.php and /wire/core/PageArray.php for all the traversal and modification methods (there are a lot). For the most part, they are patterned after jQuery traversal methods, but I included alternate names like unshift() and shift() for people that prefer PHP function names. Just for fun, here's your example all bundled on one line. foreach($pages->find("parent=/navigation/")->prepend($pages->get('/')) as $item) { ... Or even shorter: foreach($pages->find("parent=0|/navigation/") as $item) { ... The selector above is saying to find all pages that have no parent (i.e. "0") or have a parent called /navigation/. Both examples above return the same result. That won't work because the function only accepts one param (a selector). But because all the pages you are selecting there have the same parent, this would work: $pages->find("parent=/, name=navigation|page|item2");
- 1 reply
-
- 2
-