-
Posts
1,336 -
Joined
-
Last visited
-
Days Won
62
Everything posted by BitPoet
-
Glad to hear that helped. What I meant regarding saved/added: the saveReady and saved hooks are executed every time you save a book page, even if it is just to amend some information. The created timestamp won't change anymore after the first save when it was added. The "added" hook will only execute once for each book page at the time it is created, so you can avoid running your code each time. On saved/added vs. saveReady: there might be an (unlikely, but not impossible) error where something prevents saving your book page. If that happens and you use saveReady, your parent page's lastcreated field will have been updated nonetheless, which will lead to an inconsistency until the next book page is added and correctly saved so it overwrites its lastcreated field again.
-
If that's the exact code, you have an error. It should read "$p->parent->lastcreated", not "$parent->lastcreated". Perhaps that's the whole cause. I'd put the code in a "saved" (or even better "added", since the created property isn't changed after the first save) hook though, so that updating the parent only happens after successfully saving the book page. <?php $pages->addHookAfter('added', function($event) { $p = $event->arguments(0); if($p->template->name == 'book') { $parent = $p->parent; $lastcreated = $parent->lastcreated; if($p->created > $lastcreated) { $parent->lastcreated = $p->created; } // Save just the lastcreated field and leave modified user and time alone $parent->save("lastcreated", ["quiet" => true]); } });
-
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.
-
Definitely. Thank for pointing that out, I have ammended my post.
-
Not sure where the best place for this is, but I felt like sharing a little snippet for site/ready.php I wrote that creates a PageArray::groupBy method: <?php /** * * Adds a groupBy method to all PageArray instances. * * Returns a nested array, with the values of the page properties whose names * were passed as arguments as the keys. * * Usage: * ====== * * $grouped = $mypagearray->groupBy(field1 [, field2 ...] [, mutator_function]); * or * $grouped = $mypagearray->groupBy(mutator_function); * * Example: * ======== * * $mypagearray = $pages->find("template=blog-post, sort=year, sort=month"); * $grouped = $mypagearray->groupBy("year", "month"); * * foreach($grouped as $year => $monthgroup) { * echo "<div class='year'><h2>$year</h2>" . PHP_EOL; * echo "\t<ul class='month'>" . PHP_EOL; * * foreach($monthgroup as $month => $mypages) { * echo "\t\t<li><h3>$month</h3>" . PHP_EOL; * * echo "\t\t\t<ul class='post'>" . PHP_EOL; * * foreach($mypages as $post) { * echo "\t\t\t\t<li><a href='{$post->url}'>{$post->title}</a></li>" . PHP_EOL; * } * * echo "\t\t\t</ul>\n" . PHP_EOL; * echo "\t\t</li>\n" . PHP_EOL; * } * * echo "\t</li>" . PHP_EOL; * echo "</ul>" . PHP_EOL; * } * * Example Output: * =============== * * <div class='year'><h2>2016</h2> * <ul class='month'> * <li><h3>1</h3> * <ul class='post'> * <li><a href='/grouptest/grouptest-10/grouptest-10-10/'>Group Test 10 10</a></li> * <li><a href='/grouptest/grouptest-6/grouptest-6-10/'>Group Test 6 10</a></li> * <li><a href='/grouptest/grouptest-10/grouptest-10-12/'>Group Test 10 12</a></li> * <li><a href='/grouptest/grouptest-1/grouptest-1-12/'>Group Test 1 12</a></li> * <li><a href='/grouptest/grouptest-5/grouptest-5-3/'>Group Test 5 3</a></li> * <li><a href='/grouptest/grouptest-10/grouptest-10-4/'>Group Test 10 4</a></li> * <li><a href='/grouptest/grouptest-3/'>Group Test 3</a></li> * <li><a href='/grouptest/grouptest-6/grouptest-6-4/'>Group Test 6 4</a></li> * <li><a href='/grouptest/grouptest-10/grouptest-10-7/'>Group Test 10 7</a></li> * </ul> * * </li> * * <li><h3>2</h3> * <ul class='post'> * <li><a href='/grouptest/grouptest-5/grouptest-5-10/'>Group Test 5 10</a></li> * <li><a href='/grouptest/grouptest-3/grouptest-3-7/'>Group Test 3 7</a></li> * <li><a href='/grouptest/grouptest-9/grouptest-9-5/'>Group Test 9 5</a></li> * <li><a href='/grouptest/grouptest-7/grouptest-7-12/'>Group Test 7 12</a></li> * <li><a href='/grouptest/grouptest-3/grouptest-3-11/'>Group Test 3 11</a></li> * <li><a href='/grouptest/grouptest-9/grouptest-9-11/'>Group Test 9 11</a></li> * </ul> * * </li> * * <li><h3>3</h3> * <ul class='post'> * <li><a href='/grouptest/grouptest-7/grouptest-7-10/'>Group Test 7 10</a></li> * <li><a href='/grouptest/grouptest-12/grouptest-12-12/'>Group Test 12 12</a></li> * <li><a href='/grouptest/grouptest-11/grouptest-11-5/'>Group Test 11 5</a></li> * </ul> * * </li> * * <li><h3>4</h3> * <ul class='post'> * <li><a href='/grouptest/grouptest-8/grouptest-8-3/'>Group Test 8 3</a></li> * <li><a href='/grouptest/grouptest-12/grouptest-12-6/'>Group Test 12 6</a></li> * </ul> * * </li> * * </li> * </ul> * * IMPORTANT! * ========== * * Your PageArray needs to be sorted by the fields you group by, or your return array will be an * unorderly mess (the grouping is still correct, but the order of keys is arbitrary). * * Mutator Function: * ================= * * Instead of just reading properties from the page, you can also pass a mutator function * to groupBy. It gets passed the page object as its first arguments and any optional property * names after that. * * This might come in handy if you want to group by year and month but only have a single * DateTime field. You can then use a grouping function like this: * * $blogposts = $pages->find("template=blog-post, sort=created"); * $grouped = $blogposts->groupBy(function($pg) { * return array(strftime('%Y', $pg->created), strftime('%m', $pg->created)); * }); * */ wire()->addHook("PageArray::groupBy", function(HookEvent $event) { $out = array(); $args = $event->arguments(); if(count($args) == 0) throw new InvalidArgumentException("Missing arguments for function PageArray::groupBy, at least 1 required!"); $last = count($args) - 1; $fnc = is_string($args[$last]) ? FALSE : array_pop($args); foreach($event->object as $pg) { if($fnc) { $props = call_user_func_array($fnc, array_merge(array($pg), $args)); } else { $props = array_map(function($propname) use($pg) { return $pg->{$propname}; }, $args); } $cur = &$out; foreach($props as $prop) { if(!isset($cur[$prop])) $cur[$prop] = array(); $cur = &$cur[$prop]; } $cur[] = $pg; } $event->return = $out; });
- 4 replies
-
- 15
-
-
-
[Solved] Navigation breaks on form template after using relative paths
BitPoet replied to ryanC's topic in General Support
Don't use relative paths. They are an artifact of days long gone (at least in regular websites - there are use cases in routed app components) and they create more problems than they solve. If you worry what happens when you move a site to a deeper directory, use PHP to prefix your links with $config->urls->root. -
I don't think this works. The size property for @page only accepts the values "auto", "portrait", "landscape" or an absolute width/height tuple. Named page formats aren't listed as supported.
-
That would be brilliant. Though @Soma might have to rename his module from Pollino to Pollissimo (it feels like it's about to outgrow the diminutive...)
-
Update: I have been playing around some more. There's now another branche dev-bitpoet-cke that includes a Textformatter which replaces ##POLL:name-of-poll-page## with the poll output and a CKEditor plugin for easy insertion.
-
What would be the best way to mirror json data into the Processwire DB
BitPoet replied to h365's topic in Getting Started
If you don't need to search by specific field names nested in the matrix, you could add a concatenated (hidden) textarea field, hook into saveReady and render the matrix contents into that field. Then include that field for your search. Or, if you want to be able to search by property names (at any depth) have at least MySQL 5.7.8, you could try out the attached module JsonSearchable.zip. It's a field type derived from Textarea that uses native JSON storage. Supposed you made a page field named "myfield" and entered a JSON of: { "testdata":[ { "segment":1, "title":"Hello World", "average":20, "max":"30", "min":5 }, { "segment":2, "title":"This is Funny", "average":40, "max":"30", "min":5, "details":{ "name":"nobody", "email":"secret" } } ] } You could e.g. search for <?php $pages->find("myfield=30"); $pages->find("myfield.max=30"); $pages->find("myfield.details.name=nobody"); Note however that this kind of search on many large datasets can be an absolute performance killer. Numeric comparisons are not supported. -
Hi @Soma! First of all, thanks for another really useful module. Since I'm planning to add polls to my blog site profiles, I've dabbled with it abit. To make things work nicely with the existing templates, I had to tweak a bit of the generated HTML and, in the course of that, changed your module a bit: It now uses templates for every bit of HTML produced Added config settings for all these HTML template snippets There's a template for the main wrap, so wrapping the renderPoll() return manually is no longer necessary Added a config option and poll template field for a poll closing date (+time) pollino-ajax-script.js now wraps a div around the result before inserting it. That prevents a jQuery error if the result contains more than one HTML element. I'm storing any array $config data passed to renderPoll() in the user session and retrieve it in the AJAX action Added collapsed fieldsets for different template areas (generic, form, result) in the module config Last but not least, added "PHP" hints to the code blocks in README.md I have made a fork and added a branch with all these changes here. Perhaps you could give it a look (test drive?) and tell me if I should prepare a pull.
-
[SOLVED(ish)] priviledges redirecting users from template wrong
BitPoet replied to benbyf's topic in General Support
Just perform the login while you have the developer console (F12) open, once on the dev site, once on live, and compare response headers line by line. See if something is missing or different on the live server. -
site-profile Yet Another Blog Profile: Editorial
BitPoet replied to BitPoet's topic in Themes and Profiles
Great minds think alike -
[SOLVED(ish)] priviledges redirecting users from template wrong
BitPoet replied to benbyf's topic in General Support
Are you logged in at all after the call to login (perhaps output your user name somewhere on the home page)? Are there any noticeable differences in the raw responses, especially the cookie headers (either in the login call or the redirect)? -
site-profile Yet Another Blog Profile: Editorial
BitPoet replied to BitPoet's topic in Themes and Profiles
Nah, ProcessWire is enough of an addiction -
Great job, @ryan! It was really astounding to watch the commits roll in and the open issues melt over the last few weeks, and there are so many new features too! I've been using latest dev versions extensively, and the few minor bugs I stumbled upon were solved before I could report them I even used some of the newly implemented features without realizing it This year already rocks!
- 16 replies
-
- 13
-
-
site-profile Yet Another Blog Profile: Editorial
BitPoet replied to BitPoet's topic in Themes and Profiles
Hehe. The yearly hey fever hit me over my holiday week, so I could a) dose myself up with that anti-allergy stuff that makes me too tired to do anything (including going out) or b) stay inside without drugs and find the time to spend a few hours every day doing fun things on my computer Choosing b wasn't difficult. The lacking choice of nice blogging templates in PW was something that has been nagging me for quite a while, so this was the perfect opportunity. I do hope so! -
Since all good things come in threes, here's another responsive blog profile for PW3: Editorial Travel Blog Template Like the previous two, it builds upon @kongondo's Blog module and uses @justb3a's Simple Contact Form. It also makes use of @Pete's XML Sitemap and @ukyo's Font Icon Picker. Features: Responsive Slide-in sidebar Homepage with picks and last posts, 3-column layout Selectable widgets, e.g.: Recent posts Recent comments Current month calendar with links to posts per day User-switchable sort order for lists (ascending/descending) Configurable list pagination An online demonstration can be found here. And again: all feedback is welcome!
- 15 replies
-
- 17
-
-
-
site-profile Blog profile "Striped" (in development)
BitPoet replied to BitPoet's topic in Themes and Profiles
Let's give the users a choice -
site-profile Another Blog Profile: Strongly Typed
BitPoet replied to BitPoet's topic in Themes and Profiles
Update: there's now a preview available here.- 1 reply
-
- 1
-
-
site-profile Blog profile "Striped" (in development)
BitPoet replied to BitPoet's topic in Themes and Profiles
I have just set up a small preview with a few "real life" pages here. -
And here's another site profile, again based on a free template from html5up.net: Download link: Strongly Typed Travel Blog Template (Responsive) GitHub Repo Features are much the same as in: Additionally, the sidebar can be aligned either to the left or right, and navigation is cached for 24 hours using MarkupCache. As always, I'd be happy about any feedback. Mobile Screenshot:
- 1 reply
-
- 7
-
-
Repeater field error: table creation not allowed
BitPoet replied to ivineets's topic in General Support
Sounds like MyISAM is switched off in your database server. You can either switch this back through a storage engine setting in your server configuration (see MySQL docs for details) or you could try switching to InnoDB (if your version already supports FULLTEXT indexes for InnoDB) by adding $config->dbEngine = 'InnoDB'; in site/config.php. -
I'm not sure. You could add some htaccess/rewrite trickery to avoid redirects, but that would mean that all template settings have to be identical. If somebody changed the trailing slash setting for just one template, that would fail even worse (like end in an endless redirect loop). It might be possible to avoid his kind of error if the backend issued a redirect with a 307 status code instead of 301 for slash url redirects, as that would preserve the request method and POST data for the repeated request, but there has been a lot of back and forth about 307 and308 methods, browser implementation details, compatibility with older browsers and possible security issues which I haven't been following up on. Perhaps @ryan himself might be able to say whether redirecting with 307 would be an option.
-
site-profile Blog profile "Striped" (in development)
BitPoet replied to BitPoet's topic in Themes and Profiles
Thanks for pointing that out. I only changed this after I removed all the test posts that triggered the pager I have updated the repo.