Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/24/2017 in all areas

  1. Hey! When I was building a little commercial Processwire website for a family member, I started looking into caching with WireCache and somehow had troubles to find a satisfying solution to organize the caches and their expirations. My site had a few parts that updated in a regular manner while other parts should be refreshed whenever the current page - or e.g. for the menu: any page - was saved. I wanted to create a cache of the whole page's html which should expire whenever any of its parts expired. This would be simple if you could set multiple expire values for one cache. Unfortunately, you can only set one. So I started to build a solution to my problem which uses the WireCache and creates a dependency tree for every cache. And since I haven't yet implemented a Processwire module and this little class might be useful for other websites, too, I thought I'd try to make a module out of it. This is it. Github: https://github.com/janKir/CacheNesting Please have a look, and feel free to leave a comment. This is my first module, so any suggestions are welcome. I am not even sure if my approach makes much sense for performance reasons. I'm happy to hear your opinions! Thanks a lot!
    5 points
  2. PHP's mail() is "just" a simple function one can call. However, WireMail is a class, which means one can use it to instantiate objects (ie. "create instances of it") which can be used to "manage" the action of sending emails. You can read a bit about OOP here, for example. First of all $m = wireMail(); gets an instance of WireMail and stores a reference to it in $m. $m is just a variable, it can be called "anything" (except for reserved words, of course) like $mail but do not confuse the function mail() with the variable $m. Just copy the complete examples provided in the docs or in Ryan's post and adjust it accordingly. For example: $mail = wireMail(); $mail->to('user@hi.com')->from('ryan@runs.pw'); // all calls can be chained $mail->subject('Mail Subject'); $mail->body('Mail Body'); $mail->bodyHTML('<html><body><h1>Mail Body</h1></body></html>'); $mail->send(); That is a simple example which should work.
    4 points
  3. The WireMail documentation is here. It has several examples that should help you get started with it pretty quickly.
    3 points
  4. I think you're nearly there. I'll have a stab at this and maybe, if you take code B, and add to it: <?php // wrap the whole thing in a condition that only runs // if the form has actually been submitted if ($input->post->submit) { // get the values submitted from the form via the 'name' attribute on each input field, // pass them through sanitization (to remove any possible malicious code), // and save to variables $name = $sanitizer->text($input->post->name); $userEmail = $sanitizer->email($input->post->email); $comments = $sanitizer->text($input->post->comments); $subject = "Feedback from my site"; $myEmail = "me@me.com"; // construct the email body content that you'll receive $emailContent = " <html> <body> <p><b>Name:</b> {$name}</p> <p><b>Email:</b> {$userEmail}</p> <p><b>Comments:</b></p> <p>{$comments}</p> </body> </html> "; // create new wireMail object $mail = wireMail(); $mail->to($myEmail)->from($userEmail); $mail->subject($subject); $mail->bodyHTML($emailContent); $mail->send(); } ?> It would replace your Code A. I'm not as experienced as the other members here but I think something like this. =EDIT= You'll want some kind of validation though because this would run even if the fields weren't all filled out. This is what... wireIncludeFile("./vendor/vlucas/valitron/src/Valitron/Validator.php"); $v = new \Valitron\Validator(array( "name" => $name, "email" => $email, "message" => $message ) ); $v->rule("required", ["name", "email", "message"]); $v->rule("email", "email"); ...from my original link does. Makes sure the required fields are not empty. Worry about that once the form works though
    2 points
  5. Thanks for explaining that szabesz, much of that makes sense as it builds on what I've been doing with non-form pages in processwire. I'm sure part of it is this is my first tackling of HTML forms in general, so I'm adding an extra level of abstraction to something I don't fully understand in the first place. I understand that $variables point to something else, I get the concept of classes as that is similar to CSS, I see how wireMail and WireMail have different purposes, so I guess I'm half-way there. I'm going to start with a new basic test form and see if I can get some kind of functionality going.
    2 points
  6. A quick&dirty piece for site/ready.php. The collapsed status still needs some working on, but it appears to also be working in ajax mode: wire()->addHookAfter("Field::getInputfield", null, "hookGetInputfield_lockCheckedRepeaters"); function hookGetInputfield_lockCheckedRepeaters(HookEvent $event) { $thisPage = wire('page'); // Only run our locking logic if we are editing the page in the backend if($thisPage->process != "ProcessPageEdit") return; // We don't want to lock the repeater itself (or do we?) if($event->object->type instanceOf FieldtypeRepeater) return; $repPage = $event->arguments(0); $context = $event->arguments(1); // The backend retrieves the field within the repeater context, otherwise something else // is happening we do not want any part of ;-) if($context != "_repeater" . $repPage->id) return; // Set collapsed status in the input field (the event's return), could be made a little // more elaborate $event->return->collapsed = ($event->return->collapsed === Inputfield::collapsedNo || $event->return->collapsed === Inputfield::collapsedNoLocked) ? Inputfield::collapsedNoLocked : Inputfield::collapsedYesLocked; }
    2 points
  7. @mel47, you must use the "Custom PHP code" option, adding a hook to /site/ready.php $wire->addHookAfter('InputfieldPage::getSelectablePages', function($event) { if($event->object->hasField == 'event_date') { // Where 1234 is the ID of the settings page $event->return = $event->pages->get(1234)->date_selection; // The selectable pages is the value of the "date_selection" field } });
    2 points
  8. Are you sure you have more than 3 pages with non-empty "answers" repeaters? When I test a selector that includes a repeater.count clause the expected number of pages is returned (i.e. the limit).
    2 points
  9. Was about to ask about FiledtypeTable migrations but decided to try myself and it seems to work fine this way, dropping it here in case someone's in need: <?php class Migration_2017_10_23_12_24_20 extends FieldMigration { public static $description = "Add table field"; protected function getFieldName(){ return 'booking_advanced_fields'; } protected function getFieldType(){ return 'Table'; } protected function fieldSetup(Field $f){ $f->label = 'Booking Form Extra Fields'; $f->collapsed = Inputfield::collapsedNever; $this->insertIntoTemplate('home', $f, "booking_advanced", true); //Booking advanced is a checkbox in this case, hence the showIf setup to make the table appear if required $this->editInTemplateContext('home', $f, function(Field $f) { $f->set("showIf","booking_advanced=1"); }); $f->set("maxCols", 4); $f->set("col1name", "column1"); $f->set("maxCols", 4); $f->set("col1type", "text"); $f->set("col1sort", "1"); $f->set("col1label", "Column 1 Label"); $f->set("col1width", 50); $f->set("col1settings", "textformatters=TextformatterEntities\nplaceholder=\ndefault=\nmaxLength=2048" ); $f->set("col2name", "column2"); $f->set("col2type", "text"); $f->set("col2sort", "2"); $f->set("col2label", "Column 2 Label"); $f->set("col2width", 50); $f->set("col2settings", "textformatters=TextformatterEntities\nplaceholder=\ndefault=\nmaxLength=2048" ); $f->save(); $table_module = wire("modules")->get("FieldtypeTable"); $table_module->_checkSchema($f, true); } }
    2 points
  10. Oh yes it is! As I use the admin's login form as a public login form (just redirecting frontend users to another page) it was crucial to change the logo... #logo { display: none; margin-top: 6px; } //replacing the logo: var logo_o = $("#branding #logo"); logo_o.attr("href", "/"); var innerHtml_str = logo_o.html(); var updated_str = innerHtml_str.replace("/wire/modules/AdminTheme/AdminThemeReno/styles/images/", "/site/templates/admin/"); logo_o.html(updated_str); logo_o.show(); //made hidden by display: none; so we need to turn it on. This is to prevent flashing. I hope that's all. I did it some time ago....
    1 point
  11. I was experimenting with replacing the PW logo. The implementation is kind of a brute force but I don't think there's a better way atm.
    1 point
  12. This should send the email: <?php $email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL); if (isset($_POST['submit'])) { $to = 'myemail@xyz.com'; $subject = 'Feedback from my site'; $message = 'Name: ' . $_POST['name'] . "\r\n\r\n"; $message .='Email: ' . $_POST['email'] . "\r\n\r\n"; $message .='Comments: ' .$_POST['comments']; $mail = wireMail(); $mail->to($to)->from('myemail@xyz.com'); // all calls can be chained $mail->subject($subject); $mail->body($message); $mail->send(); }
    1 point
  13. If you're think you're going crazy (I did ) and wondering why you can't uninstall modules on your site, please update Tracy! - the new Request Info panel was the cause. I also just fixed an issue with the ProcessWire Version Switcher panel. Not sure when it stopped working as expected (I think maybe a PW core change affected it?), but it wasn't doing a final reload after the version was changed which made it look like nothing had happened. This is now fixed and once again makes it possible to change core versions with one click.
    1 point
  14. That seems like a lot of images to store in an image field. Looks like there might soon be some improvements to the file/image fields to support pagination. See https://processwire.com/blog/posts/fieldtype-pagination/ There is also a request at https://github.com/processwire/processwire-requests/issues/106 for image grid mode to not include the image thumbnails in the image field. That could help performance client side, but I'm not sure off hand why the reordering of your image fields aren't working.
    1 point
  15. That is really weird. Not sure what could cause that, but some things to try: Add "include=all" to the selector. Add "check_access=0" to the selector. If there is any access control set for the repeater field, select the "Make field value accessible from API even if not viewable" option. Test the selectors in a template file to rule out any issue with the Tracy console.
    1 point
  16. Haven't thoroughly read everything written above. Quick suggestions: $config is your friend For paths, (and other stuff), $config is your friend. Rather than entering paths yourself, let it to the donkey work. For instance, if you have an includes folder in /site/templates/includes/ you can get to that easily using: $path = $config->paths->templates . 'includes/'; Delayed Output If you are not already, I recommend you use this approach. Makes it easy to pass and change variables if needed. See the Automatic Inclusions section (the $config->prependTemplateFile). Your files do not have to be named .inc. They could be .php or even .tpl.
    1 point
  17. Hmm. Felix is the author and maintainer of the PHP IntelliSense extension I referred to. I do not use the VSC code in-built one. Works for me too in VSC. IntelliSense I have noticed that if I do this: $animals = new Animals(); $traits = $animals->getTraits(); PHP IntelliSense works fine. However, if I do this... public $animals $this->animals = new Animals(); $traits = $this->animals->getTraits(); It doesn't work...I have been meaning to file a 'bug' report. I've tried the other IntelliSense but they don't work as well as Felix's.
    1 point
  18. It is html, css and js in php files. IntelliSense (at least out of the box) just does not recognize that it is html context embedded in php PW template, so no autocompletion and stuff. Felix Becker (the creator of php language server, used in VS Code as the base for php IntelliSense) writes about it in the mentioned issue. I did not find a workaround. Edit: Actually the main problem is the other way around. PHP includes in html templates/views.
    1 point
  19. Ivan, what exactly? HTML IntelliSense? The extensions I use provide HTML auto-completion, tag matching (and changing) and CSS IntelliSense. I'll post my list of extensions later.
    1 point
  20. If anyone's interested, I've forked Ryan's ProcessWireUpgrade module and added the ability for it to detect if github has a tagged release for the latest version of each listed module (except for the PW core repos which will require special handling). If a tagged release entry is found, it then adds an extra link to the table. This is strictly an alpha "proof-of-concept" experiment, but if you are interested my fork of the repo is here - just replace the current version of the module code with my fork and you should be OK. Providing module authors start tagging their releases on github, it will allow you to navigate to the release notes for review before you hit the upgrade link. As you can see, Mike Rockett has already started tagging his releases - and hence his module gets the extra "Release Notes" link. Worthwhile idea?
    1 point
  21. You PHP Intellisense for PW isn't great or PHP Intellisense in General because I use it for Symfony and Yii2 and it's superb but a memory hogger. Netbeans still tops it all in terms of speed for me.
    1 point
  22. This issue is what primarily stops me from using VS Code for php development (and that means "at all").
    1 point
  23. If it's any consolation, it's not that great in PHPStorm either. I think I will setup a similar forum topic for PHPStorm users to vent their frustrations and workarounds.
    1 point
  24. This part is already done. My problem is the selector. Thanks for the post, I didn't found it. However, I'm not sure what is really implemented in PW. Anyway, I tried many combinations using * (like $pages->find("date_selection=[*], template=config") but I was unable to get a non-null query. If someone else have an idea! Thanks
    1 point
  25. I use VS Code often, but PHP support is far from good compared to other editors like Sublime Text. VS Code is great for Javascript though.
    1 point
  26. Thanks for your reply As a matter of fact. I was tasked in creating a form heavy application. I started using NativeScript but the designers abused the combo box (html select option) in the desings. Because picker views (combo box) were huge in the native implementation compared to the web versions, the UX should be redesigned from scratch (there were so many inputs in the form that a single screen should be separated in 5 or more just to be more simple to use). So because time and money constraints the solution was: throw away Nativescript and just use a web view with onsen framework. Onsen, Nativescript, Jasonette or React Native are wonderful tools for making Apps with Javascript. It's important to know the limitations and capabilities of each tool and select the right one for the job at hand.
    1 point
  27. Sorry for being unclear! I would have expected the second to also return five pages but it only returns 3. Thanks for the link szabez, that's a very similar problem but in my case it should also work with the answers.count>0
    1 point
  28. I don't follow you - which part do you think might be a bug? Are those results not what you would expect from those selectors?
    1 point
  29. Ah. I saw that one and didn't install because of 'under development'. Teach me for being a coward. Thanks. Good video btw ?
    1 point
  30. It's working for me. I assume the code in your first post is just for demonstration, but double-check that you are using the name of your checkbox field in the selector, i.e. "sort=highlight" and not "sort=checkbox". And you will want to reverse the sort for the checkbox to have checked items appear first: "sort=-highlight".
    1 point
  31. Hi Bernhard, Modified and Created are the same for new – not yet modified "again" – pages. Does that help? Related post:
    1 point
  32. Hey there @Samk80, Max from Snipcart here. Don't hesitate to ping us at geeks@snipcart.com should you decide to give our product a try! We'd be glad to help. And a huge thanks to @evan & @flydev for mentioning Snipcart. Goes a long way!
    1 point
  33. Hi, I do not know if this is what you need, but @bernhard used to share with us his modules: https://processwire.com/talk/topic/15524-preview-rockdatatables/ (see more: https://processwire.com/talk/topic/17207-custom-office-management-crmcontrolling-software/) Also: https://processwire.com/talk/topic/4147-excel-like-crud-in-pw-using-handsontable/ https://github.com/wanze/PwHandsontable https://processwire.com/talk/topic/16608-fieldtypehandsontable-excel-like-inputfield/ Hope this helps.
    1 point
  34. Just looked at this issue recently. This seems to do the job: $this->addHookAfter('FieldtypeRepeater::wakeupValue', function($event) { $field = $event->arguments('field'); // Only for a particular repeater field // Could also use page argument for other tests if($field->name !== 'my_repeater') return; $pa = $event->return; $pa->sort("-created"); // or whatever sort you want $event->return = $pa; });
    1 point
  35. And you'll probably want to add something to make sure you only match pages containing my_repeater: $pages->find("my_repeater.count>0, !my_repeater.my_checkbox<1");
    1 point
  36. $pages->find("!my_repeater.my_checkbox<1"); This should work. It means find all pages where NOT at least one repeater does have an unchecked checkbox.
    1 point
  37. This addresses the original post. I have built and operated a web shop that did $750 - $1mil in sales per year, so I have some experience in this field. You have categories, brands, and product attributes (like size, color, sex). What you don't want to do is mix these things up. Here's how I would approach this.... Categories -- Shoes ---- Heels ---- Tennis Shoes ---- Boots Your categories do not contain sex or brand, this is stored with the product. Here's what your product fields would look like... ProductTitle ProductCategoryPage (page field type) ProductManufacturerPage (page field type) ProductAttributesRepeater (repeater field type, there may also be a case for page field type. This is where you save things like color, size and sex, and probably sku depending on how your shop is set up) Then when you need to find products you have an efficient and flexible way to do so.... Find products in category boots where manufacturer equals brand $pages->find('category=boots,manufacturer=brandname') Find all products by brand then display by category $pages->find('manufacturer=brand') Find all products by color and sex $pages->find('attributes.color=orange,attributes.sex=women') Find all products by sex and category $pages->find('category=shoes,attributes.sex=men') I think it was mentioned, but I would also use url segments and a central controller to handle the page requests (a controller to build the product listing depending on values in the url segments). Just keep an eye your sql queries for performance. In some cases it may be better to use multiple smaller queries and filter the data in your loop. You may also need to use the autojoin feature on some of these fields, but I don't fully understand autojoin yet, so it may not do what I expect.
    1 point
×
×
  • Create New...