Jump to content

Robin S

Members
  • Posts

    5,008
  • Joined

  • Days Won

    333

Everything posted by Robin S

  1. @Violet, I just made a fix to the code snippet... // Return if body field absent or unchanged if(!$page->body || !$page->isChanged('body')) return;
  2. I might be wrong, but my understanding is that the ACF/Purifier settings for a CKEditor field only affect content that goes through the CKEditor inputfield and is then saved to the database. A textformatter on the other hand never saves its changes to the database and it isn't involved with the inputfield - it just makes changes on-the-fly as the content is output to the front-end. Another thought: if you have multiple textformatters applied, check to see if the order they are applied makes a difference.
  3. Child pages can be good when: You think it will be helpful for the relationship to be shown in the URL to the pages: /manufacturers/dodge/challenger/ Although it is also possible to 'fake' a page URL using URL segments. The child will exclusively belong to that parent (it doesn't belong to multiple categories). If either of these is not the case then you are better off with Page Reference fields. So in your example, you have fish in an aquarium. If by "fish" you mean "species of fish" then you wouldn't want to have these as child pages of an aquarium, because multiple aquariums might have the same species of fish and you don't want to duplicate the species pages.
  4. There shouldn't be any iframe tags involved - you simply insert the URL to the video (not an embed snippet or anything like that) in a new paragraph in your CKEditor field.
  5. This module is a textformatter, so it doesn't write anything to the CKEditor field. As long as you can insert a link URL into your field as text without interference from HTML Purifier then there shouldn't be any problem.
  6. @Macrura if $widget is a page, then try this... $widget->getFormatted('dw_color')
  7. Another option which avoids the need to parse and modify the links on every frontend page load (as a textformatter does), you could just do it once when a page is saved. The example below (add to /site/ready.php) uses Simple HTML DOM as the parser: // Change 'body' to whatever your CKEditor field is named $wire->addHookAfter('Pages::saveReady', function(HookEvent $event) { $page = $event->arguments(0); // Return if body field absent or unchanged if(!$page->body || !$page->isChanged('body')) return; // Load Simple HTML DOM from site root require_once $this->config->paths->root . 'simple_html_dom.php'; // Create DOM from body field $html = str_get_html($page->body); // Get all the links $links = $html->find('a'); foreach($links as $link) { $href = $link->href; // For any link that is not relative and does not start with the site httpRoot... if(strpos($href, '/') !== 0 && strpos($href, $this->urls->httpRoot) !== 0) { // Set rel and target attributes $link->rel = 'nofollow'; $link->target = '_blank'; } } // Set the results to the body field $page->body = $html->save(); });
  8. Hi @adrian, Might be a silly question, but just wondering why the dump output doesn't appear in the same order that the dumps occur in. So if I do... ...how come the output order is reversed?
  9. The GitHub readmes that are used in the modules directory have become a bit messed up recently. Example: https://modules.processwire.com/modules/tracy-debugger/ Not sure who manages this section of the website. @ryan?
  10. This is a topic that comes up quite commonly on the forums - search for "blocks" and you'll probably find a bunch of topics. Short answer... No cost: PageTable Some cost, but very much worth the investment: Repeater Matrix (in the ProFields bundle)
  11. Thanks for the update! A few little things... 1. $debug variable has been left behind in the module and may be undefined. 2. The default selector should be an empty string. 3. Wouldn't it be more efficient to set is_first and is_last according to array key like you did in MarkupSimpleNavigation? In terms of understanding the module, I find the way that $defaultOptions, $defaultStates, $enableStates, $levels and $collapsed are set to be a bit counter-intuitive. To my way of thinking, you only want to set properties to the module itself for settings that are intended to be global (applying to all menus in your site). Because when these options are set as properties of the module they persist for all subsequent menus unless you explicitly change them. But things like $levels and $collapsed are things that you want to set individually for a single menu - you don't want these settings affecting other menus. So I'd rather be passing these settings in as arguments to the render() method - that way I don't have to keep track and reset them for menus that are rendered subsequently. Similar for setting menu options for all levels of a menu - that's why I thought something like a specific array key 'all' could be used when passing in the menu options. So I'm just setting default options for that one menu and not affecting other menus. To be clear, I still like the idea of setting some global $defaultOptions, $defaultStates, etc - but for things like setting a levels limit or setting options for all levels of a specific menu it's less error-prone if these don't affect other menus.
  12. Posting some more stuff while it is fresh in my mind... I made a new commit here. Changes... 1. Fix for selector not falling back to what is defined in the default options. 2. Allows menu options to be defined for all levels by using "all" as the options array key. Example: $menuOptions = array( // use these options for all levels in this menu "all" => array( "selector" => "template=basic-page|domain_root", "callback" => function($item, $level){ $class = $item === wire("page") ? " current" : ""; $class .= wire("page")->parents->has($item) ? " parent" : ""; $class .= $item->numChildren("template=basic-page") ? " has_children" : ""; return array( "item" => "<a href='$item->url'>$item->title $item->template</a>", "listOpen" => "<li class='level$level$class'>", "listClose" => "</li>", "wrapperOpen" => "<ul class='mainnav'>", "wrapperClose" => "</ul>", ); }, ) ); Setting an explicit array key also made me think of something else that it would be good to mention in the module readme. If you want to set options only for level 3 (for example) it isn't necessary to include anything for the other levels. Instead of... $menuOptions = array( array(), // level 1 array(), // level 2 array( // level 3 "selector" => "template=basic-page", ), ); ...you can do... $menuOptions = array( // options for level 3 (array keys are zero-indexed) 2 => array( "selector" => "template=basic-page", ), ); And an issue to report: there is a problem when using Aligator to render more than one menu - the $level variable in the render() method can be incorrect for any menus after the first menu. This is because $level is declared as a static variable, so after the first menu is rendered $level can retain its value when it should be reset to zero for each menu that is rendered. Not sure of the best way to fix that (the whole static variable / recursive function thing makes my head spin). Edit: In this commit I changed from the static variable to passing $level as an argument to render() and it seems like an okay solution.
  13. Cool. But I do think it makes sense for utilities like CodeMirror or Ace to exist as separate inputfield modules so that they can be used elsewhere in Page Edit, other modules, etc, rather that duplicated within every module that uses them. Things like this are not really dependencies (a plain textarea works fine without them) but more a progressive enhancement.
  14. Nice one. How about using InputfieldAceExtended for the configuration textarea if it is installed? if($this->modules->isInstalled('InputfieldAceExtended')) { $f = $this->modules->get('InputfieldAceExtended'); $f->mode = 'ini'; $f->modes = array('ini'); $f->theme = 'twilight'; } else { $f = $this->modules->get('InputfieldTextarea'); } $f->attr('name', 'CKEaddons_toolbar'); //...
  15. One more thing: I think that here and here Aligator should fall back to the selector defined in the defaults rather than an empty string. $selector = isset($options[$level-1]['selector']) ? $options[$level-1]['selector'] : $this->defaultOptions['selector'];
  16. Me again. Is there a way I can set options for all levels of a particular menu without changing the default options? Suppose I have several menus in my site and I have defined some default options for Aligator that suit most of these menus. Now on one of these menus I want to exclude a particular template from all levels in the menu. I don't know how many levels will be in this menu (users may add pages creating additional levels of nesting). So I can use the "selector" setting for this, but do I use this in the default options or the options for that specific menu? It seems like there are catches either way. Default options: works for all levels (good), but affects all the menus in my site (bad). Menu options: limited to this specific menu (good), but I have to repeat the setting over and over some arbitrary number of times to account for all the levels that might exist in the menu (bad). Seems like there should be some way to set default options (all levels) but just for this one menu. Or am I missing something?
  17. I opened a GitHub issue myself: https://github.com/processwire/processwire-issues/issues/383
  18. Client: "What's a filter? Should I add one? Why are there all these dropdowns? What's a num_children? I've forgotten my modified_users_id - can you email it to me? What's a bookmark? I have a bookmark for Google - is it like that? I don't understand what I do on the columns tab. My brain hurts. Why did you make this so confusing? etc, etc, etc" But seriously, it's just a permission so you have the option to show Lister to a role or not show it to a role. It's just to give flexibility.
  19. Not sure why you are using an Options field for this. I think you want an integer field named "number_of_saves" or whatever. Then you increment the number with each save originating from the front-end.
  20. Hi @abdus, Can you say more about this? Does this... $foo = $pages->find("template=foo"); foreach($foo as $foo_item) { //... ...use more memory than... foreach($pages->find("template=foo") as $foo_item) { //... ...? I thought these would be same in terms of memory usage, or is memory able to be "released" later somehow if you are not assigning to a variable?
  21. Thanks for the suggestions for including "Home" - I had been playing around with adding a "show_root" option to Aligator but your suggestions are simpler and better. I made a few other changes in a fork of Aligator that I'll pass on for consideration. 1. I think there is a typo here - should be... if($return["wrapperClose"]) { 2. I changed the early returns so that an empty string is returned, to be consistent with the @return tag in the function DocBlock. 3. I added a new argument that is supplied to the callback function - a $props array of some menu-related properties of the current $item. The reason being that these properties are commonly needed to work out the menu markup, and they are already determined within the Aligator render() function - so it makes sense to pass 'is_parent', 'is_current' and 'num_children' as an argument rather than have to determine them again separately in the callback function. I also included 'is_first' and 'is_last' in the $props array because it is much more efficient to determine this within render() from the $key in the foreach (just like is done in MarkupSimpleNavigation) than in the callback as per my post above. But now that I think about it I don't know that these properties are that useful after all - probably anything you would use them for could be just as easily achieved in CSS or JS with :first-child and :last-child. 4. Lastly, because of the $props argument I override 'is_parent' and 'num_children' in the case of the Home page being rendered. That's because despite the way PW treats Home as the root parent of all pages (there are probably good reasons for this), I think most website users think of the Home page as a sibling of the top-level pages rather than a parent of them. The commit with my changes is here if you are interested.
  22. Wow, super update this week! The SCSS compilation feature in ProCache sounds great. Currently I have a roll-my-own solution using scssphp - does the new ProCache feature use scssphp or something different? The front-end users module is awesome news - it's one of those few missing pieces that PW has been really needing. Beginners especially will benefit from this, and because of the security considerations that come with a login system it's great to have a solution from PW's creator. I was expecting that such a module would be a "Pro" release, so big thanks for making this a free module! Can't wait to try it.
  23. That error from the Repeater module looks like the same thing I raised a GitHub issue for recently, so there's a good chance it relates to PW's caching of module data rather than Recurme specifically. Ryan has pushed a fix for the issue to the dev branch.
  24. There's nothing invalid about the original page name in your gif. Adding the $beautify argument to $sanitizer->pageName() will give a result that is closer to the JS replacement that happens in the admin interface. But I take your point that it would be useful to have a sanitizer option that is an exact match for the JS replacement.
×
×
  • Create New...