Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/16/2018 in all areas

  1. This version expands upon our recently introduced Focus Point selection feature for image fields by adding zoom support to the mix. This version also continues resolving GitHub issue reports as other recent dev versions have, while we work towards a release candidate for ProcessWire 3.1. https://processwire.com/blog/posts/pw-3.0.91/
    8 points
  2. Mastering PHP Design Patterns book from Packt Publishing is free for the next 22 hrs (as of time of posting) https://www.packtpub.com/packt/offers/free-learning
    7 points
  3. // inside a class e.g. modules $this->addHookAfter('Pages::trash', $this, 'myHookMethodName'); $this->addHookAfter('Pages::delete', $this, 'myHookMethodName'); public function myHookFunction($event) { // ... } // outside a class e.g. inside ready.php or templates wire()->addHookAfter('Pages::trash', null, 'myHookFunctionName'); wire()->addHookAfter('Pages::delete', null, 'myHookFunctionName'); function myHookFunction($event) { // ... }
    5 points
  4. ahem... don't you want to use camelCase? preventDeletionLastEvent would be more readable than preventdeletionlastevent -> https://processwire.com/api/coding-style-guide/#4.6-methods
    4 points
  5. Here's one way to enforce only a single featured item while still enabling featured status to be set while editing an item (as opposed to using a Page Reference field on some other page to select a single featured item). In /site/ready.php... $wire->addHookBefore('InputfieldCheckbox::render', function(HookEvent $event) { $inputfield = $event->object; if($this->process != 'ProcessPageEdit') return; $page = $this->process->getPage(); // If this isn't the existing featured item... if($inputfield->hasField == 'featured' && $page->template == 'news_item' && !$page->featured) { // Add a note about the existing featured item $existing_featured_item = $this->pages->get("template=news_item, featured=1"); $inputfield->description = "Only one item may have featured status. Featuring this item will un-feature '$existing_featured_item->title'."; } }); $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // If the "featured" checkbox is checked... if($page->template == 'news_item' && $page->featured) { // Remove the featured status of any other items $existing_featured_item = $this->pages->get("template=news_item, featured=1"); if($existing_featured_item->id) $existing_featured_item->setAndSave('featured', 0); } });
    4 points
  6. There's no reason to feel sorry, we're a helpful bunch here On a sidenote: you can try the "PW custom Google search engine" I've configured some time ago: https://cse.google.com/cse/publicurl?cx=013706179141317928628:dendm4c3gpq I have used the title of this forum thread ("Restore trashed page from API") and the first result in this very thread here, and the second one is the API reference page for trash - at the bottom you'll see "related" API links, one of them being "restore". I have bookmarked this custom search so I can simply type "PW", hit enter, and search across a variety of PW-sites/resources. edit: kongondo was faster
    3 points
  7. No worries . Btw search tip: Use this one instead: E.g., searching for restore trash page or restore trash page api returns $pages->restore() as the second result and your question as the fifth .
    3 points
  8. // Grab a page from the trash and restore it $trashedPage = $pages->get(1234); $pages->restore($trashedPage); http://processwire.com/api/ref/pages/restore/
    3 points
  9. I wonder why you need something like this in the first place "to have at least one date". wire()->addHookBefore('Pages::trash', null, 'hookTrashDelete'); wire()->addHookBefore('Pages::delete', null, 'hookTrashDelete'); function hookTrashDelete($event) { $page = $event->arguments("page"); //prevent deletion of last child $preventTpls = [ 'single-date', 'single-event', 'single-business-vacation', 'single-special-business-hours' ]; if(in_array($page->template, $preventTpls)) { preventDeleteDateEntry($event, $page); } } function preventDeleteDateEntry($event, $page){ if($page->parent->numChildren() === 1) { $event->replace = true; // now original function won't be called wire()->warning(__("Deleting of the last date is not allowed. There must be at least 1 date.")); } else { wire()->message(__("1 date was deleted.")); } } I would code it like this. So the hook could be used for different things. Also some code formatting for better reading. Use $page->numChildren(), in case you have thousands/millions of children you'd get a server out of memory Don't use $event->return = error.
    3 points
  10. I built a simple cart system using JS + Local Storage; works perfectly and the cart contents last a long time; This is for visitors to collect swatch samples and then be able to request those samples in a form; there is no ecommerce in this case, but once you have the cart, it shouldn't be hard to use that data to interact with a 3rd party payment system.
    3 points
  11. I've done a simple cart functionality with sessions. Works great. However, if you want to keep the infos longer than the browser session, you should use cookies instead. One thing to consider, however (mainly from a usability POV): Users tend to switch devices constantly. They browsed the product catalogue yesterday on their laptop, and want to continue browsing your site today on their tablet or phone. If you don't want to use registration / login, you could implement a simple bookmarking feature: Let the user create an individual bookmark (URL) for his selection, so he can continue on another device and even with another browser. This could also be used as a feature for wishlists, or product comparison tables which have become standard features in today's e-commerce world.
    3 points
  12. @andrew24, Moderator Note Please consider this your first and final warning against spamming in these forums. This forum is for ProcessWire jobs. You had hidden a link to your non-ProcessWire CMS behind your email address. I have removed your email and the said link.
    3 points
  13. 2 points
  14. Quote from page 9 of the book: "Technical debt, the eventual consequence of poor system design, is something that I've found comes with the career of a PHP developer. This has been true for me whether it has been dealing with systems that provide advanced functionality or simple websites. It usually arises because a developer elects to implement a bad design for a variety of reasons; this is when adding functionality to an existing codebase or taking poor design decisions during the initial construction of software. Refactoring can help us address these issues. SensioLabs (the creators of the Symfony framework) have a tool called Insight that allows developers to calculate the technical debt in their own code. In 2011, they did an evaluation of technical debt in various projects using this tool; rather unsurprisingly they found that WordPress 4.1 topped the chart of all platforms they evaluated with them claiming it would take 20.1 years to resolve the technical debt that the project contains."
    2 points
  15. Here is my code for others who also deals with the same issue. This little function prevents the deletion of the last child page if page has a certain template. Code runs inside ready.php. //prevent deletion of last child function wire()->addHookBefore('Pages::trash', null, 'preventdeletionlastevent'); wire()->addHookBefore('Pages::delete', null, 'preventdeletionlastevent'); function preventdeletionlastevent($event) { $page = $event->arguments(0); if(!in_array($page->template->name, ['single-date', 'single-event', 'single-business-vacation', 'single-special-business-hours'])) return; $parent = $page->parent; $childrennumber = count($page->parent->children); if($childrennumber === 1) { $event->replace = true; // now original function won't be called $event->return = wire()->warning(__("Deleting of the last date is not allowed. There must be at least 1 date.")); } else { wire()->message(__("1 date was deleted.")); } }
    2 points
  16. I've done something like this using cookies: https://www.grafikgesellen.at/textilien/textilien-mit-wunschdesign/t-shirts/ I'll showcase the site as soon as they've launched it. Any feedback already welcome (don't want to intercept this thread though ). This one sounds a little more challenging. I think you would need a login for the clients then.
    2 points
  17. @szabesz, It's something that takes a long time to be really fluent with it. And don't try and fit every problem or situation into a Design Pattern as most people who start off with this topic inevitably get excited and try and fit every problem into one. The trick is to learn to identify when a problem seems like it can elegantly be solved by applying a suitable design pattern to it if one exists at all.
    2 points
  18. for the most part, the hidden field option i think is best, but does take some logic and page saving; If you do want to have them be virtual, then you can do a hook wire()->addHookProperty('Page(template=product)::rating', function($event) { $product = $event->object; $event->return = $product->points / $product->votes; }); but you will be limited to in-memory selection, since the property is not in the database
    2 points
  19. Hey everyone! It's been a while since I last had a time to work on this module. But now I finally managed to focus on this module. So here are the latest updates. The codebase of the module grew very big and the more features I added the more time I had to spend to make sure the changes I made does not break anything. Because I had to manually verify if everything works as expected. After long night hours of trial and error I managed to setup tests for this module. Tests will help us quickly add/remove features as needed, because now there is no need for manually verifying all edge cases. Also I setup the Travis-CI so people can contribute more confidently and I can merge pull requests without worrying! There are already bunch of tests, but there is still some I'll be adding. ? ? I will add some documentation on how to run tests locally in github wiki pages soon and let you know here. Another thing to note is that the master branch of our module no longer tracks the vendor code. This means that if you download the master branch and put it into your /site/modules directory it will not work. Instead you should use release builds that are a cleaned version of the module. It includes required vendor codes and does not have extra files that are not relevant to ProcessWire. Like presentation gif images, test files and so on. This makes the module size smaller!
    2 points
  20. Yeah. I've had it in my signature for ages (so, you see, we are not so clever ) . I can't remember who created this particular CSE though. I also have it bookmarked in my bookmarks bar for easy access.
    1 point
  21. I don’t know your site, but wouldn’t you want to count only the siblings whose templates are also in $preventTpls?
    1 point
  22. Yep - field/template overrides are great. re: working in a team I'm a big fan of JIRA (or similar tools). It's good practise to chunk your project into smaller tasks and sub-tasks. We even use it sometimes to estimate hours for quotes. If used right, everyone in the team sees who is working on what (swimlanes view).
    1 point
  23. Thanks for the advice! Yeah, I know that Design Patterns are not something that should be forced no matter what, especially when dealing with CMSs like PW. That is why I used the word "study", because I guess I will get a better understanding of PHP by reading this book. Also, Design Patterns are not new to me, back in my ActionScript 3 days I read a lot about them and that helped me there too.
    1 point
  24. Aaahh, I see!! This would be a solution Thanks!!!
    1 point
  25. Hi @Juergen I'm not sure about $wire->addHookBefore("Pages::trash","Pages::delete", function($event) { .... run code }); But you can define function separately wire()->addHookAfter('Class::method', null, 'myHookFunctionName');
    1 point
  26. That's another report from 2015
    1 point
  27. Thank you! I've just downloaded it and skimming through the pages I can see that I must study this book
    1 point
  28. By the way, has anyone seen a website that already takes steps to comply with this? I'm seeing a page for a webinar on the subject with a registration form and no consent warning or even privacy policy link anywhere. I'm clicking google ads for companies selling consulting services that don't seem to have anything in place either.
    1 point
  29. https://processwire.com/blog/posts/pw-3.0.86/
    1 point
  30. Support for progressive JPGs is integrated into the Dev version. I think it is there since 3.0.80, but don't know exactly. To use it put this into your site/config.php $config->imageSizerOptions('interlace', true);
    1 point
  31. Welcome to the forum @FireDaemon Did you read this page? https://processwire.com/docs/security/admin/ Yes. In fact, during install process you are asked if you want to rename it. But you can do it later also. You could try this module. Yes That's already in core: see https://processwire.com/docs/security/admin/#preventing-dictionary-attacks In a test-environment, you can further add stuff like .htaccess allow/deny rules, i.e. only allow access from certain IPs.
    1 point
  32. Thanks for posting this Juergen, just needed a second button, too As far as I know (and for me it works) you don't need to include two buttons just stick to your first code with the class definition inserted like so for example.. $form = $event->return; $buttontext = __("Save and go to page"); $f = $this->modules->InputfieldSubmit; $f->attr("name", "submit_save_minor"); $f->attr("value", $buttontext); $f->class .= ' ui-priority-secondary head_button_clone'; $form->insertAfter($f, $form->get("submit_save")); the class is taking care of the duplication because the upper button/s are clone using jquery, thus "head_button_clone" tells the script to clone this button, too
    1 point
  33. One more: Loop pages in ProcessWire without building a $pageArray. This is useful for when a find() would return too many results to keep in memory. $selector = "template=pages_template"; // as an example while (1) { $p = wire('pages')->get("{$selector}, id>$id"); // get page with id bigger than previous if(!$id = $p->id) break; // assign current page's id to $id or break the loop if it doesn't exist // do stuff using $p as the current page wire('pages')->uncacheAll(); }; This served me well when I had to modify thousands of pages in one go. Works great with bootstrapping from the terminal because it doesn't affect the viewing of the website.
    1 point
  34. Great in lack of time i post here some links with description: 1. adrian - copy page via api https://processwire.com/talk/topic/7101-easy-way-to-clone-a-page-from-api/#entry68465 2. harmster - using csrf in own forms https://processwire.com/talk/topic/3779-use-csrf-in-your-own-forms/ 3.horst - implement a global ultility function lib/file https://processwire.com/talk/topic/7573-best-way-to-implement-a-global-utility-function/#entry73157 4. nico - reset password via api https://processwire.com/talk/topic/7167-server-error-with-latest-dev-build/#entry69041 5. yellowled - list/filter items https://processwire.com/talk/topic/7673-list-items-or-contacts/#entry74444 for the moment - i will catch the repo until i've the time....it's christmas you know for most germans this not really a quiet time....
    1 point
  35. So, let's launch this finally! › https://processwire-recipes.com/ ‹ As you can see, it's a work in progress. The design is going to change, Nico at the helm, and once we got a "critical mass" of recipes, another way of structuring recipes (the "table of contents") will also go online. To contribute, you can post your recipes either in this thread and we'll pick it up, or - codey - via Pull Request on GitHub of this repo here. Frankly, that's the favoured way, simple and a good start dive in to GitHub and this form of Open Source contribution. As always, feedback (and of course, contribution) is really welcome. We're always eager to learn - and helping to learn new stuff and create a place to spread some PW knowledge, that's what PWR was about in the first place Big big thanks to my partner in crime owzim who, among other things, contributed the - imho - heart of this tiny project: a textfile-to-page-importer. Finding an elegant way to contribute was one of the reasons this took so long, and during Beyond Tellerrand conference, it finally clicked into place.
    1 point
×
×
  • Create New...