Jump to content

Robin S

  • Content Count

  • Joined

  • Last visited

  • Days Won


Everything posted by Robin S

  1. If I use Tracy to do a test dump in FieldtypePage::wakeupValue (which is where the stored IDs are loaded into a PageArray) then it seems that this method executes regardless of the visibility of the field in Page Edit. And it's not Page Edit that's the main problem anyway. If you have a field then presumably you want to work with that field, but whenever you do... $page->my_pr_field ...then all the pages are loaded to memory. So for instance if you want to add a page via the API... $page->my_pr_field->add($p) ...then you are automatically loading all the pages to memory. @bernhard's suggestion and @teppo's module are good workarounds but I think it's important to get a core solution to this. PW has an "everything is a page" philosophy, so pages can be any unit of data, not necessarily a viewable page of content. And Page Reference fields are the fundamental way to make connections between pages in PW. So when you have thousands of pages that need to have connections to thousands of other pages then you have to start looking beyond the core fieldtypes which is a limitation for PW. Sometimes you can do what @wbmnfktr suggested and reverse the connection, putting the PR field in the other template to reduce the number of pages stored per field. But this isn't always possible. In terms of concrete examples, imagine you were using PW to build some kind of Spotify-like database that tracks users' listening habits. There could be thousands of users who listen to thousands of songs, so either way you cut it you want to store thousands of pages in a PR field.
  2. I can't reproduce that here. If you insert an image without the caption checkbox checked then the plugin inserts an image with the class applied and doesn't insert a wrapping figure element. <p><img alt="" class="align_right" src="/site/assets/files/1/colin-watts-1141600-unsplash.300x0-is.jpg" width="300" />Lorem ipsum dolor sit amet, adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec faucibus. Nunc iaculis suscipit dui.</p> If you insert an image with the caption checkbox checked then the plugin inserts a figure + img + figcaption with the class applied to the figure element. <figure class="align_right"><img alt="" src="/site/assets/files/1/colin-watts-1141600-unsplash.300x0-is.jpg" width="300" /> <figcaption>Your caption text here</figcaption> </figure> <p>Lorem ipsum dolor sit amet, adipiscing elit. Nullam dignissim convallis est. Quisque aliquam. Donec faucibus. Nunc iaculis suscipit dui.</p> Something to be aware of is that if you change the alignment classes for Page Edit Image from their defaults you need to allow those classes in the Extra Allowed Content setting for the CKEditor field. img figure(is-pulled-left,is-pulled-right) It would be better if the class names configured in Page Edit Image were automatically allowed - there's an open issue about this: https://github.com/processwire/processwire-issues/issues/800
  3. @AndZyk, a Page Reference field doesn't scale well because all pages are loaded into memory and there is no ability to limit the loaded pages or paginate the inputfield in admin. Back in 2016 Ryan said it was likely that pagination would be added to several core fieldtypes but it hasn't happened yet: https://processwire.com/blog/posts/fieldtype-pagination/ The Page Reference fieldtype/inputfield is the one that would benefit the most from this. I have an open request for this that you could add your voice to: https://github.com/processwire/processwire-requests/issues/13
  4. See the module config for Page Edit Image (which is the Process module used by the PWImage plugin):
  5. Yes. If you want the hook to apply to a specific Lister Pro instance instead of a bookmark you could do this: $wire->addHookBefore('ProcessPageLister::execute', function(HookEvent $event) { /* @var ProcessPageLister $lister */ $lister = $event->object; // If executing a specific Lister Pro instance if($event->wire('page')->name === 'your-lister-page-name') { // Find the templates that contain the meta_title field $tpls = new TemplatesArray(); foreach($event->wire('templates') as $template) { if($template->flags) continue; // Skip system templates (e.g. repeater templates) if($template->fieldgroup->has('meta_title')) $tpls->add($template); } // Set the defaultSelector for the Lister $lister->defaultSelector = "template=$tpls, meta_title=''"; } });
  6. @cst989, here is one way you could do it. First create a new Lister bookmark with the columns and sorting set the way you want. It doesn't matter what you set in the filters because we are going to override that in a hook. Take note of the bookmark ID in the URL when you view the bookmark in Lister. Now add the following hook to /site/ready.php, updating the bookmark ID to suit: $wire->addHookBefore('ProcessPageLister::execute', function(HookEvent $event) { /* @var ProcessPageLister $lister */ $lister = $event->object; $bookmark = $event->wire('input')->get('bookmark'); // If executing your specific bookmark if($bookmark === '_1574293851') { // Find the templates that contain the meta_title field $tpls = new TemplatesArray(); foreach($event->wire('templates') as $template) { if($template->flags) continue; // Skip system templates (e.g. repeater templates) if($template->fieldgroup->has('meta_title')) $tpls->add($template); } // Set the defaultSelector for the Lister $lister->defaultSelector = "template=$tpls, meta_title=''"; } });
  7. Also, take a look at the WireHttp docs, particularly WireHttp::getJSON() - this method can make your code more streamlined. 🙂
  8. JSON is just a string so you can save it to $session as a string: Or you could decode the JSON to an associative array and then save that array to session. The core wireDecodeJson() function is a handy shortcut to force the JSON to decode as associative arrays rather than objects.
  9. Have you looked at the $session documentation? If so is there a specific problem you're having?
  10. It's unlikely the browsers themselves are making the difference here. Probably you are logged into the PW admin in Chrome but not in the other browsers. So your problem is due to some access restriction on page/template "b".
  11. It works for me, so double-check your code. Another way you can find related templates is to apply a tag to them in the admin (Advanced tab). Then you can find the templates that have that tag and find pages using those templates. // Find templates with tag "foo" $tpls = $templates->find("tags=foo"); // Find pages using those templates $items = $pages->find("template=$tpls");
  12. Try: // Set filename manually $filename = $config->paths->templates . 'lvl04-post.php'; // Or get filename from one of the templates that uses it // $filename = $templates->get('lvl04-post')->filename; // Find templates that use this template file $tpls = $templates->find("filename=$filename"); // Find pages using those templates $posts = $pages->find("template=$tpls, limit=5");
  13. Looks promising. And when you've sussed it out you could add a little write-up in the tutorials section for the next person needing tips for a calendar. 🙂
  14. "Why is a simple calendar so hard to find?" Why the assumption that someone else will have created a plug-and-play solution for you? Web software exists if a web developer codes it. You are a web developer. Do you see where I'm going with this... 😉
  15. Yes, but it's up to you to connect only fields that have the appropriate allowed pages for the templates they are added to. From the module readme:
  16. @MarkE, this module connects two Page Reference fields across the site - the module config doesn't allow for limiting the connection by template. Nor would I want to add that because it would make the config more complicated than it needs to be for the majority of users. I suppose it might be possible to add a hookable method to the module that could let you opt out of updating connected fields in certain circumstances, but I doubt that would be preferable to simply creating a different Page Reference field that isn't connected to other fields by this module.
  17. @vwatson, if you want a simple but not 100% tamper-proof solution then the AdminOnSteroids module makes it fairly easy. 1. Install AdminOnSteroids. 2. In the "Asset Paths" section, add the URL to a CSS file that will contain custom styles for the admin: 3. In this CSS file, for a role named "editor"... /* Hide restore and delete links in ProcessDatabaseBackups */ .role-editor.ProcessDatabaseBackups a[href*='/db-backups/restore/'], .role-editor.ProcessDatabaseBackups a[href*='/db-backups/delete/'] { display:none; }
  18. The simple solution is to create a new text field "full_name" and add it to your template. Set the visibility to "Hidden (not shown in the editor)". In /site/ready.php: $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); if($page->template == 'your_template') { $page->full_name = $page->first_name . ' ' . $page->last_name; } }); You'll need to save all the pages once to populate the full_name field - if there are a lot then use the API to loop over the pages and save them. Now you can search the full_name field.
  19. @tpr, I have added a fix for this in v0.0.2 of the Link Hover plugin if you want to update the version included in AOS: https://github.com/Toutouwai/linkhover Not as far as I can see. Without the Link Hover plugin installed there is no equivalent functionality to show the link URL on hover. Thanks for the bug report though.
  20. The Inputfields JS API is really cool, thanks @ryan! What do you think about adding a feature so that some (all??) of these JS functions could be triggered via URL query string parameters? As per my request here it would be neat to be able to create links (e.g. modal) to a form that automatically show/hide/highlight/etc particular fields.
  21. This is possible if you use a hook to build the dialog form. See the example in the module readme. You would define the options like this: $wire->addHookAfter('HannaCodeDialog::buildForm', function(HookEvent $event) { // The Hanna tag that is being opened in the dialog $tag_name = $event->arguments(0); // Other arguments if you need them /* @var Page $edited_page */ $edited_page = $event->arguments(1); // The page open in Page Edit $current_attributes = $event->arguments(2); // The current attribute values $default_attributes = $event->arguments(3); // The default attribute values // The form rendered in the dialog /* @var InputfieldForm $form */ $form = $event->return; if($tag_name === 'your_hanna_tag_name') { $modules = $event->wire('modules'); /* @var InputfieldSelect $f */ $f = $modules->InputfieldSelect; $f->name = 'Post_sorting_order'; $f->id = 'Post_sorting_order'; $f->addOptions([ 'recipe_comments.count' => 'Recipe comments', '-recipe_comments.count' => 'Recipe comments (descending)', // etc ]); $form->add($f); } }); Or if you don't want to use a hook you just need to do the work of converting the labels into the values you want to sort by in the Hanna tag code. For example: switch($Post_sorting_order) { case 'Recipe comments': $sort = 'recipe_comments.count'; break; case 'Recipe comments (descending)': $sort = '-recipe_comments.count'; break; // etc }
  22. Welcome to the PW forums @eddietoast! Check that you have extended page name support enabled: https://processwire.com/blog/posts/page-name-charset-utf8/ That may be all you need to get Chinese page names working, but I've noticed that people have had a few questions/problems with Chinese characters, particularly regarding the $config->pageNameWhitelist setting. In this issue Ryan seems to recommend setting $config->pageNameWhitelist to empty, but then in this issue an empty value for that setting seemed to cause a different problem. And the topic linked to below has some related discussion: If you find you can't get Chinese page names working then please open an issue at Github because it sounds like this is something that might need some attention from Ryan. Or if you do get it working please make a post in the tutorials section explaining what settings you used. An alternative might be to use my recently released Sanitizer EasySlugger to create latin page names from Chinese characters. To do that I expect you would need to edit the ImportPagesCSV module to call $sanitizer->utf8Slugger() when the pages are created. Or you might like to use the code I posted here (it's an addon action for the Admin Actions module) as a starting point for your own custom CSV import action. P.S. Please use the code button in the forum post editor toolbar when you are including code in a post.
  23. Sanitizer EasySlugger Allows the use of the EasySlugger library as Sanitizer methods. Installation Install the Sanitizer EasySlugger module. Usage The module adds four new sanitizer methods. slugger($string, $options) Similar to $sanitizer->pageName() - I'm not sure if there are any advantages over that method. Included because it is one of the methods offered by EasySlugger. $slug = $sanitizer->slugger('Lorem Ipsum'); // Result: lorem-ipsum utf8Slugger($string, $options) Creates slugs from non-latin alphabets. $slug = $sanitizer->utf8Slugger('这个用汉语怎么说'); // Result: zhe-ge-yong-han-yu-zen-me-shuo seoSlugger($string, $options) Augments the string before turning it into a slug. The conversions are related to numbers, currencies, email addresses and other common symbols. $slug = $sanitizer->seoSlugger('The price is $5.99'); // Result: the-price-is-5-dollars-99-cents See the EasySlugger readme for some more examples. seoUtf8Slugger($string, $options) A combination of utf8Slugger() and seoSlugger(). $slug = $sanitizer->seoUtf8Slugger('价钱是 $5.99'); // Result: jia-qian-shi-5-dollars-99-cents $options argument Each of the methods can take an $options array as a second argument. separator (string): the character that separates words in the slug. Default: - unique (bool): Determines whether a random suffix is added at the end of the slug. Default: false $slug = $sanitizer->utf8Slugger('这个用汉语怎么说', ['separator' => '_', 'unique' => true]); // Result: zhe_ge_yong_han_yu_zen_me_shuo_3ad66c4 https://github.com/Toutouwai/SanitizerEasySlugger https://modules.processwire.com/modules/sanitizer-easy-slugger/
  24. v0.1.6 released. Prompted by a feature request, the module now has a config option to include files from Repeater fields that are in the page being edited. Nested Repeater fields (files inside a Repeater inside another Repeater) are not supported. As with all my modules going forward, PW3 is now a requirement.
  25. Welcome @Elko! From comments that I've seen here in the forums I know that there are people using PW successfully with millions of pages. So that might mean that there is nothing to worry about if you decide to use a page for every time slot for every user. But personally speaking, when I've had situations like this it has felt a bit wrong to use large numbers of pages to store such simple data and I have used Profields Table for this sort of thing instead. This isn't based on any tests I've done - just on gut instinct. I have a feeling that if you need to regularly and quickly load and process large numbers of records then pages can be a bit less than optimal. @bernhard's RockFinder module might be useful to avoid loading full Page objects: Or if you're comfortable working with databases then there's no reason why you couldn't use an external database (or just an extra table in the PW database) together with the $database API. This might give the fastest performance.
  • Create New...