-
Posts
5,008 -
Joined
-
Days Won
333
Everything posted by Robin S
-
@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; }
-
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.
-
@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.
-
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.
-
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 }
-
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.
-
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/
-
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.
-
Store data in Processwire as pages, or in a separate database?
Robin S replied to Elko's topic in General Support
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. -
User role permissions (parent-child relation)
Robin S replied to alanxptm's topic in API & Templates
Welcome @alanxptm! There are separate permissions that can be set on the Access tab of each template's settings: View Pages (normally all roles are given this permission), Edit Pages, Create Pages, Add Children. So besides the View Pages permission you would set the permissions as follows for the author role... category template: Add Children post template: Edit Pages, Create Pages -
Not sure why you would be seeing that. I tested here and couldn't reproduce - that kind of selector works fine for me regardless of limit.
-
A couple of hooks that I have found useful in some situations... In the admin menus the icon associated with each page is normally determined by the "icon" item in the Process module config (e.g. as set in the getModuleInfo() method). But sometimes you might want to change that icon. For example, the Lister Pro module uses the "search-plus" icon, but this is not so good when you have multiple Lister Pro instances because it makes each instance less distinct. With the hook below I can use a custom icon for the extra Lister Pro instances I have added: // Add custom icons to Lister Pro menu items $wire->addHookAfter('Page::getUnknown(page_icon)', function(HookEvent $event) { $page = $event->object; if($page->process == 'ProcessPageListerPro') { if($page->title === 'Flora species') { $event->return = 'leaf'; } elseif($page->title === 'Flora images') { $event->return = 'picture-o'; } } }); If you change an icon in the admin menus like this you can do a Modules > Refresh to clear the menu cache and see the updated icon. And for Page List you probably know that you can assign an icon to all pages that use a template in the template's "Advanced" tab. But with the hook below you can assign icons to pages more dynamically based on any properties of the page. So, for example, you could assign a warning icon to a page to alert site editors if some important field was left empty. // Add warning icon to news items without a date $wire->addHookAfter('Page::getIcon', function(HookEvent $event) { $page = $event->object; if($page->template == 'news_item' && !$page->date_1) { $event->return = 'exclamation-triangle'; } });
- 5 replies
-
- 12
-
-
I think this is the crux of it - it's mostly a communication issue. It's not surprising that people come to PW with an experience of seeing how some other open-source GitHub-hosted projects are managed and expect that it's the same for PW. Many projects encourage the user base to submit pull requests. However, PW is not one of those projects and this probably needs to be communicated more clearly somewhere. Open-source is not one thing but many things depending on the project and those who manage it. My impression is that PW is open-source in the sense of "a very smart person made this software and you can use it for free and also modify it to suit your needs". But it's not open-source in the sense of "hey everybody, let's collaborate on writing code for this software". There will be pros and cons to the different approaches to managing an open-source project, but all things considered I think most would agree that the formula Ryan is following has proven very successful to date.
- 14 replies
-
- 11
-
-
@Ben Sayers, I created a pull request with a fix for this issue: https://github.com/Rayden/FieldtypeStarRating/pull/1 In the meantime you could update InputfieldStarRating.js with the code from here and do a hard refresh in your browser to clear the cache.
-
Thanks, all working great. ?
-
solved - how to save $pages array for later use
Robin S replied to Rob(AU)'s topic in General Support
@Rob(AU), glad to hear you've got something working. Something to think about though: seeing as each portfolio page may have multiple tags, what happens if a user opens a portfolio page in a new tab via "tag=foo" and then the same portfolio page in a different tab via "tag=bar"? You only have a single session variable for the tagged pages so these will overwrite each other, and the portfolio page doesn't "know" which tag it is being viewed under. I think it would be better not to use session but to pass the relevant tag as a parameter in the URL. So you would write link URLs to portfolio pages under tag "foo" like "/path/to/page/?tag=foo" and under tag "bar" they would be "/path/to/page/?tag=bar". Then in your portfolio template you would have some code like this: // Initialise some null pages as fallback $prev_page = new NullPage(); $next_page = new NullPage(); // Get the tag from $input if any $tag = $input->get->text('tag'); // If there is a tag if($tag) { // Get the IDs of portfolio pages with this tag - assumes a tag field named "tag" // It's more efficient to just get the IDs rather than the full Page objects, especially if there are a lot of portfolio pages $tagged_ids = $pages->findIDs("template=portfolio, tag=$tag"); // Get the position (key) of this current page in the array $page_position = array_search($page->id, $tagged_ids); // Get the previous page if any if(isset($tagged_ids[$page_position - 1])) { $prev_page = $pages($tagged_ids[$page_position - 1]); } // Get the next page if any if(isset($tagged_ids[$page_position + 1])) { $next_page = $pages($tagged_ids[$page_position + 1]); } } And where you want to output the prev/next links: <?php if($prev_page->id): ?> <p><a href="<?= $prev_page->url ?>?tag=<?= $tag ?>">Prev page</a></p> <?php endif; ?> <?php if($next_page->id): ?> <p><a href="<?= $next_page->url ?>?tag=<?= $tag ?>">Next page</a></p> <?php endif; ?> This way each portfolio page knows the tag it is being viewed under, and it means you can do things like share a link to a portfolio page such that the tag is specified. -
There's no drawback that I know of but this module is pretty new so it's possible that something will reveal itself over time.
-
That sounds like an issue that should perhaps be fixed in the core - when redirecting due to lack of access I don't think this should be permanent redirect because as you say the user may just need to log in and then they should have access. Maybe you can create a GitHub issue for this to get Ryan's take?
-
The actual action I noticed this on works with an external database so it's not easily shareable but attached is a demo action that shows the issue. Thanks for taking a look at this. DemoAction.action.php
-
Hi @adrian, Within an admin action we have the option to return true or false depending on if the action succeeded or failed (and I assume success or failure is up to the action author depending on what the overall objective of the action is). If an action returns true then a database restore link is shown. But it seems that if the action returns false then the link to restore the database is not shown. I'm not sure if no backup is made or it's just the restore link that's missing - maybe the former because when I manually visited the /restore/ URL segment and clicked the Restore button then the restore didn't work. Is it possible to get a backup and a link to restore it when an action returns false? Also, maybe the background colour of the failure message could be a pale red because it's hard to see links against the dark red (there's actually a link to the logs in the failure message above). BTW, the module readme doesn't make it entirely clear that an action should return false on the fail state, as only the failureMessage is mentioned:
-
I think you might be working with the wrong init.php - you'll see in my earlier post that the hook needs to go in /site/init.php. Along with /site/ready.php this is one of the places that hook code is commonly added to. You can create either/both of these files if they don't exist. More info in this blog post: https://processwire.com/blog/posts/processwire-2.6.7-core-updates-and-more/#new-core-files-for-site-hooks Turn off ProCache while you are investigating the issue to make sure it isn't contributing to the problem.
-
Multi-tree select with "real" multiselects on the fly?
Robin S replied to gerritvanaaken's topic in General Support
@gerritvanaaken, I created a module in response to your topic: -
A module created in response to the topic here: Page List Select Multiple Quickly Modifies PageListSelectMultiple to allow you to select multiple pages without the tree closing every time you select a page. The screencast says it all: https://github.com/Toutouwai/PageListSelectMultipleQuickly https://modules.processwire.com/modules/page-list-select-multiple-quickly/
-
@Ben Sayers, you can use bd() to dump the $url variable in the hook. $wire->addHookBefore('ProcessPageView::pageNotFound', function(HookEvent $event) { $url = $event->arguments(1); // Dump $url to the Tracy debug bar bd($url, 'url'); // The old URLs you want to redirect from (relative to site root) $redirects = [ '/blog/foo/', '/blog/bar/', ]; if(in_array($url, $redirects)) { // Get the blog landing page however suits $blog_page = $this->wire('pages')->get('template=blog'); // Redirect to blog landing page $this->wire('session')->redirect($blog_page->url); } }); When you visit a URL that does not match any page then you'll see the $url variable dumped via the Tracy debug bar. Tracy docs are here: https://adrianbj.github.io/TracyDebugger/#/debug-methods?id=bardump Enter some random letters in the URL to confirm that the hook is firing and you can see the dump. Then try one of your old blog post URLs. If you don't see any dump then the hook is not firing, in this case because ProcessPageView::pageNotFound() is not executing. In which case you have something interfering before PW can attempt to render the page requested in the URL - so probably due to an .htaccess rewrite or something caused by Jumplinks (or another module or hook if you have anything else that affects URLs).
-
Super-cool, thanks!