Leaderboard
Popular Content
Showing content with the highest reputation on 04/27/2018 in all areas
-
Happy Friday! Just a short update this week. This latest version of the core on the dev branch contains a whole lot of commits, mostly related to GitHub issue resolutions. See April 23–27 in the dev branch commit log. Thanks for all the continued testing, reports and discussion. I don't have anything new to report other than that, but am working to have another master version here shortly. Thanks and have a great weekend!11 points
-
Sorry, Boss! It's not what you think. I'm on the site for the source code only, not for the girls. Honestly!5 points
-
No surprise here.. I guess I am from the old school. A 'long time' ago, logos used to be background images set on anchors (<a> tags). Menu items (<a> tags) used to have background images called sprites that would 'shift' on hover to create a nice hover effect...3 points
-
3 points
-
hmm, some of these results are simply BS. One was a Shopify site, another MediaWiki. But lo and behold, I also found two adult sites built with PW (thank God I didn't open them in my office...) NSFW!3 points
-
Just found this nice collection of open-source PHP + JS projects: https://spatie.be/en/opensource One of them is used in a (very nicely written) PW tutorial http://blog.mauriziobonani.com/processwire-building-a-basic-reserved-area/3 points
-
This was an interesting read. http://blog.mauriziobonani.com/processwire-building-a-basic-reserved-area/3 points
-
Forgot to say, welcome to the forums! ProCache is awesome. And if you were you, I'd take a look at @tpr's Latte module too. It's great!2 points
-
Hey @bernhard - I get your issue with empty vs bloated for sure. When I get some time I'll look into the possibility of a check for an empty object, although I do think that maybe that's something the PW wire __debugInfo method might be the best way to handle this. Just an FYI - Ryan just added a detailed PageFiles __debugInfo() method, so now we get this in the Request Info panel, which is pretty nice!2 points
-
@Robin S, @Torsten Baldes and everyone else. Ryan has just implemented my suggestion for that snippet of JS which means that I can now remove the autocomplete removal hack from this module. Please update your PW core and this module and let me know if you find any further issues. Thanks!2 points
-
Maybe you are calling $copy->of(false) in the wrong place. This works for me, cloning a page with children and grandchildren. $copy = $pages->clone($page); //$copy->parent = '/cloned-parent/'; $copy->title .= $page->title . ' - copy'; $copy->name = $sanitizer->pageName($copy->title); $copy->of(false); $copy->save();2 points
-
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 change1 point
-
I've just added a pull request for a ProcessWire driver to laravel valet: https://github.com/laravel/valet/pull/55/files For anyone wanting to have a quick local dev environment (on a mac) you should certainly take a look. https://laravel.com/docs/master/valet1 point
-
Yeah, I remember making logos for a tags using: <h1><a href="/">COmpany Name</a></h1> a.logo { width: 350px; height: 75px; text-indent: -9999px; background: url(logo.png) no-repeat left top; } I never used many backgrounds with spans however.1 point
-
That's correct. The output from Twig is cached as static file and if present, ProCache directly serves this via .htaccess.1 point
-
As long as you use regular selectors and don't loop over thousands of pages it will be perfectly fine1 point
-
Yes. Unless I'm utterly wrong. Twig will render PHP files at runtime, and their output in the browser is the same output that's processed by ProCache. ProCache will render static version of the pages in /assets/ProCache-xxxxx/page-name/index.html that will be server by .htaccess rules (or Nginx rules, like I do)1 point
-
You really should!! Just make sure port 80 is not blocked by any other program ( https://forum.laragon.org/topic/929/no-port-80-in-use-check ) It's incredibly easy to switch php versions and different php settings (like I showed with xdebug). You can even use it as portable version on a usb drive (I think that version is limited to one php version, though). But moving your sites is as simple as copying the related "www" and "data" folders to another instance of laragon. https://medium.com/@oluwaseye/add-different-php-versions-to-your-laragon-installation-d2526db5c5f1 It's also the fastest setup I've had so far (tried xampp and vagrant).1 point
-
<unrelated> I need to try laragon again. Last time I did, it didn't work for me or I didn't want to exclusively work on PHP 7.x. I still need to support PHP 5.3 + for some of my modules and laragon did not seem to support that? </unrelated>1 point
-
1 point
-
This one seems to be a rather big PW site: https://www.surveysampling.com/ And then another gov site: http://catawbacountync.gov/ https://www.niagarafallstourism.com/ seems also nice http://www.livius.org/ The Livius.org website offers information on ancient history. Now there are 3883 pages. You will also find more than 9,100 original illustrations. https://albertina.at/ stunning museum site https://www.centarzdravlja.hr/ a Croatian health/lifestyle portal https://www.stromvergleich.de/ compare electricity prices across Germany https://www.iphm.co.uk/join-iphm/therapists/iphm-therapist-online-application/ big signup form built with FormBuilder https://www.valkevents.com/ Dutch event company http://www.cuafc.org/ Cambridge University Association Football Club http://fashion.si/ Slovenian fashion mag1 point
-
Unfortunately, still didn't work. End up using alternate solution: using symlink, not really pretty like htaccess but similar result. @szabesz BTW thanks for helping to references, indirectly that refer to alternate solution above.1 point
-
Sure, I'm with you here. But I think it's much more critical to get an empty dump than to get a bloated one where you need to look for the correct information and maybe turn on the "cleanup feature". But I can live with both versions, of course Edit: @adrian could it maybe show a notice on empty debugInfo objects to turn "debugInfo cleanup" OFF to be sure it is really empty?1 point
-
1 point
-
1 point
-
@adrian Sorry I just saw this. If it breaks something revert it. Seems to work for me.1 point
-
If you check this tutorial https://support.plesk.com/hc/en-us/articles/213367429-How-to-upgrade-MySQL-from-5-1-to-5-5-on-Linux, you can see a note that says "The PHP package can also be updated during this procedure". I did not pay attention to this because I had installed the latest version of PHP, but it seems that anyway the package and its configuration were changed during the upgrade. maybe.. and during the user login at admin too.. because like in my example, it can happen after the installation... At least we need a topic, or a recipe at https://processwire-recipes.com/ or wherever the option we have, to guide beginners like me. Explaining all the test that must be done after "This request was aborted because it appears to be forged" because after my investigation I found several causes for this, and almost 127 forum entries about it. https://www.google.com/search?q=site:processwire.com+"This+request+was+aborted+because+it+appears+to+be+forged" Now, at this moment I can breathe! I want to say a BIG THANK YOU to @flydev who won my admiration and has been a wonderful human being1 point
-
It's a bit on the back burner right now. I was hoping for some more elaborate possibilities with MySQL 8, but the changes to JSON support there were on the homeopathic end rather than the dynamic typing support I had hoped for. I plan to brush up the UI and client side validation a bit once PW 3.1 gets out, though, and test things out in depth with UIkit admin theme.1 point
-
i added this parameter, working now JSON_UNESCAPED_SLASHES file_put_contents('posts.json', json_encode($json, JSON_UNESCAPED_SLASHES));1 point
-
1 point