Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by ethanbeyer

  1. I'm looking for a way to dynamically change the SMTP server settings for this module depending on my environment. If I'm on my local box, I want to use Mailtrap or Debugmail.io in order to prevent test emails from going to real addresses – but on the live server I want to maintain my Mandrill credentials. I thought it would be as simple as this: $this->addHookAfter("TemplateFile::render", function($event) { $config = wire('config'); $wmsmtp = wire('modules')->get('WireMailSmtp'); if($config->env == "dev") { $wmsmtp->set('smtp_host', "different-smtp-server.com"); $wmsmtp->set('smtp_port', "25"); $wmsmtp->set('smtp_user', "username2"); $wmsmtp->set('smtp_password', "a_different_password"); } }); But that doesn't seem to be working. I'm sure I'm using a bad hook for this, but I can't find a hook for when Module Configs are loaded - only saved - and I am almost positive that ProcessWire can do this. I just don't know how! Anybody done anything like this before?
  2. Looking at this, it's got a lot of what I needed! I added a few other little features, but thank you for this code! It's been very helpful! @adrian I never would've found this on my own - thank you!! I never would've been able to see how Process modules worked without this file, either: https://github.com/ryancramerdesign/ProcessHello/blob/master/ProcessHello.module.php Lastly, here's the repo for the module I made - I'd love any feedback (There are definitely some janky bits)! https://github.com/ethanbeyer/ProcessWire-Blacklisted-Page-Names-Module
  3. I have made some major progress - but I could use some help for that last little push. @adrian, I've looked over your code for the PageRenameOptions module extensively, and apart from learning a lot, I am going to install that module on every single PW site I have. So thank you!! What I decided to do was to write a small module that handles this issue. See below: <?php use Helpers; class ProcessPageBlacklisted extends WireData implements Module, ConfigurableModule { protected $configFields; /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( 'title' => 'Blacklisted Pages', 'version' => 100, 'summary' => 'Creates an array of Blacklisted Pages that prevents the user from making pages that shouldn\'t exist.', 'href' => '', 'singular' => true, 'autoload' => true ); } /** * Init Function - loads scripts via hooks */ public function init() { // Add the Hooks to these two pages to add the JS $this->addHookBefore("ProcessPageEdit::buildForm", $this, "addScripts"); $this->addHookBefore("ProcessPageAdd::buildForm", $this, "addScripts"); } /** * Function to add the relevant Javascript to the Add and Edit Page screens */ protected function addScripts(HookEvent $event) { $conf = $this->getModuleInfo(); $version = (int) $conf['version']; return wire('config')->scripts->add( $this->config->urls->ProcessPageBlacklisted."ProcessPageBlacklisted.js?v={$version}" ); } public function execute() { $name = $this->wire('sanitizer')->pageNameUTF8($this->wire('input')->get('name')); if(!strlen($name)) return ''; $blacklisted_names = explode("\n", $this->data['blacklisted_names']); if(in_array($name, $blacklisted_names)) { $out = "<span class='taken ui-state-error-text'><i class='fa fa-exclamation-triangle'></i> " . $this->_('This name is not allowed!') . "</span>"; } return $out; } public function getModuleConfigInputfields(array $data) { $form = new InputfieldWrapper(); $f = wire('modules')->get('InputfieldTextarea'); $f->name = 'blacklisted_names'; $f->label = __('Blacklisted Page Names'); $f->value = $data['blacklisted_names']; $form->add($f); return $form; } } I'm making pretty heavy use of the ProcessPageAdd module, which has also been very helpful to look through. I copied the JS file from ProcessPageAdd and made a few changes to it, and I believe everything will work as planned once I figure out how to get the script to actually interface with the module itself through the execute() method. I keep reading Docs and different forum postings, but I'm stumped here. I expected that having a class called ProcessPageBlacklisted would be reachable through "admin/page/blacklisted", the output of the page being created by execute(). Apparently, I'm wrong. The javascript looks at what's in the name box, does an ajax call to "admin/page/blacklisted", and returns: ` {"error":false,"message":"Unrecognized path"} ` Can someone tell me what I need to do in order to get the output from the execute() function? Thank youuuuu...
  4. @Robin S yes, exactly. If someone typed in "www" as the name, I'd like to throw an error that says that that name is not allowed, and not save the page. I'm going to tinker with those two hooks.
  5. For some further background on this issue, please see this forum post. I have a template called "subdomain" - and for pages with that template, I need to throw an error if the name is something like "edit" or "admin" or "www" or "processwire", because all of those subdomains are already in use, and I want to prevent URL collision. Is there a method or a hook or something that I'm missing that sets a name as disallowed/blacklisted/native? Thanks in advance!
  6. Thanks, @adrian! I was already using it, but didn't realize it took over the wireMail(); calls!
  7. Late to this long topic, but any news on CC or BCC or attachment?
  8. @Robin S oh you're so right! I updated the code in my post.
  9. Thank you both - @kongondo and @LostKobrakai! I knew there had to be a way to do that, but wasn't sure even how to google it. I'm sure I read right past that part of the docs. Here's what I needed the Or Groups for: "related posts"! I've got two page-types that can be related via Categories, Tags or a Connected Client, and I wanted to be able to show other Posts or Projects that had the same Category, Tag or Client attached. Previous versions of the following function were always finding related posts only when there was an exact match of Categories+Tags. But with your help, I was able to rewrite the function to the following: public function getRelatedPages( $base_page_id, $page_type ) { // set values $pages = wire("pages"); $page = $pages->get($base_page_id); $search = array(); $matches = new WireArray; // Categories if($page->Categories->count > 0) { foreach($page->get("Categories") as $category) { $category_array[] = $category->name; } $category_string = implode("|", $category_array); $search[] = "(Categories={$category_string})"; } // Tags if($page->Tags->count > 0) { foreach($page->get("Tags") as $tag) { $tag_array[] = $tag->name; } $tag_string = implode("|", $tag_array); $search[] = "(Tags={$tag_string})"; } // ConnectedClient if(isset($page->ConnectedClient)) { $search[] = "(ConnectedClient={$page->ConnectedClient})"; } $search_string = implode(", ", $search); $matches = $pages->find($search_string)->sort("random")->filter("id!={$page->id}, template={$page_type}, limit=3"); // Debug // $this->dd($search); // Output the final matches return ($matches->count > 0) ? $matches : NULL; } Thanks again!
  10. Hello, I've been working on building a find query and I think I need to be able to do an OR search on multiple selectors, all of which have a number of possible values. The first way I did this was with three queries: // Categories if($page->Categories->count > 0) { foreach($page->get("Categories") as $category) { $category_array[] = $category->name; } $category_string = implode("|", $category_array); $same_categories = $pages->find("template={$page_type}, Categories={$category_string}")->filter("id!={$page->id}"); } // Tags if($page->Tags->count > 0) { foreach($page->get("Tags") as $tag) { $tag_array[] = $tag->name; } $tag_string = implode("|", $tag_array); $same_tags = $pages->find("template={$page_type}, Tags={$tag_string}")->filter("id!={$page->id}"); } // ConnectedClient if(in_array('ConnectedClient', $page->fields)) { $same_client = $pages->find("template={$page_type}, ConnectedClient={$page->ConnectedClient}")->filter("id!={$page->id}"); } if($same_categories->count > 0) $matches->import($same_categories); if($same_tags->count > 0) $matches->import($same_tags); if($same_client->count > 0) $matches->import($same_client); But for some reason, only the first "$matches" seems to stick. So to me, it would make sense to be able to structure a find query like this: $search = $pages->find(" template=post|project, [Categories=one|two|three]|[Tags=yes|no|maybe]|[ConnectedClient=1065] ")->filter("id!={$page->id}"); Does this make sense? I need to find all pages that match [Tags=yes OR no OR maybe] OR [Categories= one OR two OR three] OR [ConnectedClient=1065]. I realize it might turn into a SQL-needed scenario, but given the flexibility of Processwire, the ability to string together a query like this would be super nice. Is there a way?
  11. @Macrura Thanks for taking my suggestions into account! Loved getting to help you improve it just that little bit. Thanks again for the module to begin with!
  12. I'm not sure how that would make it more reliable, since that's not one of the issues we were having to start with—and this way of handling the JS cuts down on complexity/errors that adding another included script file could introduce.
  13. I've done some more digging. The field with SimpleMDE definitely needs to be refreshed, but it is possible to just "init" that field if we hook into the correct triggered events. I've tested this with Textarea fields using SimpleMDE as their Inputfield: If the field is closed; or if the field is within a Fieldset that is closed; or if the field is on a tab that is not visible on page load... The following code fixes all of those cases: /** * Init for Processwire * These items could be added if fullscreen or sidebyside would work on PW * Note that fullscreen mode is not working right on Reno theme */ var initSimpleMDE = function() { var thisID = $(this).attr('id'); var visible = $(this).is(":visible"); if(visible && $(this).data('simplemde-made') !== 'true') { $(this).attr('data-simpleMDE-made', 'true'); // console.log($(this).data()); var simplemde = new SimpleMDE({ element: document.getElementById(thisID), toolbar: ["bold", "italic", "heading", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "|", "preview", "side-by-side", "fullscreen", "|", "table", "horizontal-rule", "code", "|", "guide" ], spellChecker: false, promptURLs: true, // forceSync: true, }); } } /** * Init the field on page load */ $(window).load(function(){ $('.InputfieldSimpleMDEField').each(initSimpleMDE); }); /** * Re-init for fields that are now visible due to: * - opening a tab with a hidden field, making it visible * - opening an accordion with a hidden field, making it visible * - opening a field that was closed */ $(document).on('wiretabclick reloaded opened', function() { // console.log("got here"); $('.InputfieldSimpleMDEField').each(initSimpleMDE); });
  14. The biggest reason I made sure to include "wiretabclick" was because I have multiple tabs with different SimpleMDE fields on them - they all showed up blank when clicking on their tab until you clicked in the SimpleMDE field itself. This was the only way I could get the values to show up on tabs.
  15. @Macrura I fixed it! See the code attached. var initSimpleMDE = function() { var thisID = $(this).attr('id'); var visible = $(this).is(":visible"); if(visible) { var simplemde = new SimpleMDE({ element: document.getElementById(thisID), toolbar: ["bold", "italic", "heading", "|", "quote", "unordered-list", "ordered-list", "|", "link", "image", "|", "preview", "side-by-side", "fullscreen", "|", "table", "horizontal-rule", "code", "|", "guide" ], spellChecker: false, promptURLs: true, // forceSync: true, }); } } $(window).load(function(){ $('.InputfieldSimpleMDEField').each(initSimpleMDE); }); // Fix for things hidden on pageload, by @Ethan Beyer $(document).on('wiretabclick', function() { $('.InputfieldSimpleMDEField').each(initSimpleMDE); });
  16. @Macrura I'll keep tinkering and see if I can make any headway. If I do, I'll let you know! Thanks for the update!
  17. Sorry - your explanation of the problem is more accurate. The value of the field definitely exists, it's just not visible until the field is given focus. My idea for how to fix this was something like `imagesLoaded()` for Masonry layouts. I was going to see if there was a way to "retrigger" the SimpleMDE field after a tab was opened. I just didn't know if opening a tab triggers a Javascript event. If it does, I think that would fix this problem.
  18. I just wrote this as a comment on the Module itself, but two issues I've found with this (otherwise perfect and awesome) Module: 1. SimpleMDE has been updated from 1.10.1 to 1.11.2 2. If a textarea field in the admin is using InputfieldSimpleMDE, but is closed upon load, or on a separate content tab created with `FieldsetTabOpen`, its value is blank. I've been trying to debug why all morning, but it's over my head.
  19. Thanks, @adrian and @Juergen! I'll look into the Hook option - I need to do it for some text fields. I'll report back if I'm having any trouble. E
  20. Hey! New to ProcessWire but I am *loving* its flexibility and extensibility! Thanks for all the work on it. I just wanted to swing by this discussion and see if there was any chance that default values had been reconsidered? I'm looking for a way to do exactly what @Joss stated above.
  • Create New...