Search the Community
Showing results for tags 'Array'.
-
Page Query Boss Build complex nested queries containing multiple fields and pages and return an array or JSON. This is useful to fetch data for SPA and PWA. You can use the Module to transform a ProcessWire Page or PageArray – even RepeaterMatrixPageArrays – into an array or JSON. Queries can be nested and contain closures as callback functions. Some field-types are transformed automatically, like Pageimages or MapMarker. Installation Via ProcessWire Backend It is recommended to install the Module via the ProcessWire admin "Modules" > "Site" > "Add New" > "Add Module from Directory" using the PageQueryBoss class name. Manually Download the files from Github or the ProcessWire repository: https://modules.processwire.com/modules/page-query-builder/ Copy all of the files for this module into /site/modules/PageQueryBoss/ Go to “Modules > Refresh” in your admin, and then click “install” for the this module. Module Methods There are two main methods: Return query as JSON $page->pageQueryJson($query); Return query as Array $page->pageQueryArray($query); Building the query The query can contain key and value pairs, or only keys. It can be nested and contain closures for dynamic values. To illustrate a short example: // simple query: $query = [ 'height', 'floors', ]; $pages->find('template=skyscraper')->pageQueryJson($query); Queries can be nested, contain page names, template names or contain functions and ProcessWire selectors: // simple query: $query = [ 'height', 'floors', 'images', // < some fileds contain default sub-queries to return data 'files' => [ // but you can also overrdide these defaults: 'filename' 'ext', 'url', ], // Assuming there are child pages with the architec template, or a // field name with a page relation to architects 'architect' => [ // sub-query 'name', 'email' ], // queries can contain closure functions that return dynamic content 'querytime' => function($parent){ return "Query for $parent->title was built ".time(); } ]; $pages->find('template=skyscraper')->pageQueryJson($query); Keys: A single fieldname; height or floors or architects The Module can handle the following fields: Strings, Dates, Integer… any default one-dimensional value Page references Pageimages Pagefiles PageArray MapMarker FieldtypeFunctional A template name; skyscraper or city Name of a child page (page.child.name=pagename); my-page-name A ProcessWire selector; template=building, floors>=25 A new name for the returned index passed by a # delimiter: // the field skyscraper will be renamed to "building": $query = ["skyscraper`#building`"] Key value pars: Any of the keys above (1-5) with an new nested sub-query array: $query = [ 'skyscraper' => [ 'height', 'floors' ], 'architect' => [ 'title', 'email' ], ] A named key and a closure function to process and return a query. The closure gets the parent object as argument: $query = [ 'architecs' => function($parent) { $architects = $parent->find('template=architect'); return $architects->arrayQuery(['name', 'email']); // or return $architects->explode('name, email'); } ] Real life example: $query = [ 'title', 'subtitle', // naming the key invitation 'template=Invitation, limit=1#invitation' => [ 'title', 'subtitle', 'body', ], // returns global speakers and local ones... 'speakers' => function($page){ $speakers = $page->speaker_relation; $speakers = $speakers->prepend(wire('pages')->find('template=Speaker, global=1, sort=-id')); // build a query of the speakers with return $speakers->arrayQuery([ 'title#name', // rename title field to name 'subtitle#ministry', // rename subtitle field to ministry 'links' => [ 'linklabel#label', // rename linklabel field to minlabelistry 'link' ], ]); }, 'Program' => [ // Child Pages with template=Program 'title', 'summary', 'start' => function($parent){ // calculate the startdate from timetables return $parent->children->first->date; }, 'end' => function($parent){ // calculate the endate from timetables return $parent->children->last->date; }, 'Timetable' => [ 'date', // date 'timetable#entry'=> [ 'time#start', // time 'time_until#end', // time 'subtitle#description', // entry title ], ], ], // ProcessWire selector, selecting children > name result "location" 'template=Location, limit=1#location' => [ 'title#city', // summary title field to city 'body', 'country', 'venue', 'summary#address', // rename summary field to address 'link#tickets', // rename ticket link 'map', // Mapmarker field, automatically transformed 'images', 'infos#categories' => [ // repeater matrix! > rename to categories 'title#name', // rename title field to name 'entries' => [ // nested repeater matrix! 'title', 'body' ] ], ], ]; if ($input->urlSegment1 === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Module default settings The modules settings are public. They can be directly modified, for example: $modules->get('PageQueryBoss')->debug = true; $modules->get('PageQueryBoss')->defaults = []; // reset all defaults Default queries for fields: Some field-types or templates come with default selectors, like Pageimages etc. These are the default queries: // Access and modify default queries: $modules->get('PageQueryBoss')->defaults['queries'] … public $defaults = [ 'queries' => [ 'Pageimages' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus', ], 'Pagefiles' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'filesize', 'filesizeStr', 'hash', ], 'MapMarker' => [ 'lat', 'lng', 'zoom', 'address', ], 'User' => [ 'name', 'email', ], ], ]; These defaults will only be used if there is no nested sub-query for the respective type. If you query a field with complex data and do not provide a sub-query, it will be transformed accordingly: $page->pageQueryArry(['images']); // returns something like this 'images' => [ 'basename', 'url', 'httpUrl', 'description', 'ext', 'focus'=> [ 'top', 'left', 'zoom', 'default', 'str', ] ]; You can always provide your own sub-query, so the defaults will not be used: $page->pageQueryArry([ 'images' => [ 'filename', 'description' ], ]); Overriding default queries: You can also override the defaults, for example $modules->get('PageQueryBoss')->defaults['queries']['Pageimages'] = [ 'basename', 'url', 'description', ]; Index of nested elements The index for nested elements can be adjusted. This is also done with defaults. There are 3 possibilities: Nested by name (default) Nested by ID Nested by numerical index Named index (default): This is the default setting. If you have a field that contains sub-items, the name will be the key in the results: // example $pagesByName = [ 'page-1-name' => [ 'title' => "Page one title", 'name' => 'page-1-name', ], 'page-2-name' => [ 'title' => "Page two title", 'name' => 'page-2-name', ] ] ID based index: If an object is listed in $defaults['index-id'] the id will be the key in the results. Currently, no items are listed as defaults for id-based index: // Set pages to get ID based index: $modules->get('PageQueryBoss')->defaults['index-id']['Page']; // Example return array: $pagesById = [ 123 => [ 'title' => "Page one title", 'name' => 123, ], 124 => [ 'title' => "Page two title", 'name' => 124, ] ] Number based index By default, a couple of fields are transformed automatically to contain numbered indexes: // objects or template names that should use numerical indexes for children instead of names $defaults['index-n'] => [ 'Pageimage', 'Pagefile', 'RepeaterMatrixPage', ]; // example $images = [ 0 => [ 'filename' => "image1.jpg", ], 1 => [ 'filename' => "image2.jpg", ] ] Tipp: When you remove the key 'Pageimage' from $defaults['index-n'], the index will again be name-based. Help-fill closures & tipps: These are few helpfill closure functions you might want to use or could help as a starting point for your own (let me know if you have your own): Get an overview of languages: $query = ['languages' => function($page){ $ar = []; $l=0; foreach (wire('languages') as $language) { // build the json url with segment 1 $ar[$l]['url']= $page->localHttpUrl($language).wire('input')->urlSegment1; $ar[$l]['name'] = $language->name == 'default' ? 'en' : $language->name; $ar[$l]['title'] = $language->getLanguageValue($language, 'title'); $ar[$l]['active'] = $language->id == wire('user')->language->id; $l++; } return $ar; }]; Get county info from ContinentsAndCountries Module Using the [ContinentsAndCountries Module](https://modules.processwire.com/modules/continents-and-countries/) you can extract iso code and names for countries: $query = ['country' => function($page){ $c = wire('modules')->get('ContinentsAndCountries')->findBy('countries', array('name', 'iso', 'code'),['code' =>$page->country]); return count($c) ? (array) $c[count($c)-1] : null; }]; Custom strings from a RepeaterTable for interface Using a RepeaterMatrix you can create template string for your frontend. This is usefull for buttons, labels etc. The following code uses a repeater with the name `strings` has a `key` and a `body` field, the returned array contains the `key` field as, you guess, keys and the `body` field as values: // build custom translations $query = ['strings' => function($page){ return array_column($page->get('strings')->each(['key', 'body']), 'body', 'key'); }]; Multilanguage with default language fallback Using the following setup you can handle multilanguage and return your default language if the requested language does not exist. The url is composed like so: `page/path/{language}/{content-type}` for example: `api/icf/zurich/conference/2019/de/json` // get contenttype and language (or default language if not exists) $lang = wire('languages')->get($input->urlSegment1); if(!$lang instanceof Nullpage){ $user->language = $lang; } else { $lang = $user->language; } // contenttype segment 2 or 1 if language not present $contenttype = $input->urlSegment2 ? $input->urlSegment2 : $input->urlSegment1; if ($contenttype === 'json') { header('Content-type: application/json'); echo $page->pageQueryJson($query); exit(); } Debug The module respects wire('config')->debug. It integrates with TracyDebug. You can override it like so: // turns on debug output no mather what: $modules->get('PageQueryBoss')->debug = true; Todos Make defaults configurable via Backend. How could that be done in style with the default queries? Module in alpha Stage: Subject to change This module is in alpha stage … Query behaviour (especially selecting child-templates, renaming, naming etc) could change
- 24 replies
-
- 29
-
I'm working on a newsletter solution with WireMailSMTP and this Newsletter Tutorial. I only changed the lines 73 to 83 in newsletter.php, but there's a strange issue with the $subscribers array: $testMode = isset($_POST['test_email']) ? true : false; if ($testMode) { $subscribers = wire('input')->post('test_email'); if (strpos($subscribers, ',') !== false) { $subscribers = explode(',', $subscribers); } } else { $subscribers = $pages->find('template=subscriber'); $subscribers = $subscribers->explode('email'); } if (is_array($subscribers)) { $subscribers = array_map('trim', $subscribers); } $mail = wireMail(); $mail->sendSingle(true)->to('test@domain.de')->bcc($subscribers); $mail->from('xxx@domain.de'); $mail->subject($newsletter->title); $mail->bodyHTML($html); $numSent = $mail->send(); echo json_encode(count($subscribers)); $this->halt(); The email is sent to test@domain.de but not to bcc $subscribers. Errorlog: PHP Notice: Unknown: Invalid mailbox list: <> (errflg=3) in Unknown on line 0 I'm grateful for any advice. Greetings Florian
- 1 reply
-
- wiremailsmtp
- newsletter
-
(and 1 more)
Tagged with:
-
Hello, I've been struggling for hours with this, and it is driving me crazy. I guess I completely misunderstand basic concepts, but I'm facing a wall here hence this message... Here's what I'm trying to do : I have a list of players in $allPlayers (pages) Each player has (among others) 2 pageArray fields : 'group' and 'team'. I'm trying to loop through all the players to build another pageArray (or WireArray or whatever...) to gather the players in groups/teams accordingly and deal with the different info I have on them and calculate a score. My main problem is that some players are in a different team but their group has the same name (and I need to restrict players to their own team mates). Here's my 'code' so far (which doesn't work) : // Build group list (for players having a team) $allPlayers->filter("team.name!=no-team")->sort("team.name"); $allGroups = new PageArray(); $uniqueGroups = []; $uGroups = new PageArray(); // This was a test, see below... $already = []; foreach($allPlayers as $p) { // Assign a groupId to each player $groupId = $p->team->id.$p->group->id; $p->groupId = $groupId; if (!in_array($groupId, $already)) { // The following lines were a test but didn't work and I DON'T UNDERSTAND WHY ? // $uG = new Page(); // $uG->of(false); // $uG->template = 'player'; // $uG->name = $groupId; // $uGroups->add($uG); // bd($uGroups->count()); // !! Keeps showing 1 ? My purpose was to be able to use $uGroups->karma, $uGroups->nbBonus... afterwards array_push($uniqueGroups, $groupId); } array_push($already, $groupId); } // Then, I loop through $uniqueGroups, get the players and calulate my score foreach($uniqueGroups as $group) { // Limit to groupId players for group scores $players = $allPlayers->find("groupId=$group"); // Check for group bonus and calculate scores [...] // I cut to simplify my post // But my other problem is storing my score : I can't use $group->karma or $group->nbBonus since $group is a ragular PHP array ? } // Then, I wanted to create a new pageArray (hence my $uGroups above) to be able to sort them with the following $uGroups->sort("-karma"); And I'm stuck... More than 5 hours today already on this, and still blocked I've tried playing with WireData, WireArray... but I'm all lost here. You can understand why I'm posting in the 'Getting started' forum ! For further information, this part of code is embedded in a setScoreboard() function and this is the 'group' part of it. If anyone can devote a little time to give me a clue on how to think about this, I'd greatly appreciate ! Thanks ! PS : The more I write about this, the more I think I am able to get the group members and scores (with my awkward coding), but then I am unable of simply storing this information before rendering it. Here I'm referring to my comment in my code where I say that TracyDebugger keeps showing me only 1 $uGroups page. I wish I could dynamically build a 'uniqueGroup' page with Pagefields for Group, Team, pageArray for Members, Integer fields for calculated Karma, nbBonus...... sigh......
-
Another dumb question: Is there a field type for a text-based array? In my case I need to store an array of RSS feeds for SimplePie. Storing that list of links in a textarea - text formatted to look like an array - doesn't work with the script. It works with one link. The images field is an array. I assumed there would be an equivalent for URLs or text in general. Or is there another approach for these cases? Edit: I guess using the optional (module) Repeater field type is the best solution in this case? I have now a working solution based on that. Still curious about other ideas.
-
While ProcessWire and WireArray does not have support for array_chunk, there is a simple way to achieve this. With array_chunk() you can easily add DIVs to a foreach loop, without having to set up counters when using general PHP (hat-tip to Laurance over at StackOverflow). The idea in a ProcessWire context is to use array_chunk() to split an array into chunks - and use eq() when looping page results. Simple example that will split a WireArray into three columns. Before we begin, you should know the array_chunk syntax: array_chunk($array, $chunk_size, $preserve_keys=true|false). <?php $p = $pages->get('/news')->children('limit=15, template=article, sort=-sort'); ?> <div class="row"> <?php foreach (array_chunk(range(0,14),5) as $chunk): ?> <div class="col"> <?php foreach ($chunk as $i): ?> <h5><a href="<?=$p->eq($i)->url?>"><?=$p->eq($i)->title?></a></h5> <?php endforeach; ?> </div> <?php endforeach; ?> </div> A more realistic example: <?php $p = $pages->get('/news'); $pp = $p->children('limit=15, template=article, sort=-sort'); ?> <h2><a href="<?=$p->url?>"><?=$p->title?></a></h2> <div class="row"> <?php foreach (array_chunk(range(0,14),5) as $chunk): ?> <div class="col"> <?php foreach ($chunk as $i): ?> <h5> <a href="<?=$pp->eq($i)->url?>"><?=$pp->eq($i)->title?></a> </h5> <?php endforeach; ?> </div> <?php endforeach; ?> </div>
- 2 replies
-
- 3
-
- array_chunk
- chunk
-
(and 2 more)
Tagged with:
-
I believe I have hit a roadblock on this one. I am trying to pass an array to a "cc" in wiremail (using wiremailsmpt to extend). Everything else is working, but I am getting an "invalid email address" for $cc_recipient[0]. I looked in wiremail, and it is checking to see if it is a valid email address before sending (which my variable is not). Is there a way around this by chance?
-
Hello good people. I was looking today on a header styling that I would like to use in my next project where I want to grab X-amount of posts and place them in a grid with different sizes and layout (hopefully you will understand me better from the layout shown above ). So far I was able to pull an array of posts and present them on the front-end using identical code for all results, however I have never dealt with a similar presentation where the 1st and 2nd posts have one style, 3rd has another, 4th different again and so on. Let's say in this scenario I would grab some results with $pages->find(...) but how would then I apply the different styling for every result?
-
Hello, I'm trying to build a selector array to work with an OR operator. I need all pages where the datetime field ("date_pub_end") is empty or in the future. In a selector string this could be solved with the following two examples (with and without OR-group) $selector1 = "... ,!date_pub_end<={$now}, ..."; $selector2 = "... ,(date_pub_end=''),(date_pub_end>={$now}), ..."; But I'd like it to work in selector arrays, so far I couldn't find a solution.
-
Hi everyone, I've recently hired at a new company and here I am evaluating the abilities of ProcessWire for our projects. I was able to meet almost every requirement so far, but there is one point I couldn't find an adequate solution for: outputting data to json. I am aware of modules like https://modules.processwire.com/modules/pages2-json/ (which does not seem to work for me) but I thought with a function like wireEncodeJSON this should be much cleaner. What I would like to achieve is outputting pages with according field values into an array to use this within javascript. My first attempt on this was: $jsontestOne = $pages->find(1001)->children(); echo wireEncodeJSON($jsontestOne); which outputs [{}] and afterwards I tried that one: $jsontest = $pages->find("template=basic-page")->getArray(); echo wireEncodeJSON($jsontest); which outputs [{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},...] Maybe you can point out where my mistake is. Thanks in advance!
-
I am trying to integrate another script, Questions2Answer, with Processwire user management. The script needs an array with key/value pairs for user->name => user->id The script provides an array $userids with active user->ids that looks like this var_dumped for a page with two users: array(2) { [0]=> int(1107) [1]=> int(41) } How can I take $userids, find the corresponding $user->names in Processwire as values and then return that to Q2A as a clean key/value array? This is probably basic PHP, but I have tried so many variations that I now completely lost the plot. Any pointers appreciated.
-
Hello processwire community, this is my very first post, I am newbie in php - trying to test a simple search form which allow frontend user to search and filter data. Macro steps are as follow: 1) Create the form with options as checkboxes, allowing the user to choose multiple values selection within multiple checkbox groups; 2) Create the pw process code in order to revert back the selected items (as a result of multiple checkbox filter combination), allowing pagination as some results may be more than 50 items; --- Here some of the most related topics I've found over PW forum: https://processwire.com/talk/topic/7282-paging-issue-with-html-form-check-boxes/ https://processwire.com/talk/topic/3472-enable-pagination-for-search-results/#comment-38214 https://processwire.com/talk/topic/1883-how-to-use-input-whitelist-with-checkboxes-or-any-array/ https://processwire.com/talk/topic/1547-getting-multiple-checkbox-values-within-processwire/ https://processwire.com/talk/topic/1034-search-form-with-multiple-fields/ https://processwire.com/talk/topic/10193-multiselect-search/ --- Now, the html form works just fine (code below), it brings all checked values to the url string. Essentially I have four different groups of checkboxes: cb_sectors[] (multiple pages as categories); cb_expertise[] (multiple pages as categories); cb_status[] (multiple pages as categories); cb_year[] (integer). The user may select multiple values within the above four checkbox groups, thus creating even quite complex combination. <form name='search' id='search-works' method='get' role='form' action='<?php echo $pages->get('/search/')->url; ?>'> <div class="collapsible-header">Sector</div> <?php foreach($pages->get("/sectors")->children as $sec) echo " <p class='checkbox'> <input type='checkbox' name='cb_sectors[]' value='{$sec->name}' id='{$sec->name}'/> <label for='{$sec->name}'>{$sec->title}</label> </p> " ?> <div class="collapsible-header">Status</div> <?php foreach($pages->get("/taxonomy/Status")->children as $st) echo " <p class='checkbox'> <input type='checkbox' name='cb_status[]' value='{$st->name}' id='{$st->name}' /> <label for='{$st->name}'>{$st->title}</label> </p> " ?> <div class="collapsible-header no-padding">Expertise</div> <?php foreach($pages->get("/expertise")->children as $cb_expertise) $checked = $cb_expertise->name == $input->whitelist->cb_expertise ? " selected='selected' " : ''; echo " <p class='checkbox'> <input type='checkbox' name='cb_expertise[]' value='{$cb_expertise->name}' id='{$cb_expertise->name}' $checked/> <label for='{$cb_expertise->name}'>{$cb_expertise->title}</label> </p> " ?> <div class="collapsible-header no-padding">Year</div> <?php // generate a range of years from '09 to '17, or maybe better doing it via pages as years? for($year = 2009; $year <= 2017; $year += 1){ echo " <p class='checkbox'> <input type='checkbox' name='cb_year[]' value='$year' id='$year' /> <label for='$year'>{$year}</label> </p> "; } ?> <input class="no-class" type="submit" id="search-submit" name="submit" value="Search"> </form> The question is then mostly focusing on the second step, the pw process code: As some previous posts on this topic say - I should (in sequence) sanitize, whitelist and validate the results before pass them to the final output (correct me if I'm wrong). The thing is that I cannot find a way to get all values in a array and sanitize/whitelist/validate them -> some post suggest to use arraytoCSV as a way to let PW remember the filtered items while moving through pagination. Is arraytoCSV the best way to sanitize and whitelist the user input combination? The following code simply get selected values coming from the above form. As you can see, no sanitize nor whitelist nor validation is in place, as without the array the sanitizing function gives back only the last selected value (not the full combination for every group of checkboxes). Can you please help me implementing an array within the following code and the way to sanitize - whitelist - validate "get" values? I know for most of you is just as simple as drinking coffe, but would be great if you could drive me in the right direction. Thank you in advance! <?php namespace ProcessWire; if(count($input->get)) { if($input->get->cb_expertise) { foreach ($input->get->cb_expertise as $expertise) { // here we are just ensuring submitted products are in fact valid echo $expertise; } } if($input->get->cb_sectors) { foreach($input->get->cb_sectors as $sector) { // here we are just ensuring submitted products are in fact valid echo $sector; } } if($input->get->cb_status) { foreach($input->get->cb_status as $status) { // here we are just ensuring submitted products are in fact valid echo $status; } } if($input->get->cb_year) { foreach($input->get->cb_year as $year) { // here we are just ensuring submitted products are in fact valid echo $year; } } } ?>
- 21 replies
-
I'm getting this warning when I try to print an array: Warning: array_values() expects parameter 1 to be array, object given... This is my code: $array = $page->get("planos"); print_r(array_values($array)); I've always thought that $page->get will give you an array, but I'm not so sure now. Thanks for any help.
- 1 reply
-
- array
- array_values
-
(and 2 more)
Tagged with:
-
<?$work_pages = new PageArray();?> <?$project_1 = $pages->get("parent=/work/projects, limit=1, sort=sort"); $work_pages->add($project_1); // Code for Project 1 goes here $project_2 = $pages->get("parent=/work/projects, id!=$work_pages, limit=1, sort=sort"); $work_pages->add($project_2); // Code for Project 2 goes here $project_3 = $pages->get("parent=/work/projects, id!=$work_pages, limit=1, sort=sort"); $work_pages->add($project_3); // Code for Project 3 goes here // etc I have the above code which gets project pages then adds the project to an array to exclude from the next selector. I'm sure this was working fine but seems to have started including unpublished pages - if I unpublish or hide pages they still show up. I've done some troubleshooting and have excluded any caching issues - the code is definitely pulling in unpublished pages. Working on Processwire 2.8.35.
- 2 replies
-
- array
- unpublished
-
(and 2 more)
Tagged with:
-
Im having problems with this little piece of code: $slider = $pages->get("/slider/")->children(); echo $slider(0)->images->first()->url; echo $slider(1)->images->first()->url; echo $slider(2)->images->first()->url; gives me that error: Error: Method name must be a string (line 1641 of /home/islak/public_html/wire/core/WireArray.php) Instead if i use: $slider = $pages->get("/slider/")->children(); echo $slider(1)->images->first()->url; echo $slider(2)->images->first()->url; It works perfectly fine. If I don't use the 0 index everything goes smoothly, but of course I can't show the first children's data. Thanks for any help.
-
Hi, is there any way of deleting the entire contents of an array from the API? I have had some success removing an item with: $page->image->remove($page->image->first()); But as I have to specify the item within remove() I'm not sure how to remove all the items. Thanks
-
Hi folks, This may be a bit of a daft question as it may be more a PHP question than a PW question, but thought I would check. I have some tags set up for each 'project' on my site. All good, and if I echo out $project->project_tags it returns 1025|1074|1026|1027 and obviously I can do a foreach loop on them etc. All good. However, I want to check if a tag exists then assign a colour value to it, for example: data-color="<?php if ($project->project_tags == 1025) : ?>#ff0000<?php endif; ?>" Is there a way to check an array for a value rather than running a foreach loop on it and doing it that way? Thanks, R
-
Hi All, I have an images field for multiple images set to always return an array. My images field holds 5 images. I'm trying to get the first image of the array and then remove that to get an array that holds images 2-5. Here's my testing code so far $images = $page->images; $firstimage = $images->eq(0); //also tried $images->first() with same result $restimages = $images->remove($firstimage); echo count($images) . " images<br>"; foreach ($images as $img) { echo $img->basename . "<br>"; } echo "firstimage<br>"; echo $firstimage->basename . "<br>"; echo "restimages<br>"; foreach ($restimages as $img) { echo $img->basename . "<br>"; } And here's the output: 4 images mario_florenz_1.jpg mario_florenz_3.jpg mario_florenz_2.jpg mario_florenz_5-1.jpg firstimage mario_florenz_4.jpg restimages mario_florenz_1.jpg mario_florenz_3.jpg mario_florenz_2.jpg mario_florenz_5-1.jpg A few things that buffle me: -count($images) returns 4 where it should be 5 -foreach through $images returns only 4 images where it should be 5 -$images->eq(0) returns the first image but this one is not returned when I loop through all images -$images and $images->remove($firstimage) return the same I really don't understand what is happening here. Reading through the API docs on images and WireArray manipulation it seems my code should work. Any help would be much appreciated.
-
I am setting up a new processwire site (kathep.com/cms), and have a problem I can't find a solution to on the forum so far. I would like the footer of one of my templates (course.php), to display a random quote in a specific category, from a collection of quotes. I currently have the quotes stored in a text file, and have set up four fields in processwire to take the information (quote_text, quote_author, quote_category, quote_reference). My questions are: 1. What is the best way to store the quotes in processwire? I'm not sure if its best to create an individual page for each quote, or to shell out for protools and store them in a table. I saw this example from Sinnut on this thread which looks good to me: But as I'm a beginner, I'm seeking advice of someone with more expertise! Would this structure suit my use case? 2. What is the best way to allow quotes to be stored in multiple categories? Ideally I would like to be able to select multiple categories for some quotes. Would this best be done in with check boxes? I'm not sure. 3. In my course.php file, what is the best way to call a random quote from a specific category? Thank you for reading this, and I hope someone can help.
-
Hi folks, I am trying to query (find) pages who have a certain page as a parent, but then filter this result so it only returns the pages listed. I know you can do the following for one: $pages->find('parent=/widgets/')->filter(1020); But how do you do it for many? I thought the below would've worked... $pages->find('parent=/widgets/')->filter(1020|1069|1070|1071|1072|1073|1074|1075|1076)->getRandom(); Thanks, R
-
Hi, I'm trying to combine two find() arrays in a random order but currently can only make it give me back the same order each time. here's what im working with: $works = $pages->find('template=work'); $articles = $pages->find('template=article'); $works->prepend($articles); $randWorks = $works->getRandom(count($works)); foreach($randWorks as $child) { $class = $child === $page->rootParent ? " class='active'" : ''; echo "<a$class href='{$child->url}'>{$child->title}</a>"; }
-
Hello all, I'm back on my PW site and I'm facing an issue for a couple of hours now and it's driving me crazy... I'm sure it's not that much for a bunch of you, but it looks hopeless to me so here's my problem : I'm sending a form to a page and I have many checkboxes sent, so I used an array. My code looks like this : <table class="adminTable"> <tr> <td></td> <th ng-repeat="task in tasks" title="{{task.summary}}"><div class="vertical-text"><div class="vertical-text__inner">{{task.title}}</div></div></th> </tr> <tr> <td></td> <td ng-repeat="task in tasks" title="Tout cocher"><input type="checkbox" /></td> </tr> <tr ng-repeat="player in players"> <th>{{player.title}}</th> <td ng-repeat="task in tasks" title="{{player.name}} - {{task.title}}"> <!-- <input type="hidden" name="player[{{$parent.$index}}]" value="{{player.id}}" /> --> <input type="checkbox" name="player[{{player.id}}][]" value="{{task.id}}" /> </td> </tr> </table> The important line (to me) is the <input type="checkbox" name="player[{{player.id}}][]" value="{{task.id}}" /> in which I'm trying to pass both the id of the player and the task id to record for the player. All this is embedded into an ng-repeat loop since I'm using AngularJs... Anyway, the variables look ok when I'm looking at the generated source and in fact it look fine if I print_r($GLOBALS) when I recieve the POST variables. Here's the print_r($GLOBALS) result : [_POST] => Array ( [adminTableSubmit] => Enregistrer [player] => Array ( [5157] => Array ( [0] => 1580 [1] => 1578 ) [5171] => Array ( [0] => 1580 [1] => 1578 ) ) ) (2 players and 2 tasks for each) BUT : if I write $checked_players = $input->post->player; I get an empty array! Indeed, trying to debug my thing (I guess I can call it a 'thing' at this time), I type : foreach($input->post as $key => $value) echo htmlentities("$key = $value") . "<br />"; $checked_players = $input->post->player; print_r($checked_players); and here's what I get : adminTableSubmit = Enregistrer player = Array Array ( ) Whereas I keep thinking my print_r($checked_players) should return : [5157] => Array ( [0] => 1580 [1] => 1578 ) [5171] => Array ( [0] => 1580 [1] => 1578 ) so that I could then work with that and save data as pages... So please, what I am doing wrong? I'm sure I'm messing things up. I've tried so many possibilities and nothing has worked so far. Hence my message to the community. I really don't get it since it seems like such a basic problem... but the facts are there : I'm stuck Hope to hear from one of you soon. Thanks in advance for your help PS : Sorry for my long post, but I'm trying to be as clear s possible.
-
I am finishing up my first processwire site (yay), and this last bit is giving me a bit of a headache: For a news slider, I want to output x number of posts, with three posts per slide. (for a theoretically unlimited number of slides) I figure in theory this should work something like the code below, however the looping logic, among other things is still somewhat beyond me: <?php $items_per_page = 3; $start = ($pages->get("/news/")->find("sort=sort")->pageNum - 1) * $items_per_page; $total = count($pages->get("/news/")->find("sort=sort")); $slicedarticles = $pages->get("/news/")->find("sort=sort")->slice($start, $items_per_page); foreach ($slicedarticles as $slicedarticle => $total) { echo "<div class='slide'>"; foreach ($slicedarticle as $article) { echo "<h3>{$article->title}</h3><p>{$article->body}</p>"; } echo "</div>"; } ?> Can someone point me in the right direction with this? Much appreciated! Cheers, Phil
-
Not sure how to ask this, but basically I have an associative PHP array outputting a song ID and it's lyrics from PW using this code: It's being stored in the $lyricsArray variable <?php // Loop though album Tracks $numTracksContainingLyrics = 0; // How many contain lyrics? $lyricsArray = array(); // Create empty array to hold lyrics foreach ($albumTracks as $track) { $html = "<tr>"; $html .= "<td>"; $html .= "<a href='" . $track->song_file->url . "' class=''>" . $track->title . "</a>"; $html .= "</td>"; $html .= "<td>"; if ($track->lyrics != null) { // If lyrics field isn't empty $html .= '<a href="#" class="lyricCLicked" data-reveal-id="songID_' . $track->id . '">Lyrics</a>'; $numTracksContainingLyrics++; foreach ($track as $value) { $lyricsArray[$track->id] = $track->lyrics; } }; $html .= "</td>"; $html .= "<td>"; $html .= "<a href='#'>Buy</a>"; $html .= "</td>"; $html .= "</tr>"; echo $html; } ?> The PHP code for outputting those values mentioned above is below: What I'd like to do is also output the song title (commented in red in the code below). However, I don't know how to go about doing it using the simple arrays I have been constructing. <?php foreach ($lyricsArray as $key => $value) { $lyricModal = '<div id="songID_' . $key .'" class="reveal-modal small" data-reveal>'; $lyricModal = '<h2>' . //HOW DO I ALSO GET $track-title HERE??? . '</h2>'; $lyricModal .= $value; $lyricModal .= '<a class="close-reveal-modal">×</a>'; $lyricModal .= '</div>'; echo $lyricModal; } ?> Thank you for your help!
-
I have a repeating loop which displays tracks from an album with a link on each track pointing to lyrics which appear in a popup window. Well, that's what I want to do at least Here's the code which displays the track listings: <?php // Show Album Tracks $albumTracks = $page->children; foreach ($albumTracks as $track) { $html = "<tr>"; $html .= "<td>"; $html .= "<a href='" . $track->song_file->url . "' class=''>" . $track->title . "</a>"; $html .= "</td>"; $html .= "<td>"; if ($track->lyrics != null) { // LYRICS LINK $html .= "<a href='#' data-reveal-id='lyricPopup'>Lyrics</a>"; }; $html .= "</td>"; $html .= "<td>"; $html .= "<a href='#'>Buy</a>"; $html .= "</td>"; $html .= "</tr>"; echo $html; } ?> The link is pointing to a modal popup div below: <div id="lyricPopup" class="reveal-modal" data-reveal> <h2><?php echo $track->title; ?></h2> <?php ?> <a class="close-reveal-modal">×</a> </div> What I need to do is have each track's lyrics popup in the modal. Can anyone supply the code for setting up the multi-dimension array which keeps tracks of which song title (lyric link) was clicked so that the appropriate lyrics for that particular song (associated with that song) appear in the modal? I understand the concept of arrays, but multidimensional are out my league. Knowing which link was clicked and retrieving the associated content for it is also beyond me. Not sure where to start. Thanks!!!
-
I'm not able to get my array list. I have a menu template and I'm grabbing it, but it won't let me go inside it I get this error Warning: Invalid argument supplied for foreach() in /x/site/templates/includes/header.inc on line 61 $items = $pages->find('template=menu, title=Toolbar Menu, include=all'); //THIS SHOULD WORK foreach ($items->menu_item as $item) { $output .= '<li><a href="' . $item->link . '"'; if ($item->open_in_new_window) $output .= ' target="_blank"'; $output .= '>' . $item->title . '</a></li>'; } I'm attaching a screenshot of a selector test