Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/08/2017 in all areas

  1. Wrapping up the fieldset trilogy comes part 3: Fieldset Group, which is now released. In the post we take a closer look at it and compare it to the other fieldset types. Then we wrap up with some hints about more coming up in the weeks ahead. https://processwire.com/blog/posts/fieldsetgroup-module-released/
    8 points
  2. hi and welcome deceleration quite easy: <?php // overview for($i=1; $i<??; $i++) { echo "<a href='./$i'>"; // create a link with that url segment echo "ZIP $i... [" . $pages->count("template=yourtemplate, zipcode^=$i") . "]"; echo "</a><br>"; } // details $zip = $sanitizer->int($input->urlSegment1); if($zip) { $items = $pages->find("template=yourtemplate, zipcode^=$zip"); foreach($items as $item) { echo "<a href='{$item->url}'>{$item->title}</a><br>"; } }
    3 points
  3. sagol, yuvarlanıp gidiyoruz iste. means for the non-turkish members: thanks, this is really a great community and i learned a lot of interesting stuff. god bless ryan.
    2 points
  4. Ok, in my test setup `country` field may include spaces, so urlSegments is out of question. In these situations you can use query strings and send encoded parameters with urls. If user goes to a nonexistent url, it redirects back to summary list <?php namespace ProcessWire; $detailMode = false; // show people in a country? $grouped = []; if ($input->get->country) { // always sanitize user input $country = $sanitizer->selectorValue($input->get->country); $persons = $pages->find("template=person, country=$country"); $detailMode = true; if (!$persons->count) $session->redirect('./'); } else { // summary mode $persons = $pages->find('template=person'); foreach ($persons as $person) { $country = $person->country; if (isset($grouped[$country])) { $grouped[$country][] = $person; } else { $grouped[$country] = [$person]; } } } ?> <?php if($detailMode): // showing single country ?> <h1><?= $persons->first->country ?></h1> <?php foreach ($persons as $person): ?> <?= $person->title ?><br> <?php endforeach; ?> <?php else: // showing all countries ?> <?php foreach ($grouped as $country => $people): ?> <?php $encoded = "./?" . http_build_query(['country' => $country]) ?> <?= $country ?> <a href="<?= $encoded ?>">[<?= count($people) ?>]</a><br> <?php endforeach; ?> <?php endif; ?> Result looks like this One drawback of using query parameters is that the url looks like mysite.com/url?param=value, instead of mysite.com/url/value.
    2 points
  5. You're welcome. I'm glad your problem got solved. You're right, thanks for pointing that. I was reading the source for urlSegments just today. Gotta love @ryan's humor // ProcessPageView.module /** * Get the requested page and populate it with identified urlSegments or page numbers * * @return Page|null * */ protected function getPage() { $config = $this->wire('config'); $shit = isset($_GET['it']) ? trim($_GET['it']) : "/"; // dirty $it = preg_replace('{[^-_./a-zA-Z0-9]}', '', $shit); // clean unset($_GET['it']); if($shit !== $it && $config->pageNameCharset == 'UTF8') { $it = $this->wire('sanitizer')->pagePathNameUTF8($shit); } // ... while((!$page || !$page->id) && $cnt < $maxSegments) { $it = rtrim($it, '/'); $pos = strrpos($it, '/')+1; $urlSegment = substr($it, $pos); $urlSegments[$cnt] = $urlSegment; $it = substr($it, 0, $pos); // $it no longer includes the urlSegment $selector = "path=" . $this->wire('sanitizer')->selectorValue($it, 2048) . ", status<" . Page::statusMax; $page = $this->pages->get($selector); $cnt++; } // ... }
    2 points
  6. datatable connected to the pagefield updating the pageautocomplete field seemed a little tricky in the beginning but the final approach was quite easy: // handle buttonclicks $('#addcompetences').click(function(e) { e.preventDefault(); var table = $table.DataTable(); // datatable instance var $field = $('#wrap_Inputfield_competences'); // asm select field var $template = $field.find('li.itemTemplate'); // selected page template var $ol = $template.closest('ol'); // get selected competences from table var selectedtable = $.map( table.rows({selected:true}).data(), function(val, i) { return [[ val.id.sort, val.title + ' (' + val.cluster.filter + ')' ]]; } ); // update ASM // clone template and populate values $.each(selectedtable, function(i,val) { // check double if($ol.find('.itemValue:contains("' + val[0] + '")').length) return; // add clone var $new = $template.clone().appendTo($template.parent()); $new.find('.itemValue').text(val[0]); $new.find('.itemLabel').text(val[1]); $new.removeClass('itemTemplate'); }); // add state changed class $field.addClass('InputfieldStateChanged'); // update original input InputfieldPageAutocomplete.rebuildInput($ol); return false; });
    2 points
  7. I've made a few CSS changes, now preview buttons look the same in all 3 image grid modes and I've fixed some other glitches too. The CSS file was a bit overcomplicated, I could eliminate large blocks so I hope I haven't broken anything I also checked the preview images with more than one crop setting (multiple buttons) and it's working fine here. All is in the PR.
    2 points
  8. Others may come up with different suggestions, but intercooler.js (there is a module, but I haven't used it, even though I have used intercooler) can do infinite scrolling and history.pushstate. (And a load of other clever stuff, but they're your main two.)
    2 points
  9. During boot, inside /site/config.php $page is not yet determined, so I am limited in determining what to prepend/append. For this reason I disable $config->prependTemplateFile (& append) and use a 'controller' hook like this. wire()->addHookBefore('TemplateFile::render', function (HookEvent $event) { // skip if AJAX if ($event->config->ajax) return; /** @var TemplateFile $templateFile */ $templateFile = $event->object; // Skip admin pages if (strpos($event->input->url, $event->config->urls->admin) === 0) return; // check if this is a partial template, if so, stop $fileDir = pathinfo($templateFile->get('filename'), PATHINFO_DIRNAME); $templatesPath = $event->config->paths->templates; if (realpath($fileDir) !== realpath($templatesPath)) return; $templateName = $templateFile->page->template->name; $prepends = [ 'routes' => $templatesPath . "{$templateName}.routes.php", 'before' => $templatesPath . "_before.php" // like your _init.php ]; // then comes the actual template file $appends = [ 'view' => $templatesPath . "views/{$templateName}.php", 'after' => $templatesPath . "_after.php", 'layout' => $templatesPath . "layouts/main.php" ]; foreach ($prepends as $name => $file) { if (file_exists($file)) $templateFile->setPrependFilename($file); } foreach ($appends as $name => $file) { if (file_exists($file)) $templateFile->setAppendFilename($file); } }); So to adapt this to your setup, you can define your urlSegments inside template.routes.php, and stop further appends with return $this->halt(). This way only template.routes.php is loaded and remaining appends are skipped while still allowing PW to complete its shutdown.
    2 points
  10. Thank you Ryan! Both modules look awesome! And I see use cases for both of them on sites I am working on right now. It is especially nice to see these developed in response to a community feedback made through a PW weekly poll. And this is the first reason I hope both fill be released in the core. The second is that that FieldsetGroup is such a natural and kind of even expected extension of the regular fieldset it must be valuable to many. I got my ProFields subscription anyways, but still...
    1 point
  11. Optionally, you can create a select field, or better, a page field and select flavors for each post while editing and render items depending on that https://processwire.com/blog/posts/making-efficient-use-of-fields-in-processwire/#use-page-fields-rather-than-individual-checkboxes if($item->flavors->get("name=hoverable")) { // this page has the "hoverable" flavor set }
    1 point
  12. Here are two ways: <?php namespace ProcessWire; /** @var $pages Pages */ $posts = $pages->find('template=post, sort=-published'); $latest = $posts->shift(); // removes first item off of $posts ?> <ul class="post-list"> <li class="item--latest item"> <?= $latest->title ?> </li> <?php if ($posts->count): ?> <?php foreach ($posts as $i => $p): ?> <?php $itemClass = ($i % 3 == 0) ? "item--hoverable" : ''; ?> <li class="<?= $itemClass ?> item"><?= $p->title ?></li> <?php endforeach; ?> <?php endif; ?> </ul> <!-- OR --> <?php if ($posts->count): ?> <ul class="post-list"> <?php foreach ($posts as $i => $post): ?> <?php if ($i === 0): // LATEST POST ?> <li class="item--latest item"> Latest: <?= $post->title ?> </li> <?php elseif ($i === 1): // BASIC ?> <li class="item--basic item"> Basic: <?= $post->title ?> </li> <?php elseif ($i % 3 === 0): // HOVERABLE ?> <li class="item--hoverable item"> Hover Me: <?= $post->title ?> </li> <?php endif; ?> <?php endforeach; ?> </ul> <?php else: ?> <p>No posts found</p> <?php endif; ?>
    1 point
  13. I was just typing something along those lines when you posted. It's either that, or fix Spex, or refactor the whole site not to need Spex. (I figured out where the live site is, and I'm guessing that refactoring isn't actually an option.) You might find that the core PW stuff in the working version is still covered in the docs, since stuff is rarely (never?) deprecated completely, just new stuff added, and there isn't the imperative with PW to upgrade like you might be used to with WP. You can always come back here for advice - we usually try to help when we can.
    1 point
  14. Interesting. I replaced some of those functions with their new counterparts, and now the page is loading without errors, but it is not loading properly... http://dev.delucaswpg.webfactional.com I may have to just "leave well enough alone" and stick with my 2.3 installation... and muddle my way through making the changes — with documentation that is not correct for the version I'm using. Fun times. I really do appreciate you guys taking the time to try to help me figure this out though! Definitely a big help. Thank you.
    1 point
  15. I updated Spex — from 0.2 (!) to 0.99 — and still get this error: Error: Exception: Method ProcessWire::getArray does not exist or is not callable in this context (in /home/delucaswpg/webapps/delucas_dev/wire/core/Wire.php line 519) #0 /home/delucaswpg/webapps/delucas_dev/wire/core/Wire.php(386): Wire->___callUnknown('getArray', Array) #1 /home/delucaswpg/webapps/delucas_dev/wire/core/WireHooks.php(698): Wire->_callMethod('___callUnknown', Array) #2 /home/delucaswpg/webapps/delucas_dev/wire/core/Wire.php(442): WireHooks->runHooks(Object(ProcessWire), 'callUnknown', Array) #3 /home/delucaswpg/webapps/delucas_dev/wire/core/ProcessWire.php(587): Wire->__call('callUnknown', Array) #4 /home/delucaswpg/webapps/delucas_dev/wire/core/Wire.php(445): ProcessWire->__call('callUnknown', Array) #5 /home/delucaswpg/webapps/delucas_dev/wire/core/Wire.php(445): ProcessWire->callUnknown('getArray', Array) #6 /home/delucaswpg/webapps/delucas_dev/wire/core/ProcessWire.php(590): Wire->__call('getArray', Array) #7 /home/delucaswpg/webapps/delucas_dev/site/modules/Spex/Spex.module(250): ProcessWire->_ This error message was shown because: you are logged in as a Superuser. Error has been logged. When I removed Spex I got loads of "function doesn't exist" errors for the page templates, so it looks like this template is relying on it pretty heavily.
    1 point
  16. I think on @mike62's system an older version of Spex installed. 163th line seems to be empty https://github.com/jdart/Spex/blob/ad9212b4ef72b8979f53eed0d600d3c5325eb0e6/Spex.module#L163 Updating the module may fix the issue.
    1 point
  17. Will probably break something else, but the other thread I linked to above was related to Spex. Unfortunately, that module's author hasn't been around since early 2016, it looks like. It might just be that the fix in the other thread works for you (fingers crossed).
    1 point
  18. sorry my solution only works if you have zip-codes like 1... 2... 3... 10... and 19... would be listed under 1... you could replace the for(...) with this $zipcodes = [11, 15, 80, 99]; foreach($zipcodes as $zip) { ... } always depends what your initial data looks like (if you know the zip-code-categories or if they are dynamic). 1 question, so many answers
    1 point
  19. To get an output like you want, you can use: <?php foreach ($grouped as $country => $people): ?> <h2><?= $country ?> [<?= count($people) ?>]</h2> <?php endforeach; ?> Which gives
    1 point
  20. You can group pages depending on a field and output them like this. I used `country` field, instead of `zipcode` but it doesnt change anything <?php namespace ProcessWire; $persons = $pages->find('template=person'); $grouped = []; foreach ($persons as $person) { $country = $person->country; if (isset($grouped[$country])) { $grouped[$country][] = $person; } else { $grouped[$country] = [$person]; } } ?> <?php foreach ($grouped as $country => $people): ?> <h2><?= $country ?></h2> <?php foreach ($people as $p): ?> <p><?= $p->title ?></p> <?php endforeach; ?> <?php endforeach; ?> Which outputs something like this
    1 point
  21. I strongly suggest creating a template for the child pages as well. You might not have an issue at the moment, but a month from now, a year from now, when you need to change something, it won't be where you expect it to be. It'll be harder to maintain. I had to do a number of complete rewrites in the past because I was only complicating things for myself for no reason.
    1 point
  22. Never said that I would recommend reading my second link carefully and trying out markup regions (... And building your site with a template for your child pages instead of URL segments)
    1 point
  23. very nice - a good alternative to other page select options out there, and intuitive for the user;
    1 point
  24. thanks a lot. I wouldnt have got it by now. Must have taken another night without you guys!!!!!!!!!!!!!
    1 point
  25. if($page->template == "contact" || $page->template == "course" || $page->template == "holiday" || $page->template == "newsletter") { if(!$page->is(Page::statusHidden)) include ("contact.inc.php"); } Check contact.inc.php Might be a field on the homepage.
    1 point
  26. Go to backend and edit home page
    1 point
  27. Thanks, @abdus for so quick response. You are right, I don't get "category" page because of missed "echo"; And this return $this->halt(); prevents render of "categories" page. From your code: $name = sanitizer()->pageName(input()->urlSegment1); https://processwire.com/api/ref/input/url-segment/ Docs say that urlSegments are already sanitized as page names. Thanks once again!
    1 point
  28. I'm not getting that behavior. I tired to replicate your setup. This is what I have ended up with (I use jobs instead of categories but it shouldnt matter) <?php namespace ProcessWire; // categories.routes.php if (input()->urlSegment2) throw new Wire404Exception(); if (input()->urlSegment1) { /** @var Pages $pages */ $name = sanitizer()->pageName(input()->urlSegment1); $match = $pages->findOne("template=profession, name=$name"); if (!$match->id) throw new Wire404Exception(); echo $match->render(); return $this->halt(); } This is my _init.php. It gets included to every template (after its routes, if exists) <?php namespace ProcessWire; require_once '_func.php'; $testPages = $pages->find('template=profession, limit=5'); And I use it inside actual page template that renders `category` page <?php namespace ProcessWire; ?> This is: <?= $page->title ?> <p>Other Pages:</p> <?php foreach ($testPages as $p): ?> <?= $p->title ?><br> <?php endforeach; ?> And both pages render correctly So, to me the only thing that seems missing is echo statement before $p->render() and return $this->halt(); after that EDIT: This is the backend structure, I am guessing you have a similar one. You get categories from another parent
    1 point
  29. Is that a front-end form? And what is that "form thing" you don't have?
    1 point
  30. there's https://www.adminer.org/#download Put it in your root directory and access it from mysite.com/adminer.php You can find database credentials in /site/config.php
    1 point
  31. Hmm that looks quite outdated. My suggestions may not even exists in your version. Also the module list seem to include only core modules. Since you have the sources, can you download /site/templates and /site/modules folders and search all files for @ symbol?
    1 point
  32. Hello, this module has been updated and it is now compatible with Graph API version 2.10. Parameters 'description' and 'name' are not supported by the new Graph API version. Therefore, fields for description and name cannot be provided anymore.
    1 point
  33. URLs are generated from page names by default. What I'm trying to show is that you dont have to use IDs for page names, otherwise when generating URLs you'd get /codes/123 instead of /codes/wall-mounted-light. Below is a sample template that should work in your case <?php namespace ProcessWire; /** @var Pages $pages */ /** @var Sanitizer $sanitizer */ /** @var Page $child */ $child = null; if ($input->urlSegment1) { $codeChildName = "code--{$input->urlSegment1}"; $codeChildName = $sanitizer->pageName($codeChildName); $child = $pages("parent=$page, name=$codeChildName"); if (!$child->id) throw new Wire404Exception(); } ?> <div class="code-page"> <?php if ($child): ?> <!-- RENDER CHILD PAGE --> <h1>Child: <?= $child->title ?></h1> <?= $child->body ?> <?php else: ?> <!-- RENDER CODE PAGE WITH CHILDREN --> <h1><?= $page->title ?></h1> <?= $page->body ?> <h2>List of children:</h2> <ul class="chilren"> <?php foreach ($page->children as $c): ?> <?php $childUrl = "./$c->name"; // generate urls for the child ?> <li class="child"> <a href="<?= $childUrl ?>"><?= $c->title ?></a> </li> <?php endforeach; ?> </ul> <?php endif; ?> </div> I also concur with @bernhard. If you're modifying the core behavior and rendering child page at the url that matches the child's, then I'd say you should reconsider your approach. You're only complicating it for yourself. Also, thanks, I'm doing what I can. These questions are like quizzes that I enjoy solving, and get to practice coding with PW.
    1 point
  34. If pages are not public, then you wouldnt need to worry about SEO. Page name format works for pages created in the future, but for the current pages you can do: $codes = wire()->pages('template=code'); foreach ($codes as $c) { // wall-mount-mini-split becomes code--wall-mount-mini-split $replacement = "code--{$c->name}"; $c->of(false); $c->setName($replacement); $c->save(); } And in your template, where you check urlSegments: if($input->urlSegment1) { if ($input->urlSegment2) throw new Wire404Exception(); $codeName = "code--{$input->urlSegment1}"; $codeName = $sanitizer->pageName($codeName); $code = $pages("template=code, name=$codeName"); if(!$code->id) throw new Wire404Exception(); // do sth with the code page }
    1 point
  35. What you need to do is basically: Get a list of pages with limit for pagination $pages->find('template=post, limit=10, sort=-published'); Render a list of items Render the pagination at the bottom of the page Using JS listen to scroll event, and trigger AJAX request Get the response, filter the list of elements, replace the container that holds the old items Repeat As a different approach, you can implement barba.js for PJAX (ajax with history support) (and limit it to only pagination links, if you prefer), and trigger click() on the next pagination link when it gets closer to viewport. For that you can use scrollMonitor.js. Total weight of these two scripts are under 15KB, they don't add much load on the page. One bonus is that you can enable barba.js on all (internal) links (it's enabled by default) to make transitions between pages feel more responsive.
    1 point
  36. @cjx2240, I'm not sure if this is the best way, but hey it works. Put this in your /site/ready.php wire()->addHookBefore('Page::render', function (HookEvent $e) { // requested page (not the one being rendered) $page = $e->page; // skip admin pages if (strpos($e->input->url, $e->config->urls->admin) === 0) return; // force redirect to homepage if ($page->id != 1) { $e->session->redirect('/'); } }); And in your home template, put this at the beginning <?php namespace ProcessWire; $splashPage = $pages->get(1353); echo $splashPage->render(); return $this->halt();
    1 point
  37. https://moz.com/blog/structured-data-for-seo-1 Seems to me that one of the huge advantages we have with PW is that it's fairly straightforward to include 'extra' stuff as part of our rendered markup, without necessarily waiting for someone else to develop a plugin of some kind, as is so often the case with other CMSs. This blog post (and Pt 2 when it comes out I expect) not only goes into some depth on its subject, but links to loads of other resources on the topic.
    1 point
  38. Just a word of caution. Do not use this in high traffic pages, because it holds a race condition, where people might be assigned the same number.
    1 point
  39. Just updated the module to version 0.1. Almost everything in it has changed so reading the docs is a must The module does less "magic" as before, eg. doesn't add the "lazyload" class and data-sizes automatically. These should be added manually or you can write a wrapper function if you would like to simplify things (please notify me if you think you wrote one that should be part of the module). Also all the module settings are gone except the "Load scripts" checkbox because all other settings became useless after the rewrite. The new syntax looks like this (here with a helper to add a noscript tag for no-js fallback): <?php $img = $page->featured_image; ?> <img data-srcset="<?php echo $img->srcset('200x300,*2,*3'); ?>" class="lazyload" data-sizes="auto" alt="" /> <noscript> <img src="<?php echo $img->srcsetUrls[0]; ?>" /> </noscript> The main change is that you can easily tell what image sizes (sets) you need ("200x300,*2,*3" in the above example). Of course you can use WxH values for each set or use divisors too. What's more you don't have to start with the lowest image size, eg. "1200x900, /2, /4" is perfectly fine.
    1 point
×
×
  • Create New...