Leaderboard
Popular Content
Showing content with the highest reputation on 06/10/2016 in all areas
-
We've got some great updates for you this week, especially for those still running ProcessWire 2.x. ProcessWire 3.x also got a lot more stable this week. In fact, this week ProcessWire 2.x and 3.x got a lot closer! https://processwire.com/blog/posts/processwire-3.0.21-and-2.8.21/11 points
-
Hi Mélanie and welcome to ProcessWire! Since you are starting a new project, I would definitely go with the devns branch which is the upcoming 3.x version. It is quite close to being released as the new stable version and many of us are using it on production sites, including processwire.com Don't be shy about asking questions as you start to dive in - I am sure you'll love it7 points
-
6 points
-
Thought I would release a pretty simple module I made that integrates the awesome OneLogin PHP SAML toolkit into ProcessWire so you can use SSO with your ProcessWire website. Mainly developed for my own purposes as I have used SAML plugins with WordPress for many years and now that ProcessWire is my go to CMS I sort of missed the convenience of having SSO between sites and services. This is my first attempt at a ProcessWire module, it's probably not the best in terms of code, but it has been pretty stable in my tests. Here's a little demonstration of the module in action https://www.youtube.com/watch?v=YWcsV6RTh90 GitHub repo and Installation Instructions https://github.com/adamxp12/ProcessWire-SAMLAuth Any feedback would be appreciated. Even though this is quite a niche module.5 points
-
The redirection is probably the most problematic part of this plan, because the new page load will interrupt the visitor’s typing. What you would want to do is keep the search box and simply change the rest of the page using javascript. If the browser supports it, you can use history.pushState() to do manipulate the address bar, so visitors can have bookmarkable links to their search results. Here is a crude solution using jQuery. As you can see, JavaScript does most of the work: Normal page looks somewhat like this. There is a search box and some unrelated content. <body> <form id="searchform" method="GET"> <input type="text" name="s" value="purple unicorns" /> </form> <div id="content"> <!-- Your regular content stuff goes here. If the user starts typing, we replace all of this with a placeholder, do the search, then replace it with the results. Of course you would want to do something a bit more sophisticated and pretty in real life. --> </div> </body> Some JavaScript that runs on the above page and requires jQuery. $(document).ready(function() { $('#searchform :input').on('input', function() { $("#content").html('<h2>Loading…</h2>'); loadSearchResults(function(result) { if (result === false){ result = '<h2>An error occurred.</h2>'; } if (result == '') result = '<h2>No results found.</h2>'; $("#content").html(result); }); }); function loadSearchResults(callback) { var form = $('#searchform :input[value!=""]'); var serialized_form = form.serialize(); //if your search field is named “s” this will be “s=search words” if (serialized_form !== '') { var new_url = '/search/?'+serialized_form; //consequently, this will be „/search/?s=search words“ if (/* IE9 needs this check */ history.pushState) history.pushState({}, '', new_url); //your address bar now shows www.example.com/search/?s=search words $.ajax({ type: form.attr('method'), url: '/search/', data: serialized_form, success: function(result) { if (callback && typeof(callback) === 'function') { callback(result); } }, error: function() { if (callback && typeof(callback) === 'function') { callback(false); } } }); } } } The search page /search/ handles a GET parameter called s and either serves a full results page, or just the markup necessary to inject it into existing pages. <?php $s = $input->get->text('s'); $results = $pages->find("title%={$s}, limit=100"); $results_markup = "<h2>{$results->count} results found for “{$s}”:</h2>"; $results_markup .= "<ul>"; foreach($results as $r) { $results_markup .= "<li><a href='{$r->url}'>{$r->title}</a></li>"; } $results_markup .= "</ul>"; //if we’re live-searching, output only the results markup, //without <html>, <body> etc. if($config->ajax) { echo results_markup; return $this->halt(); } //now do your regular markup include('head.inc'); echo $results_markup; include('foot.inc'); ?> IRL you would probably serve JSON instead of full markup, but this keeps the JavaScript part short. You would also want to handle cases where users use the live search and then hit their browser’s back button.4 points
-
I'm really loving all the new stuff on 3.x (and now 2.x). Have a great weekend Ryan, and thanks again for being a badass.3 points
-
This was helpful debugging one issue. In later PW-versions you have to add findOne into $options array to make it work: $selectors = new Selectors("template=blog-post, limit=5, sort=name"); $pagefinder = new PageFinder(); $options = array('returnVerbose' => true, 'findOne' => false); $sql = $pagefinder->getQuery($selectors, $options)->getQuery();3 points
-
So this is where the zombie apocalypse begins. Seriously speaking: for-page-20044 is the parent of repeater items connected to page 20044. The parent of this page should be named after one of your existing repeater fields. Do you have page with ID 20044 in the system and does it have repeater fields? What about those other pages you mentioned? If, say, you have a repeater parent called "for-page-12345" and there's no page with ID 12345 in the system, then this could be a sign of cleanup not working as expected. On the other hand if a page matching each repeater parent does exist, this probably just means that you've got hundreds of pages using a template with at least one repeater field attached. Just an idea, but perhaps you could post a screenshot displaying these pages in the admin. These things are sometimes difficult to explain with text alone3 points
-
Just tested with 200 JPG files on PW-3.0.18 with SessionHandlerDB, 12 images are missing.2 points
-
Oh really? Lots of headaches for something that simple to find out? Here's your 3000th like!2 points
-
Another solution // number of news per news page $limit = 20; // get all news $allNews = $pages->find("template=news"); // get the specific news item $selector = // selectorstring to get specific news item $specificNews = $allNews->get($selector); // get the page number where to find the specific news item $key = $allNews->getItemKey($specificNews); $pageNum = ceil($key/ $limit);2 points
-
When working with Namespaces, (PW3), it is allowed to use different namespaces in one file. Assuming you have a php file you want to include with this code: <?php echo "<p>I love $var!</p>"; you can have a template file like this: <?php namespace ProcessWire { // ... } namespace fake1 { $var = 'apples'; include('./_namespace-include-test.php'); } namespace fake2 { $var = 'bananas'; include('./_namespace-include-test.php'); } namespace ProcessWire { $var = 'oranges'; include('./_namespace-include-test.php'); // ... } The output will be: Why and how this works is in the PHP manual. There you also can read that this is bad practice.2 points
-
Have not tried it so no gurantees. 404 page is just a page (though with it's id or name or both hard coded somewhere in the core). It is accessible in the page tree. So try to change the template of that page and write some code in template file to handle your case. Something has to be availiable there, like the url initially requested. But honestly I do not think that throwing a 404 for a product out of stock is a good idea in the first place. Maybe show some message (but with the 200 code) and handle the case in the product template file.2 points
-
Hey, ROBINJAIN! Welcome here, whatever country, county, location or village you're from . A user in PW is a page (almost) like any other. You can extend this page with custom fields and then retrieve the values of those fields (via $user API variable) at runtime and use them to determine, what content to show to specific user. Hope I got your question right. If not, please feel free to ask again.2 points
-
You can use WireIncludeFile core function and pass something like $p (Page) as variable into it. In the included file you can use $p instead of $page, so it will be something like $this for ya.2 points
-
included_file.php <?php $fruit = 'banana'; echo "<p>My fruit is a $fruit</p>"; main.php <?php $fruit = 'watermelon'; call_user_func( function() { return include func_get_arg(0); }, 'included_file.php' ); echo "<p>My fruit is a $fruit</p>"; Output: <p>My fruit is a banana</p> <p>My fruit is a watermelon</p> Credit2 points
-
None that I'm aware of. Of course you can always use PageFinder for this, but it's going to look a bit hacky: $selectors = new Selectors("template=blog-post, limit=5, sort=name"); $pagefinder = new PageFinder(); $options = array('returnVerbose' => true); $sql = $pagefinder->getQuery($selectors->getArray(), $options)->getQuery(); // .. and so on, depending on what exactly you're looking for2 points
-
This module extends WireMail base class, integrating the PHPMailer mailing library into ProcessWire. Module Directory - Githup repo1 point
-
I just wanted to know if anyone can reproduce this behaviour: https://github.com/ryancramerdesign/ProcessWire/issues/1871 Install SessionHandlerDB and upload a bunch of jpg to an images field. They upload fine and show but after saving the page some images are not saved and wont show anymore. They're still in the assets folder but orphaned. Thanks1 point
-
1 point
-
I, too, have experienced this, but didn't know it was due to SessionHandlerDB (which is usually the first thing I install on new sites).1 point
-
Ended up using the pageNotFound hook like you suggested, works like a charm. Still having some issues with the ProcessWire module config system, but will be easier just to bypass it and have users edit the settings.php file that the SAML library provides. Now just need to clean up the code a bit and my module is complete, which is cool.1 point
-
Well I think we'll have to stick with this bug still for a long time since Ryan can't reproduce it. I just installed again a vanilla PW locally and same scenario once SessionHandlerDB is installed.1 point
-
Ah sorry - yes of course that will be a problem for non-logged in users - didn't think that through If you go with dummy templates you'll still need to create a template php file in the site/templates directory to include your acs.php file. I think the easiest option is going to be to simply instruct users of the module to move acs.php to the root of their site. Another idea might be to check f the url contains acs.php and then hook on the pageNotFound to call a function which contains the logic from acs.php, eg: https://github.com/Notanotherdotcom/MarkupSitemapXML/blob/master/MarkupSitemapXML.module#L28 Maybe I am missing something else obvious - it's early and I am groggy!1 point
-
1 point
-
I can confirm this. This persist since a long time back in the past. Since then, we only upload bunches of images packed as zip archive. But until now, I wasn't aware that it may have to do with the SessionHandlerDB.1 point
-
It's surely possible. Recently I've done a very similar newsletter solution, see screens here. Basically you need to send an email with contents of the newsletter page body (or other) field. Things get complex when you need things like preview email (which is a must imho), subscriber lists, etc. I've done this addons mainly with JS/Ajax.1 point
-
If you take the red pill and go deep down the dark path of using devns....just kidding This module is definitive the best way to go http://modules.processwire.com/modules/process-wire-upgrade/ (Since every week there is a new dev version - upgrading with the module is a very easy thing and you could complete roll back.) Using the actual devns for a upcoming project and i think i'll be finished if the 3.x stable is there - then i will upgrade to stable and leave it on this version until i need other features or have a problem...but that are just my thoughts. regards mr-fan1 point
-
Welcome, Mélanie! It seems like almost everybody here tend to move to the latest dev release as soon as it is possible. Maybe it is because so much new tasty features are in almost every dev release, or maybe because almost every dev release is as stable as master. I would definitely encourage you not to be afraid of the dev status in most of the cases. Maybe not for a billion-visit-per-day sites, but in most cases) P.S. But backups are still a must, you know.1 point
-
What @adrian said... also see: https://processwire.com/api/coding-style-guide/#4-classes-properties-and-methods http://processwire.com/api/modules/ https://processwire.com/talk/topic/2394-how-to-present-your-module/1 point
-
Read this example fully and you'll understand your issue: http://php.net/manual/en/functions.anonymous.php#example-2001 point
-
Hey gentlemen! I just happen to need this kind of js on a project of my own and am experiencing some trouble with implementing it. So please post the solution here if it is possible. Or just do not go private .1 point
-
I'm not sure if there's really a better way to do this, without potential for breakage. $pageNum = 1; $limit = 20; $start = $pageNum - 1 * $limit; $base = "template=news, id=$mySearchedPage->id"; while($pages->count($base . ", start=$start")){ $count = $pages->count($base . ", limit=$limit, start=$start"); if($count) break; $pageNum++; $start = $pageNum - 1 * $limit; }1 point
-
if($input->pageNum == 1){ $featured = $page->get('template=blog-article, sort=-article_date'); } $rest = $page->find("template=blog-article, limit=10, sort=-article_date, id!=$featured"); // Create any pagination markup here! if($input->pageNum == 1){ $rest->prepend($featured); } // Render items1 point
-
For the simple minded this would be the foreach version that does the same. $colors = array(); $childrenByColor = array(); foreach($children as $child) $colors[$child->color][] = $child; foreach($colors as $color => $items) { $childrenByColor[] = "$color (" . $items->implode(",", "title") . ")"; } $line = implode(", ", $childrenByColor);1 point
-
Agreed, that makes a lot more sense. I'm one of those developers who tend to lean towards the simplest possible implementation and as few external dependencies as possible, even if that means writing a few extra loops, but I can definitely see the value in this1 point
-
Ok, slightly out of context, because it's Javascript, but these 3 videos from funfunfunction could really help you to understand those 3 functions: It's a series, watch them in sequence1 point
-
Coming from a Rails background years ago, I think it's best to stick with web application frameworks for any web applications that will have heavy iterations and multiple team members. With a webapp framework, you get a testing suite, migrations, ORM, REST, MVC, specific deployment tools and many other necessities. You would have to re-do all those with ProcessWire. Furthermore, using pages to act as a router doesn't feel right. "Use the best tool for the job" and all that.1 point
-
Sure – where I work at we did exactly that, and haven't looked back since. First of all, it's important to understand that at it's core ProcessWire is a (web) application framework. We prefer to call it a content management framework, but that's not very far from what most web applications do: they store, process, and output content. The way I see it, the main difference to so-called traditional frameworks is that modelling and handling data is a built-in feature, not something you have to reinvent on a case-by-case basis. I have rebuilt a couple of old projects from the scratch using ProcessWire, and in all of those cases this has saved me a lot of time and made most of the model layer obsolete. Before we started using ProcessWire we were doing sites with another CMS and custom applications with Zend Framework. At the beginning I had this idea that we would use ZF for "apps" and ProcessWire for "sites", but in just a few short months we realised that there just wasn't anything we could achieve with ZF that couldn't be done, usually with less work, with ProcessWire. Sure, sometimes we pull other libraries into the mix, but that's not a shortcoming; in my opinion it's just good design Regarding some of the things that have been mentioned here: One thing I was originally missing from Zend Framework was a clearly defined structure. Built-in "one file per template" concept is great for simple sites, but that's just about it. This is why I built the original version of my MVC project. It's not perfect, but it has served us well for years. To get most out of ProcessWire you really should be using it's data modelling abilities. Sure, you can still mock up your own data structures and write SQL to fetch content from the database etc. but that's kind of missing the point: ProcessWire makes data modelling a breeze and the selector engine is both flexible and secure. Some users prefer to build custom management panels, but in my opinion that's another thing you should try to avoid. ProcessWire's admin GUI is flexible and extendable (see Process modules), and again: in most moderately sized projects it can easily save you days of work. For routing you can use page URLs, but I'd also suggest looking into URL segments. For me, coming from the world of Zend Framework, templates are a lot like controllers and URL segments make it easy to implement the concept of actions Try not to invent your own access management system. ProcessWire has a very good implementation of RBAC already in place, and if you need more flexibility, I'd suggest looking into modules such as Dynamic Roles and/or User Groups. Rolling out your own solution is risky, tends to cost a lot, and just generally speaking is a very bad idea. Form validation has been mentioned twice here already. I don't have much insight into this, except that in the beginning we used to build forms using Zend Form, which has it's own validation built-in. That was always a bit tricky (not because of ProcessWire), and these days we use Form Builder for pretty much every form-related need. Sure, it's a commercial module, but it has saved us so much time that the price is absolutely not an issue. In my opinion the answer to your original question is yes and no: ProcessWire can't substitute an application framework because it is an application framework1 point
-
For reference, you can also make sure this happens when a page is saved in the admin as well. <?php class AdminHelperHooks extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Admin Helper Hooks', 'version' => 1, 'singular' => true, 'autoload' => true ); } public function init() { $this->addHookAfter('Pages::saveReady', $this, 'hookChangeNameToID'); } public function hookChangeNameToID(HookEvent $event){ $page = $event->arguments(0); // get the page being saved if ($page->template == 'lost-property'){ // check the template $page->name = $page->id; } } }1 point
-
Where does the $title variable come from in your code? You don't show where it is set. To set the URL you want to set the name of your page. $np->name = 'something'; If you don't set a name (as in your code) the name is generated automatically from the title. If you are setting a name from a variable you can pass it through $sanitizer->name($my_variable) to make sure it is a valid name. In your case you want to set the name to the same as the page ID. But when you are first creating your page the ID doesn't exist until you save it. So you can do something like this: $np = new Page(); // create new page object $np->template = $templates->get("lost-property"); $np->parent = $pages->get("/lost-property/"); $np->title = 'my title'; $np->save(); // save the page so you can get its ID $np->name = $np->id; // set your other page fields $np->save();1 point
-
Exactly. You would even get $settings in template context.1 point