Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by SwimToWin

  1. When working with Checkboxes ("Type: Page Reference - Input field type: Checkboxes - with Page field value type: Multiple pages PageArray" fields, that is), this works: $rs = $pages->find('template=foo, parent=/bar/'); foreach ($rs as $p) { $p->of(false); $p->myCheckboxes = null; // Unset all values first $p->myCheckboxes = 'baz'; // Then set the active checkbox with name (or, use Page ID) $p->save(); }
  2. Small request: When working with files outside ProcessWire, it would be useful to know the the public / web folder. Having this folder or directory will allow me to work with the "non-Processwire file system". Example: /var/sites/www.example.com/public/ <- (or whatever your hosting provider calls the public directory for a website) I can get the directory with $_SERVER['DOCUMENT_ROOT'] - unfortunately, the $_SERVER variable is easily manipulated and therefore unsafe (needs to be escaped and such). sprintf('%s/%s/', $_SERVER['DOCUMENT_ROOT'], 'whatever'); Currently print_r($config->paths) outputs two array keys that hold (too deep) info about the public web directory: [sessions] => /var/sites/www.example.com/public/site/assets/sessions/ [classes] => /var/sites/www.example.com/public/site/classes/
  3. I'm importing data from an external system into ProcessWire. Each of the imported records have a unique ID. How might I use the unique ID to prevent duplicate records in ProcessWire? What I want: When importing data find the foreign record ID use it to check for duplicates if a duplicate record is detected, skip it import data into ProcessWire by creating a page in /import/ continue to next record ProcessWire: Later I'll move each page to another location ... meaning that '/import/' will be empty the next time, I run an import job Looking into possible solutions: Unfortunately, ProcessWire Unique Text Fieldtype doesn't do the trick. (ProcessWire Unique Text Fieldtype will allow the page to be created - only the field with a duplicated field value will be blank. In my case, the duplicate record needs to be blocked / *not* created.) Could it be solved by modifying the code for ProcessWire Unique Text Fieldtype?
  4. Solution: has('name') does the job, that's also self-explanatory .. compared to using IDs, as I did in my tests above. var_dump( $page->config->has('foo') ); // bool(true)
  5. Thanks Andreas @AndZyk - both for solution and find() explanation; never used find() much
  6. It's incredible what you can do with ProcessWire. I did hit a limitation on my side though... 😉 and would like to ask for some support: Problem: I'm using a Page Reference Checkboxes field that gets it's Options from a few Pages; Page field value type is set to "Multiple pages PageArray". Screenshot: What I want: to check if each checkbox is checked or not (without using a foreach loop). What I tried: var_dump( $page->config->has(1898)); var_dump( $page->config->getValues()); // (WireArray is output, I don't know how to use that.) var_dump( $page->config->getValues(1898)->id ); // Warning: Attempt to read property "id" on array var_dump( $page->config->get(1898) ); // NULL var_dump( $page->config->get(1898)->id ); // Warning: Attempt to read property "id" on null var_dump( $page->config->first()->id ); // int(1898) ... better, but how to get the next value? var_dump( $page->config[1898] ); // bool(false) var_dump( $page->config->find(1898) ); var_dump( $page->config->find(1898)->id ); var_dump( $page->config(1898) ); NULL (checkbox is set) var_dump( $page->config->1898 ); // unexpected integer "1898", expecting identifier or variable or "{" or "$" var_dump( $page->config->find(1898)->id ); // Fatal Error: Uncaught Error: Call to a member function find() on null var_dump( $page->config->has(1898)); // Fatal Error: Uncaught Error: Call to a member function has() on null $a = $page->config->getValues(); echo isset($a->1898->id) ? 1 : 0; $a = $page->config->getValues(); echo isset($a->1898->id) ? 1 : 0; // Parse Error: syntax error, unexpected integer "1898", expecting identifier or variable or "{" or "$" echo isset($a[1898]->id) ? 1 : 0; // 0 (but checkbox is set?) echo isset($a[1898]['id']) ? 1 : 0; // 0 (but checkbox is set?) var_dump( $page->config->eq('foo')->id ); // int(1898) var_dump( $page->config->eq('foo') ); // wirearray var_dump( $page->config->has('foo')); // bool(true) // Is this a bug? eq() returns same Page ID for two names. echo $page->config->eq('foo'); // 1898 (correct) echo $page->config->eq('bar'); // 1898 (incorrect, the ID is 1899. ... and thanks for always being a helpful, constructive, and knowledgeable community! Make a great day! 🙂
  7. When I use the suggested solution, then I loose the default markup from main.php. How might I keep the default markup from main.php
  8. `<?php var_dump($page->content3); ?>` outputs NULL. It seems $page->content3 isn't populated?
  9. I use these Markup Regions and Bulma CSS Framework in _main.php: <section class="section"> <div class="container"> <div id="content1" class="content"></div> </div> </section> <section class="section"> <div class="container is-fluid"> <div id="content2"></div> </div> </section> <section class="section"> <div class="container"> <div id="content3" class="content"></div> </div> </section> I want to specify HTML tags required by a CSS framework - and it shall be output only when the Markup Region produces an output. I want the full SECTION to be hidden in case the region doesn't output - because if the SECTION tags are output then it will affect the layout in unintended ways. So my question is, how can I hide SECTION tags when the region doesn't produce an output? To me, the challenge here is that Bulma requires a layout structure before Content 1-3 are output (specifically, the SECTION and DIV.container tags) - and it seems this pattern is always output by Markup Regions - which is causing the mentioned issues. Feel free to suggest alternative ways to work with Markup Regions and Bulma (or other CSS frameworks).
  10. Regarding multi-language fields such as TextLanguage, TextareaLanguage, and PageTitleLanguage: When multi-language fields are shown in Page Edit mode, I often use them next to non-multi-language fields. That makes the page appear a bit disorganized and cluttered because multi-language fields vs non-multi-language fields don't align horizontally. The reason is that multi-language field have "language switcher tabs" that forces the field to "jump down" whereas normal fields stay in the normal position. See screenshot 1. It makes me sea sick! 😉 Suggested solution is to move the "language switcher tabs" up so that it aligns with the field label. See screenshot 2.
  11. @dragan - That'll work. Thanks! I use the snippet below that copies the full Image object so that all Image properties remain intact for use in the subsequent foreach(): foreach ($page->children() as $p) { $imgs = $pages->get($p->foo->id)->images; if( isset($p->foo->id) && $imgs ) { $gmi = []; foreach ($imgs as $img) { $gmi[] = $img; } foreach ( array_reverse($gmi) as $v) { echo "<img src=\"{$v->width(140)->url}\" alt=\"{$p->foo->title}\">"; } } }
  12. How might I programmatically output images from an Image field from another template in descending order? I want to reverse the order of images on the front-end page (see code below). I want to keep the order in ProcessWire Admin. The Image field accepts multiple images. Code: foreach ($page->children() as $p) { if( isset($p->foo->id) && $pages->get($p->foo->id)->images->count>0 ) { foreach ($pages->get($p->foo->id)->images as $img) { echo "<img data-src=\"{$img->width(140)->url}\" width=\"\" height=\"\" alt=\"{$p->foo->title}\" class=\"uk-align-right uk-visible@m\" uk-img>"; } } } Things I tried (that didn't have an effect): $pages->get($p->foo->id)->images->sort("sort=-sort") $pages->get("id={$p->foo->id},sort=-sort")->images I also wanted to try a for() loop but didn't know how to.. # Failed attempts: $pages->get($p->foo->id)->images[0]; $pages->get($p->foo->id)->images->1; # This works - but only for first and last (not a third image) and I would need to check if each image existed. $pages->get($p->foo->id)->images->first; $pages->get($p->foo->id)->images->last; I am aware that ProcessWire isn't specifically designed for working with child pages this way - it's probably even a bad practice - it's just that it almost always works very, very well. 🙃 PS: Would you normally set the width and height attributes, or leave them out?
  13. @adrian's script works like a charm when executed from a template page - I followed these steps: Step 1 - Create new template with same fields set as on the repeater field. * Field names must match (if they don't, you might map them manually). Step 2 - Add the script to a Template. * I set repeater field name and page template name. * The script will attempt to copy all "repeater pages" found by '$page->$rf'. So, I used a template file that could access the repeater fields with '$page->$rf'. Step 3 - Run the migration by visiting the page. * At this point, I removed the script and inspected the results. Results: * All fields were migrated (saved me a ton of detailed copy-paste work!). * Title field was set to a code ("1234-9234") because my Repeater didn't have a Title field - but it was easy to update manually. * Url name field was set to a code ("1234-9234") - and updated after I manually pressed Save on each page. * Even language fields were correctly migrated. Nice! <?php $rf = "my_source_repeater_fieldname"; //repeater field name $pt = "my-destination-page-template"; //page template name foreach($page->$rf as $r){ $np = new Page(); $np->of(false); $np->template = $pt; $np->parent = $page; foreach($r->fields as $f){ $np->$f = $r->$f; } $np->save(); }
  14. Where I am: Edit Page -> Settings -> Parent -> "+Change". Edit Field -> Page Reference field -> Input tab -> "Selectable pages (Select the parent of the pages that are selectable)" -> "+Change". ... and possibly other locations where the Page Tree is used. Quality of life improvement: When modifying Parent Pages (Edit Page) or Selectable pages (on a Page Reference field) and I press "+Change" to change the Parent Page, it would be nice if the current Parent Page came into focus without effort. Current solution: As an editor, I am required to find the Parent Page / "Page Reference parent page" manually which makes me think ("where did I put that page?"), takes a bit of time ("click, click, click"), and is hard on a larger site with a deep structure. The unmet goals are: I instantly see the context for the current Parent Page. I can effortlessly select another Parent Page. Constraints: Large website makes it hard to navigate and get a view of the Page Tree. I don't want to pick an incorrect Parent Page. It's sometimes difficult to see if I choose the right parent. The Parent Page must be in the current "Page Branch" ("/foo/bar/baz/" -> "/foo/quz/baz/"). I don't always need to see/browse the full Page Tree. Sometimes a lot of parent pages are unnessarily shown (larger websites with 4-5 levels of pages). Better: When I open the Edit Page / Edit Field page and click "+Change", I want the tree structure to expand (in a modal?) and bring the current Parent Page into focus. It's one of those small things that help create a smooth user experience. Additional thoughts: The displayed Page Tree only shows the current Page Branch; this might optionally be specified on the Template. Hide "unneeded" parent pages in a larger websites with 4-5 levels of pages (how?). Perhaps you have additional ideas that might improve working with Parent Pages when editing a page or a field?
  15. 1) It seems, the SEO reason that I gave is being taken very literaly. To me, it's more a matter of having built-in flexibility to structure pages without necessarily exposing the structure. I may not want to expose the parent page in the front-end. 2) "Virtual Pages" aligns with Ryan's "no assumptions" design principle. ProcessWire allows the admin to structure pages - but doesn't make (too many) assumptions about how these pages are output in the frontend. Or, to put it in the words of Ryan, "ProcessWire doesn't control the front-end, there are very few assumptions that can be made from an editing perspective." See also: No assumptions (cute interview!). 3) Short urls are cool - SEO or not - and "Virtual Pages" help me achieve that. Consider these versions of the same url: Long: www.example.com/book-reviews/wheres-wally-in-hollywood/ Short: www.example.com/wheres-wally-in-hollywood/ 4) WordPress has a bunch of change / shortify your urls tools - some quick examples: https://wordpress.org/support/article/pages/#changing-the-url-of-your-pages https://wordpress.org/plugins/url-shortify/ @bernhard URL hooks are nice. Thanks for that pointer. @wbmnfktr Thanks for the VirtualParents module link. I'm trying not to use plug-ins and would prefer to have this flexibility built-in (or use hooks). Thanks for constructive inputs and perspective. I'll rest my case.
  16. BACKGROUND SEO matters and so hiding pages behind a "section" is not necessarily good - example: Current practice is to show the pages "Foo, Bar, Baz" in a section. https://www.example.com/resources/foo https://www.example.com/resources/bar https://www.example.com/resources/baz For SEO reasons, it's better to show the page at root level like so: https://www.example.com/foo https://www.example.com/bar https://www.example.com/baz PROBLEM: LACK OF ORGANIZATION WHEN ALL PAGES ARE PUBLISHED AT ROOT LEVEL This design is fully possible today. However, the root folder becomes disorganized when all pages are published in the root - and the pages tree structure is not of much use when all pages are published in the root. SOLUTION: VIRTUAL PAGES TO THE RESCUE As a publisher, when publishing many pages that have a root level url, I want to organize my pages below a Virtual Page (that doesn't have a url), so that pages are organized in a Pages Tree Structure (using "Virtual Pages"). What is a "Virtual Page"? Virtual Page can never have a name (Admin -> Page -> Settings -> Name). The Name field is simply blank The Name field is never used in the url for child pages. Virtual Page is a container used to organize other pages. Virtual Page is never shown in the front-end. Virtual Page is shown in the Editing interface only. Virtual Page might have a Template - but the template can only be used in the Admin interface. Virtual Page might have fields (Title, Summary, Text etc.) - but the contents cannot be shown online.
  17. Request to have a selector operator that allows me to filter out results that do not begin with a specified comparison value. For instance like so: `^!=` `$!=` (nice to have-addition) ... think of it as an extension of the `!=` operator. Consider these use cases: In the Admin Page Editor I want to show the field "Summary" only when the page path doesn't start with "/foo/" (preferably not using LIKE to do the comparison). Selectors don't allow checking the root parent for a path (as I recall, that used to be possible, I might be wrong though). Filtering out the field might be done with these Selector operators: path^!=/foo/ path^!=/foo/|/bar/|/baz/ Result: Page path: /foo/ and /foo/one/two/ "Summary" field is not shown. Page path: /bar/ and /bar/one/ "Summary" field is shown. See also the Selectors documentation https://processwire.com/docs/selectors/ https://cheatsheet.processwire.com/selectors/ `^=` - Starts with phrase/text Word or phrase appears at start of compared value. `$=` - Ends with phrase/text Word or phrase appears at end of compared value. `^!=` - Starts doesn't with phrase/text (if/when this request is implemented) Word or phrase doesn't appears at start of compared value. `$!=` - Ends doesn't with phrase/text (if/when this request is implemented) Word or phrase doesn't appears at end of compared value.
  18. @bernhard - Where does d() come from? In my ProcessWire 3.0.165 (production) I get: $str = "| Entry | | Foo |"; $md = $modules->get('TextformatterMarkdownExtra'); $md->format($str); d($str); // Fatal Error: Uncaught Error: Call to undefined function d() // Same for: d('foo');
  19. @bernhard - Please elaborate. In ProcessWire 3.0.165 I get this intermediate "Add New" page when creating a page. If only one template can be used, the page is still shown - just without the Template field. <- The purpose is to get rid of this "Add New" page.
  20. Suggested roadmap candidates to improve core: One-step Page Creation: Skip "Add New" and go directly to the resulting page. Better un-global Title fields. Page urls with auto-incrementing IDs (and without Page Name parts). Easier Permissions for Users, Roles, Templates & Pages
  21. I love nice urls - but I also recognize that they are not always needed nor desired due to the additional steps in page creation. Suggested solution: Page ID Page ID is a per-template auto-incrementing number. No. series might be added on a per-template basis (to be configured by webmaster). Page url Replace the full page url with an ID (as an optional configuration). Page url might then change to something like: www.example.com/page/1234 Editing (Page Tree is much less important in this scenario.) Like Drupal's Node IDs (nid). Why this change? Name may reveal confidential info. Name may not matter on certain templates. Page creation is no longer a two-step process; much like adding a row in MySQL. Benefit: This change will make it easier to use ProcessWire for other purposes than websites ("Oh - so ProcessWire is also a finance system!").
  22. Skip the "Add New" dialog page on Page Tree and elsewhere and go directly to the resulting page that shows all page fields right away. Page creation is now improving from being a two-step to becoming a one-step process. Scenarios: When only one Template can be selected: Skip the intermediate "Add New" dialog page by adding a GUID or other temporary page name that is later renamed. Show the final editing page so user can start editing all fields right away On Save: Page name is renamed with title When multiple Templates can be selected: Ask user to select Template on clicking New (before leaving the Tree Page). Then use the "one Template" flow above. (I am aware why the Page Name is needed.)
  23. When webmaster un-globals the Title field (for instance to have a person template with first and last name), there are some unintended consequences. For a site that uses Title on 90% of templates, un-global isn't really useful because it makes adding a new page harder for novice editors: Title field disappears from "Add New" dialog. When I "Add New" page using a template that DOES use the Title field, then the Title field is no longer shown in the Add New dialog window (in this window, an editor will enter Title and Name - and the page is then created and shown to the user in edit mode). No other "pseudo-title" fields can be added to the "Add New" dialog (and it's not possible to skip the two-step page creation process). (There is no simple way to pre-populate the Title field on templates.) Consider these flows: When Title field is global: Steps: From Page Tree, press New to create a new page, "Add New" page is shown with Title and Name fields, (User may need to select Template) Enter Title (Name is automatically set), The new page is shown - start editing fields Observation: Title and Name are shown on same page (good!). Page is created with little mental effort. When Title field is un-global and Page Template has a Title field: Steps: From Page Tree, press New to create a new page, "Add New" page is shown with Name field (but Title is no longer shown when template DOES have the Title field), (User may need to select Template) Enter Name, The new page is shown - start editing fields ("where am I?"). Enter Title (user no longer sees Title and Name at the same time) Observation: Redundant entries (Name and Title are often identical). Name and Title are separated across pages. Better: Show Title and Name on "Add New" page, use Title to set Name (as when Title field is global). When Title field is un-global and Page Template doesn't have a Title field: Setup: Webmaster goes to Template -> Advanced to set "List of fields to display in the admin Page List" (example: "{foo} - {bar}"). Thanks to Robins S for pointing this out. Webmaster cannot specify "Title" fields to be filled in on the "Add New" page. Steps: From Page Tree, press New to create a new page, "Add New" page is shown with Name field, (User may need to select Template) Enter Name, The new page is shown - start editing fields ("where am I?"). Better: Setup allows webmaster to specify "Title" fields to be filled in on the "Add New" page. Even better: Skip the "Add New" dialog page and go directly to the resulting Title page (when only one Template can be selected). Maybe by adding a GUID or other temporary page name that is later renamed? Also I don't think it's possible to pre-populate the Title field in the Administration? (for details, see Pavle's comment). See also: Creating a page without a title? (from 2012 - so I think it's OK to begin a new thread).
  • Create New...