Jump to content


Popular Content

Showing content with the highest reputation since 03/01/2020 in all areas

  1. 33 points
    I hope everyone here is doing well, staying in, and staying healthy. Our town here is under a “stay at home” order, and it’s now the law that you can’t get within 6 feet of any other person when out walking. So haven’t left the house (other than for walks and bike rides) in about 2 weeks now. Though with the whole family home all the time, it admittedly feels a lot busier than before this Coronavirus stuff, I think because there’s now a lot more people to attend to during the day (especially kids). Not much silence compared to before. 🙂 Not a bad thing, just very different. If we’ve got to spend a few months, or even a year this way, it’ll be alright, so long as the internet keeps working. I’m just thankful to have a job where I’m already used to working this way, as I know many of you do too. It seems that this whole situation is going to move a lot of activity online that previously wasn’t, so I anticipate it’s going to be potentially a very busy and important year for web development. Online communication and content delivery is going to be that much more important for the world, making reliability, scalability and security every bit as important. These are always our focus, but just want to emphasize this even more as we look forward. With a world in temporary disarray, you can count on ProcessWire to be an especially stable and reliable tool that gets even better every week, and our community always a friendly and helpful place. I’ve got several things in progress in the core, but nothing far enough along to write about just yet. I’ve also been putting a lot of work into ProCache this week, which is long due for a version update. The module still has quite a bit of PW 2.x architecture that I don’t think is needed anymore, so I’m refactoring and improving quite a bit, in addition to feature updates. Thanks for reading and I hope that you have a good and safe weekend!
  2. 19 points
    This week we have some major improvements to our core date/time Inputfield, as well as a new ability to specify your own custom classes for Page objects. Read on for all the details and examples— https://processwire.com/blog/posts/pw-3.0.152/
  3. 18 points
    Just created my first VSCode Extension - if you like it please give it a star on Github and rate it on VSCode Marketplace 🙂 Installation: Either via https://marketplace.visualstudio.com/items?itemName=baumrock.pwsnippets or directly in VSCode: Contributions welcome! https://github.com/BernhardBaumrock/pwsnippets
  4. 18 points
    I hope you are having a good week and staying healthy with all that’s going on with this Coronavirus pandemic. Here in Atlanta, they have closed the schools indefinitely, so I’ve got my kids with me during the work days for awhile, which started this week. That might slow me down with work and development here, but hopefully not too much. It might also take me a little longer than usual to respond to messages temporarily, as I get used to the new schedule. It’s a nice change of pace to have the kids home during the day, even if it slows work a bit. Thankfully everyone here is healthy and we don’t yet know of anyone being sick. But then again, nobody is apparently able to get tested for it, so who knows. It sounds like the whole world is dealing with this, I hope you and your families stay healthy and safe. I’m still working on the same client project I’ve been working on here for months, and of course doing it all in ProcessWire. This week the client project needed to do a lot with user-submitted comments, and I had to make a lot of major upgrades to ProcessWire’s comments system in order to accommodate them. Most of these upgrades are related to API improvements and making the comments field able to better handle completely custom markup for both comments and the forms to submit them. (Commit details). A couple new classes were added, and existing classes went through major refactoring. While there have been some nice API additions as well, there aren’t any breaking changes to the existing API, so it should all keep working as it always has. I’m not going to bump the core version this week because, as major as the additions were, I don’t think they will matter much to most existing installations, so there's little reason to upgrade for most. So I’ll continue plugging away here and save the version update for when there are some more things to share as well, hopefully next week. Thanks for reading and have a great weekend.
  5. 17 points
    Hi all, Apologies for the very loud silence! I hope to elaborate more on this a bit later. However, rather than keep people guessing, I'll write something short. I have been working my fingers to the bone to release a beta by spring 2020. I suppose it hasn't gone unnoticed that I rarely post in the forums at large these days. This is because I am dedicating nearly all my time to Padloper. The plan was to start early beta testing in mid-April 2020. This was largely on track. Like many of us, maybe most of us in the forums, we have all been affected in one way or another by the current situation in the world. This has thrown a monkey wrench in the works. I have had to readjust how I work, albeit my productivity taking a hit. I wish I could properly 'guesstimate' how much delay this is going to cause but it will just be futile. On the other hand, I appreciate that you have been waiting for a relatively long time for this release. I want to reassure you that I am not just kicking the can down the road. Maybe I should have been showing you more screenshots of progress but currently, that would just eat further into my limited time. Thanks for reading, and hopefully, your patience. Cheers.
  6. 14 points
    Inspired by a recent question. Image Crop Ratios Allows preset aspect ratios to be defined per image field for the ProcessWire image crop tool. The module adds a select dropdown to the crop tool. Choose an aspect ratio and the crop area will be fixed to that ratio. Screencast Installation Install the Image Crop Ratios module. Configuration Default aspect ratios for all image fields can be defined in the module config. Aspect ratios for specific image fields can be defined on the Input tab of the field settings. You can override the ratio settings in template context if needed. Insert a hyphen as the first item in the ratio settings unless you want to force a ratio to be applied to the crop tool. The hyphen represents a blank option that allows a free crop area to be drawn. Usage Click the "Crop" link on the details view of an image thumbnail. Click the "Crop" icon at the top of the editor window. Choose an option from the "Ratio" select dropdown. https://github.com/Toutouwai/ImageCropRatios https://modules.processwire.com/modules/image-crop-ratios/
  7. 11 points
    Hi there, while developing a sideproject which is completly build with ProcessModules i suddenly had the urge to measure the performance of some modules 😉 as a result, say welcome to the FlowtiAppPerformance module. It comes bundled with a small helper module called FlowtiModuleProfiler. In the first release, even though you could select other modules, it will track the execution of selected Site/ProcessModules. This will give you the ability to gain insights how your Application behaves. The Main Module itself will come with 2 Logging Options, Database or PW Logs. Select Database for Charts and Logs...well If you just want your profiles as a simple log file in PW. You also could choose to dump the request profile into TracyDebugger as shown here: Dont wonder about my avg_sysload, somehow my laptop cant handle multiple VMs that good 😄 Settings Screen Monitoring FlowtiLogs again, dont look at the sysload 😄 I will update the Module in the future to give some filter options and aggregation, but for now it satisfies my needs. I hope it is helpfull for some. Module is submited to the directory and hosted at github https://github.com/Luis85/FlowtiAppPerformance Any suggestions, wishes etc. are much appreciated. Cheers, Luis
  8. 10 points
    This latest version of the core on the dev branch focuses on comments field updates, significant refactoring/improvements to ProcessWire’s core Template class and PagesLoader class (which is used by the $pages API variable), and we introduce a useful new $pages API method— https://processwire.com/blog/posts/pw-3.0.153/
  9. 9 points
    Hey there, hope you are all well! I would like to introduce Nova from Panic.inc, a new IDE and code editor for web developers. The application is developed natively for macOS and is the successor of Coda 2 (if you know it). I'm sitting here in my home office (because of Corona) and yesterday I got the invitation for the beta. Now I have been testing Nova for about 1 day. The application is incredibly fast! I haven't used anything comparable so far (including VSCode). The user interface is very clean and skinnable. Here is a small excerpt of the already integrated features (which of course can be extended by plugins): - Project management - Integrated Remote Publishing - Integrated Git Handling (Push, Pull, Commit, etc...) - Integrated Code Completion (PHP, JavaScript, ...) - Full featured integrated remote file browser for all thinkable protocols - Integrated web preview - Integrated console (local and remote) - Tasks (this seems to be huge! I'm telling you more when I figured out what this can do) - etc... This will definitely be my IDE for the next years! Nova is currently in closed beta. No new tester are accepted. But should be in open beta in the next few weeks! Have a nice week and stay healthy! Greetings, Martin
  10. 9 points
    I guess that tool was not exactly built for mocking up a ProcessWire template/field-setup 😄 But I think this could be quite helpful - also for asking/explaining questions here on the forum! https://dbdiagram.io/
  11. 9 points
    Everybody please take this pandemic really seriously!! Panic does not help for sure, but ignorance or underestimating this situation will cost the life of thousands of people all over the world! As the following chart shows, the mortality highly depends on the amount of people that are in need of medical care at one time! Taken from link 2, see below. I have underestimated it myself just like almost anybody in europe has, as nobody of us here has ever experienced a situation like this before (in contrast to asia). Here are two links that I encourage everybody to read, even if you live in an area that has not (yet) been affected: 1) https://www.washingtonpost.com/graphics/2020/world/corona-simulator/?fbclid=IwAR0ABgvQGxm005seLywxDkZScKImi53Du9lzAlMwrDH6qsaaefW-Oux-Gao They have great simulations of how such an exponential growth can/will happen and what every single person can do against it! 2) https://medium.com/@holger.heinze_81247/coronacodex-my-commitment-during-the-covid-19-pandemic-76613656dac0 I hope that was not offending the forum rules that don't want political discussion... I work 100% remote now and I encourage everybody to do the same if at all possible. Not because I'm afraid (luckily I'm not at high risk as I'm young and healthy), but to take responsibility for all the people around me and keep the number of people needing medical care as low as possible so that the staff in the hospitals does not have to decide which patient (with severe symptoms) is treated and which is not (and will likely die).
  12. 8 points
    Hi all, I'm searching for Alpha/Beta tester of the new rewritten Croppable Image module. I opened a new repo on Github, with the name CroppableImage4: https://github.com/horst-n/CroppableImage4 It is a rewrite of the CAI3. I dropped all internal image manipulations, to be more future safe. Now I delegate all this to the parent core image fields methods. To be able to do this, I need to change some things and the module is no longer backwards compatible. A) For the alpha & beta testing, there is a new crop method name: $image->getCrop4(), this may be changed later to the legacy $image->getCrop() method. But for the testing period to avoid conflicts with CAI3, it is named getCrop4(). <- OBSOLETE, see the next post here in thread B) With the first param, you pass the cropname into the method. Optionally you can pass image processing options as a second param, like with the core image field. To do this, you may use an array or a selector string. C) You can use every known options param. Width, Height, Size is ignored! If you also want create WebPs in one go, please add "webpAdd" => true to the options array, (or webpAdd=1 to the options selector string)! D) The resulting image variation names will differ from those of the previous version 3! Please refer to the readme of the repo and, maybe compare it against the version 3, if you not already know it. Thats it so far. I have tested it a bit in the last days and haven't found any issues. But it would be nice if some of you can test it too.
  13. 8 points
    Goldkinder Psychotherapie Website of the child and youth psychotherapist Heike Maßen from Mönchengladbach, Germany. A one-pager that gives an insight into her work and her practice rooms, as well as information about many relevant aspects. It's a simple responsive one-pager with a nice design from Uta Hugenbruch. The front end is build without any framework.
  14. 8 points
    Just wanted to put it on everyone's radar that VueMastery is having a free weekend starting today at (12 ET). All videos in every course are free to watch until Sunday at midnight. Cheers!
  15. 8 points
    I need to build two online stores in the near future. @kongondo, I was wondering if you could share any updates on the progress. Or is it still too early for any kind of announcement? 🙂
  16. 8 points
    @Zeka Thanks, I think I tracked down the issue (caching issue that occurs only when multiple date fields) and have pushed a fix on the dev branch. @szabesz From your /site/init.php you can set the location with $config->setLocation('classes', 'path/to/classes/'); for example $config->setLocation('classes', 'site/templates/classes/'); You can also use the method mentioned earlier by adding your own directories to the $classLoader. However, the more potential locations there are for something, the more overhead, so I would recommend sticking to the $config->setLocation() and keep all of your classes in one directory. This keeps everything fast and efficient. If that's the case, then you would have to add locations with the $classLoader and accept the overhead of doing so (though it's probably negligible so long as things don't grow too much). But I also think with that kind of structure, things look isolated when it comes to reusability, limiting their usefulness. That may be fine for your use case, but as far as classes go, one of the primary purposes is reuse and extending one another where appropriate, so you ideally want to keep them together. @bernhard ProcessWire preloads a few pages on every request, since they always get used. Preloaded pages are loaded as a group rather than individually, enabling it to boot faster. This happens before the init state for modules, so a module will not have the opportunity to specify a class for these preloaded pages, but a file in /site/classes/ will. See the $config->preloadPageIDs setting for a list of what those pages are. But essentially they are the homepage, admin root page, guest user+role, and superuser role. For your case, it sounds like only the homepage is a consideration here. I would suggest just asking PW to uncache the homepage at your module's init() state. This should force it to reload (when it's next requested) using your custom class. $homePage = $this->pages->cacher()->getCache(1); if($homePage) $this->pages->uncache($homePage); You can also use $config->setLocation() for this, i.e. $config->setLocation('fieldTemplates', 'site/templates/my-custom-directory/'); I think this is fine if you are just doing it once or twice, but if you find you are repeating yourself, typing out "/articles/fields" or similar in multiple places, then you always want to abstract away stuff like that into a single location so that if you ever need to change it, you change it in just one place. PHP functions are ideal for this. This will be simple to do, but when it comes to the directory and file names that you are using, I recommend using the exact same names that you do with your templates and fields, which will make it a simple matter to abstract away repetitive code or locations into functions. "All these directories" are 3 directories, 2 of which are for optional features that are disabled by default — the absolute minimum number of directories necessary to support these things. ProcessWire is focused in what is the most simple, efficient, familiar (as it relates to the admin), and maximizes reusability. It's not opinionated about it outside of those factors. For something like field-templates, a primary purpose of having them is so that you can reuse them across different templates (to avoid repeating yourself); otherwise they aren't that useful. For the structure that you appear to be using, it looks to me like your intention is to isolate them by template, so why have them at all? If the purpose is code/markup isolation (which is still worthwhile) then I think just using an include() or $files->render(); would be preferable, more efficient and flexible for your use case. So that's what I'd recommend there. The same goes for the new page classes—if you are isolating these things in the way you've suggested, it'll be confusing for classes to extend one another or be shared across multiple templates, and it'll take more overhead for PW to find them. If you don't intend to use them like that, maybe they can still be useful, but not nearly as much so. So at that point I would reconsider whether you want/need custom Page classes. Basically, you are using a highly opinionated structure for your site files, and that can be a good thing because you've decided where everything goes and have a plan/system for how it will grow in terms of your file structure. ProcessWire is built to support a lot of different types of websites and applications, and at any scale. But it's not opinionated about this stuff beyond the bare minimum, precisely so that you can be as opinionated as much as you want with your own projects. That's why you are able to build a more complex structure for your files that suits your need, and also why it's also just as suited for others that might prefer a simpler structure in their projects. There's also no need to feel obligated to use things like field templates or custom page classes just because they are there. The point of these features is to reduce redundancy and prevent you from having to repeat yourself. But you may have your own preferred ways of doing that—whether it's with functions, file/directory structure, or anything else, it's all perfectly fine in PW. A template file receiving a $page is the only assumption needed in ProcessWire and everything else is optional. So use these things when they help you do that, and avoid using them when they don't. The reason these features are disabled by default is because not everyone needs them. Personally, the only time I use field templates is for multi-value fields with lots of properties, like repeaters, where I need to reuse the same output/markup across multiple template files. Though custom Page classes I'm already using quite a bit and likely will in most cases.
  17. 8 points
    Love the custom Page classes!
  18. 7 points
    The site of Jörg Hempel was built back in 2013/2014 the first time with ProcessWire, (version 2.3+ or 2.4). Then, over the years, individual areas were repeatedly rebuilt, equipped with new features, etc. Once, more than 50000 original images had to be exchanged and replaced by larger ones. I still remember that I wrote two days on the scripts, with which all original images were automatically exchanged via SFTP and all variants were recreated. At that time, a local computer ran three days and nights continuously in four parallel tasks. The exchange ran smoothly and without a single minute downtime of the live page. Today, the images (incl. variants) occupy over 130 GB disk space. :-) But due to the different version changes, PW 2.4, 2.5, 2.6, 2.7, 2.8(!), all none namespaced, to the namespaced 3.0+, a lot of unsightly solutions were created, e.g. to adapt unmaintained third party modules etc. In the front end were some old libraries in use, too. Therefore Jörg Hempel decided to rework all areas. (design, frontend and backend). Jörg developed the design together with the design agency Quandel Staudt Design from Frankfurt, Germany. The front end was built as a HTML click dummy by Benedikt Seifert from Jena, Germany. I was left with the wiring of front end and back end, as well as the redesign of all server-side processes. The new site now runs on PW 3.0.148 and PHP 7.4, using ProCache, AOS and my image helpers (Pia, PageimageManipulator2, CroppableImage3). All images use lazyload, and infinite scrolling was dropped, so we don't have to use the m.domain for mobiles any more. The extensive filtering possibilities of the archive and the blog from the old site have been preserved. Url segments are used for the filters.
  19. 7 points
    The title might sound more exciting that it actually is. It's just a little helper module to keep things organized 🙂 Basically it just saves you from finding the correct require_once("where/is/my/nette?") and, for a little extra security, it adds an .htaccess file to block all direct access to Nette source files. Why? Nette is an awesome framework with some awesome features/utilities that ProcessWire lacks. Creating separate modules and including Nette packages multiple times in those modules would not be efficient. RockNette makes it easy to store them in a central place. Usage You'll get all necessary instructions on the module information screen: https://github.com/BernhardBaumrock/RockNette
  20. 7 points
    @Robin S The purpose I was focused on for the method is to see if the system has any page that matches the given criteria. An example of the use case appears in the Template class updates here. It verbally makes sense in code for what it's intended for. Usually I'd use a get or count for that, I didn't need any of the extras that $pages->get() or $pages->count() provide, so thought we could eliminate some overhead. Plus I can think several other other cases where the same was true, so the need has resurfaced enough times that it seemed like good method for PW to have. The method returns the ID just because it already has that info either way, and it seemed potentially more useful (and 0|1+ communicate the same thing as false|true). I had also seen where you'd mentioned a getID recently, and since this method already has the page ID, I thought this also seemed like a good opportunity to accommodate that need too. So far I haven't come across a good use case for getID() in my own projects, outside of checking for existence of something (which 'has' seems like a better term for). But it certainly makes sense alongside the existing findIDs() method, though that method is more about accommodating a scale that find() can't. But it sounds like you've had use cases for it which means others likely have too, and that's plenty good reason for me. I'll go ahead and add getID() it as an alias of has(). Depending on what need you are looking to solve, I imagine this will help people to find what they are looking for more easily.
  21. 7 points
    Right, this should be fixed now finally. For those that are interested, there was an issue with the forum session wiping out the ProcessWire session by the end of the script - a little puzzling because right up to the end of the script everything seems fine but when you redirect the session information is lost. To overcome that there's some background CURL stuff going on now so the two systems are separated completely during the login process. Please feel free to post/update your profiles again and sorry it took so long.
  22. 7 points
    Hi guys, I was very excited for this module, but my life took a huge direction change and I no longer have the time to invest in module development. I am gonna leave the files here. You guys can take it and run. Maybe there might be something useful here. Maybe not. I still think it's a good idea to do drag and drop modal building in PW. So hopefully one day something like that can come to light. I love this community and I love ProcessWire. Live long and prosper. - Joshua Designme 2.zip
  23. 6 points
    MY OPINION here: While we wait for Padloper v2, using Shopify is the best option. You will pay $29/mo plus the common fees for payment gateways 2.9% + $0.30 per transaction. This includes unlimited "managed" high-speed hosting, several free front-end themes and the easiest to use back-end you can imagine, including statistics, marketing tools, selling on multiple channels (facebook, messenger, instagram, amazon, ebay). Also you can stop your subscription at any time, and jump to Padloper v2 when it's out. But.. if what you want is to use Processwire for content and implement only the shopping cart and the payment gateway inside: Your best option is Shopify.. again. There is a plan for $9/mo that does not include the front-end store, only the admin part in which you can enable the "Buy Button" sales channel and with a small javacript code you have the cart on your website. It's very similar to what Snipcart does, but muuuuch cheaper, because Snipcart charges 2% plus 2.9% of the payment gateway in each order. In my company (we sell Air Conditioners) the AOV is between $2000 - $4000 that total fees represent a maximum of $192 per order, where Snipcart will get $80 for each order. We are in the low season, and today we start the day with 108 orders, make the numbers.. ~$8000 in one day for Snipcart plus the CC fees! I know this also depends on the type of store you have, but my advice --> never EVER go with a solution that charges you a percentage of the sale. PS: Shopify also comes with a very VERY very easy to use API (REST and GraphQL too) ..maybe one day we can have our Shopiwire LOL PPS: None of this is a Shopify affiliate program, it's just a personal experience after a lot of research. https://www.shopify.com/lite
  24. 6 points
    PageArray inherits from PaginatedArray which inherits from WireArray. WireArray checks for duplicates by default. You can change this behaviour through setDuplicateChecking!
  25. 6 points
    @adrian There are two options when you initialize your CommentForm that let you define what you want to be populated, and whether or not you want it to be editable. These are the 'presets' (array) and 'presetsEditable' (bool) options. I'm initializing with the new CommentFormCustom class below, but the presets options also work with older versions of PW: $options = [ 'className' => 'CommentFormCustom' ]; if($user->isLoggedin()) { $options['presetsEditable'] = false; $options['presets'] = [ 'cite' => "$user->first_name $user->last_name", 'email' => $user->email, ]; } $form = $page->comments->getCommentForm($options); As for using a local image for avatar, or deciding whether or not to show cite and email, this is where the CommentFormCustom class comes in handy. It leaves you in full control of the markup, so you can render whatever avatar image in there you want (whether CommentFormCustom or CommentListCustom), and exclude fields in your markup when conditions dictate. In previous versions, if you didn't want to show specific fields in the form then you would hide them with CSS. @AndZyk Here's how you might do that with a hook. This looks for markdown style links, i.e. [text](url) and converts them to HTML links. The regex may need improvement still, but maybe it's a starting point. $wire->addHookBefore('CommentList::renderItem', function($event) { $comment = $event->arguments(0); /** @var Comment $comment */ $text = $comment->getFormatted('text'); $textOriginal = $text; // look for markdown style links: [text](url) if(strpos($text, '](') { $regex = '!\[(.+?)\]\((https?://[^)\s\r\n;"\']+)\)!i'; $link = '<a href="$2" rel="noopener noreferrer nofollow" target="_blank">$1</a>'; $text = preg_replace($regex, $link, $text); } // populate changed comment text if($text !== $textOriginal) { $comment->set('textFormatted', $text); } });
  26. 6 points
    Memo to myself and mybe to safe someone else from losing hours trying to understand why a multi-language Inputfield does not render() as expected... Learnings: 1) Inputfield::render() is only hookable for single-language Inputfields! When PW renders a multi-language Inputfield the LanguageSupport module adds a hook that fires after the original Inputfield::render(). This hook calls the render() method for each language and to avoid circular references it does that directly on $inputfield->___render() and not $inputfield->render(): https://github.com/processwire/processwire/blob/51629cdd5f381d3881133baf83e1bd2d9306f867/wire/modules/LanguageSupport/LanguageSupport.module#L445-L453 2) When building a custom Inputfield that supports a multi-language setup it is critical that its render() method is defined with 3 underscores! Otherwise the LanguageSupport hook that adds the markup for the other languages' fields would not fire.
  27. 6 points
    Thanks, but not necessary. Pretty much all my modules get created because I have a need for them in work that I get paid to do, and it doesn't cost me anything to make them available for others to use too.
  28. 5 points
    I have built little forms like this manually a couple of times! It's definitely fun, though building complex forms is a lot more work than one might think, but for small forms you'll be fine. No problem at all - you just need to handle the things that FormBuilder will do. In your example, most notably: Write the HTML for the form. You can try to dynamically generate this, but building exhaustive options for form fields is much work, so for a simple form static HTML will be fine. Handle the result. I'd do that within the template file of the template where your form is output. For a normal form you'd need some form of Spam protection, CSRF protection and other stuff but since in your case you require a password that won't be necessary, since you can just throw out submission that don't match the password. Store the submission, more on that below. Submit the file. For a simple solution, you can just redirect to the URL of the file. I have built something where I wanted to make sure the file can ONLY be accessed through the form. For this, you can put your file in a safe location (outside your webroot) and stream it through PHP once you have checked if the password is correct. Make sure to output the correct header to instruct the browser to start a download. Quick and dirty, based on the readfile documentation: if ($input->post('password_field') === $page->my_secret_password) { $file = '/path/to/file.pdf'; header('Content-Type: application/octet-stream'); header('Content-Disposition: attachment; filename="'.basename($file).'"'); header('Content-Length: ' . filesize($file)); header('Cache-Control: private'); readfile($file); exit; } Honestly, don't overthink this bit. Unless you are expecting thousands of request an hour, you don't need to optimise it. Depending on what you plan to do with this data I might go with a ProFields Table field or a regular template. Those are nice because all content is stored in a single, simple table. This gives you a bit more room to optimise if and when you need to. But if you are really getting so many requests that the server can't handle them, you will probably yield more improvements by building a seperate endpoint that doesn't load ProcessWire at all and instead writes to the database directly. This will be a bit easier with a ProFields Table field, though it really doesn't matter that much. If you are using a ProFields Table, make sure you are not loading the field on your form page, because that will load ALL it's data, that might in fact get out of hand quickly if you have lots of submissions.
  29. 5 points
    If one's goal is to get an up or down from an API call, then zero vs. non-zero is functionally and effectively the same thing as boolean. If there's an opportunity to make a method more useful by taking advantage of that fact, then I'll always do it. So yes, you'll find many examples of this in PW. That's always the strategy I've tried to embrace in the PW API and plan to continue going forward. To reiterate what I stated above, the primary purpose of the has() method is not to get an ID—it is instead to check if the system has a page matching the criteria or not, without actually loading the page. Whether the method returns 0 or false makes no difference in telling the caller that the system has no page matching the criteria. Likewise if the page does match the criteria (true vs 1+). Now if you are specifically looking for a getID() function, then yes of course the name "getID" is preferable. I'm happy to add getID() as an alias for times when one might be specifically looking for that particular need. But that's not what I was looking for here. And if anyone else's experience is similar to mine, we will more often be looking to see if the system has any page matching some criteria (whether we want the ID or not). Basically replacing instances where we might have used count() before, with a more efficient alternative. So I feel pretty strongly that the has method name and return value are optimal and consistent here.
  30. 5 points
  31. 5 points
    As far as I know you don't have to use IIS, you can install apache, like XAMPP. But I can confirm PW will work on IIS as I'm on the same infrastructure as you are. I have a bit updated version of web.config here on my local test environment, but even web.config from 2016 should work. But you will need IIS rewrite module for sure. Let me know if I can assist further (like remote access via RDP or TW or anything).
  32. 5 points
    I think @LAPS wants some place that does NOT load on every request. But all of your mentioned options do load on every request 😉 How large is that list of E-Mails? 😮 If that is really too much for every request you can put it In some file that you only include() when you need it In a non-autoload module, that you request when needed (eg $modules->get('myemails')->getAll()) In a WireCache object that is stored in the Database In a dedicated page + field (eg $pages->get(1234)->emailslist)
  33. 5 points
    @wbmnfktr many thanks, but the design wasn't my work. This goes to Quandel Staudt Design ! I'm more responsible for the massive disk space usage. 😉 I only have built the homepage and the menus, - and worked on little (front end) things like the archive thumbnails on the homepage for mobile view. The design agency wanted to have fixed partial blue overlays in the bottom, with blur effect for the covered image part. I found out, that sometimes the text was to long to fit into the blue area. My recommended solution was to extend the boxes downwards, so that longer texts fit, but not too much of the image motifs get covered. Since the thumbnails are on white background, it was not possible to simply extend the semi-transparent text boxes downwards. So, now the pictures automatically get lengthened with a black, transparent gradient below and also get the blurred effect directly embedded into the pixels. original thumb like in the desktop version the lengthened (and blurred) thumb the result with the fixed partial overlay
  34. 5 points
    For logged in users, name and email are already filled in automatically and have been for awhile. There is also an option where you can make them non-editable, so that a logged in user can't modify them for each comment they make. But if you want to pull them from something other than "name" and "email" (which I think might be what you were looking for), then the new classes would definitely make it a lot easier to customize, and populate whatever you'd like in there. Likewise to render a custom avatar or hide fields, etc. The custom classes should open up a lot of new possibilities.
  35. 5 points
    You don't even need to adjust your template, as long as the rows have one common parent you can use the CSS nth-selector: .row { display: flex; flex-flow: row nowrap; justify-content: space-between; align-items: center; } .row:nth-child(2n) { flex-direction: row-reverse; }
  36. 5 points
    The replies above by Ryan and BitPoet pretty much covered the questions you raised, so just dropping a quick comment regarding this 🙂 I tend to fuss a lot over things like organising the project, so I'd say that I'm familiar with your concerns. In my opinion a sensible structure is a key design decision, and even more so when you're working with others. So yeah, I can't disagree with anything you've said here. Regardless, after giving this a lot of thought I ended up organising files by type — at least I think that's what you'd call it — in Wireframe. By this I mean that I've indeed bundled controllers in one directory, components in another, views in a third one, etc. For me this just makes more sense: When I add a new template and a view for it (assuming that it isn't already covered by some shared code, which is quite often the case), I'll probably start from the controller. I may copy-paste some parts from other controllers, or perhaps I'll extend another one if I have a very similar need at hand. Some controllers may use other controllers as sort of "subcontrollers", and often there are shared libraries as well. After the "backend" is mostly done, I'll move on to the view in order to actually put those methods to use. In other words I tend to work in layers, going from backend to the frontend. (This is just the way I like to work, and I definitely don't assume everyone to prefer the same approach.) Things like components or partials are made to be shared. If I only need a specific piece of code once — or in one template — then it probably doesn't need to be abstracted away. That'll just make things harder to grasp and add a tiny bit of overhead without actually providing much extra value. Copying files from project to project has been a relatively rare need for me, so when it does come up, it doesn't matter much if I have to copy one directory, or perhaps a couple of files from a couple of directories. That being said: in an old environment this need did come up often (and the structure was pretty complex), so I ended up writing a script to automate it 🙂 It's true that the process of building a new site often involves moving back and forth between backend and frontend, but I still prefer this sort of structure over the alternatives. Also: I find it a tad easier to maintain after the site is already live, since often a specific change will only affect one "layer" of the site. Anyway, this is largely a matter of preference 👌 Exactly. When I first read about custom Page classes, my first thought was that this stuff is frigging cool... but I probably won't be using it anytime soon. I fully agree that it's a great feature, but in my case I've already solved it in a way that — in my opinion — fits my needs better. I may end up using this for some stuff eventually, but right now I don't have a need for it, and that's fine 🙂
  37. 5 points
  38. 5 points
    Another perspective: The API acts as the model, with the $page / Page class giving you access to page data through a generic interface. By default, the PHP template file for the current content type / template acts as Controller and View, though you can easily seperate Controller and View by using, for example, a frontend templating library like twig. That's close to my usual setup: View: Twig acts as a View layer, since it gets pretty privileged access to API variables, you can get anything done you'd usually do in a PHP View class. Controller: The PHP template file acts as the Controller, for example processing input and rendering the correct Twig template. Usually, I just keep the template logic procedural, because ProcessWire already does a lot of work in determining the correct template file and setting up API variables. Though you could also use a custom Controller class and just use the template file to instantiate it. Model: As mentioned above, the $page API variable is already a kind of generic model for your data, and for sites that are mostly brochure sites / presentational in nature, this is really all you need. But if you want to go further, you can create custom page classes by extending the Page class and set your template to use that, this way you can make your model as smart as it need to be. I have written two tutorials on how to integrate Twig if you're interested 🙂 Part 1: Extendible template structures Part 2: Custom functionality and integrations
  39. 5 points
    I saw this slide on Twitter : Apparently PHP8 will throw Errors instead of Warnings for many instances. So perhaps it is adviceable to already start preparing your code for the upgrade.
  40. 4 points
    Hello All, In the middle of this pandemic, I came across a citizen-science site that I think we should all consider helping out. It's called folding@home and aims to produce the largest distributed medical research computer cluster in the world, in order to solve protein folding problems, that should help develop treatments (or cures) for multiple medical conditions we all face. If you, or your company, have any spare internet connected resources, please consider joining the cluster - it's fairly easy to setup the client and connect. I'm running this on my linux laptop and hope to keep doing so. It's quite CPU intensive so you get to choose the level of resource usage it can have. For example, to control my CPU temperature. I've limited to just a single thread on an i7. Please support if you can.
  41. 4 points
    Hi, With the deprecation of Instagram's API and therefore the end of the Instagram Feed module, I've developed a replacement module which uses the Instagram Basic Display API: https://github.com/nbcommunication/InstagramBasicDisplayApi To use this module you'll need: ProcessWire >= 2.7 A Facebook Developer account Access to the Instagram user account you wish to use Prior to installation, you'll need to create a Facebook app. The app you will create uses the User Token Generator for authentication - it does not need to be submitted for App Review (and therefore stays in Development mode). The README contains full instructions on how to create and set up the app and also how to use the module. The primary reason for this module's development was to retain functionality on existing websites that use the Instagram Feed module. To assist with upgrading, this module replicates some methods provided by Instagram Feed. I've already upgraded a couple of sites and it was quick and painless 🙂 Cheers, Chris
  42. 4 points
    So I just opened an issue and closed it immediately because I realized that my proposed solution already exists in the form of wirePopulateStringTags 🙂 It works perfectly for my use case, only requiring to use {title} with curly braces instead of title for the first example, which in a way is even more predictable. Those functions should really have better visibility in the documentation 😄
  43. 4 points
    https://affinity.serif.com/en-gb/supporting-the-creative-community/ + A new 90-day free trial of the Mac and Windows versions of the whole Affinity suite + A 50% discount for those who would rather buy and keep the apps on Mac, Windows PC and iPad + A pledge to engage more than 100 freelance creatives for work, spending the equivalent of our annual commissioning budget in the next three months (more details of this will be announced soon). [Temporary addition: https://www.planethoster.com/en/VPN At the bottom of the page, see prices/month if 1 month, 1 year or 2 years. https://my.planethoster.com/en/world/new?billingcycle=annually&currency=EUR&plan=World A better deal if you take it as a VIP option with a hosting account (servers in Paris and Montreal): Includes all the features of the World Platform™ Free WHOIS Free VPN + LSCache (I haven't tried the VIP option yet.) Several ways to have the hosting (and free domain name) (sometimes a lot) less expensive: https://docs.planethoster.com/guide/facturation/code-promo-rabais-remise-promotion (In French but you can google-translate it if needed. It's worth it.)]
  44. 4 points
    @kunago, I think Croppable Image 3 is probably the best option for a lot of cases (e.g. you don't want the user to create a cropped image smaller than the given pixel dimensions), but inspired by your question I created this module:
  45. 4 points
    So the key information here is that the offsets of timezones are not fixed for eternity. There are databases you can download to your OS or e.g. from groups like IANA, which hold information about which offset a certain timezone was exposed to at which period of time. And those databases are updated about a handful of times a year (but not each time for actual new rulings). A good example for actual changes is the EU, which is currently starting the process of migrating away from switching to/from DST. Generally you're mostly fine for past datetimes, but the farther you're in the future the more likely it becomes the offset you expect the timezone to have at the time could change until that time. If you convert 12.12.2030 10:00 for Europe/Berlin to 12.12.2030 9:00 UTC with the current offset of +1 in the winter and we go forward 10 years it's not clear if you get back 12.12.2030 10:00 for Europe/Berlin. The EU's efforts to remove DST might have been fruitful and Europe/Berlin is now at +2 offset all year (all year DST). So you take the db value of 12.12.2030 9:00 UTC, you add the offset for Europe/Berlin, which then is +2 and you get 12.12.2030 11:00 for Europe/Berlin. The UTC datetime was preserved, but the "wall time" wasn't – wall time being the time I see on the clock here in my office. You might be an hour late to some important appointment. You can ignore all the above if you never convert between timezones, which as far as I can see, is what processwire is doing. 12.12.2030 10:00 for Europe/Berlin will still be 12.12.2030 10:00 for Europe/Berlin when read from the db in 10 years. Essentially the wall time is preserved. This comes at the expense of absolute distance of time between two datetimes being subject to change and not being able to have absolute ordering for dates of different timezones. The latter is not a problem if the whole system just uses one timezone. This is why I said it's important to know what you care for. The absolute time passing by until a datetime or the actual time on the wall on a certain day. If you want UTC timestamps in your db, but not give up preserving the correct walltime you'll need to store more information in the db besides the utc timestamp to be able to react to changes like I described.
  46. 4 points
    Not that much has changed since my inital post but still I want to give a short update. One thing has changed and made my life easier. I re-installed Manjaro and used it's XFCE edition and installed i3 afterwards. So I had everything in place I may need in the future - as in graphical interfaces for changes or settings. But to be honest... I never needed it by now. Still... happy to have it around. Another thing I changed was the keyboard layout. I used to use a QWERTZ (DE) keyboard but for a few weeks now I'm using a QWERTY (ANSI) mechanical keyboard and layout. Im still struggling to hit each and every key in the right moment but... well... it works quite well so far. Most of the time it's even easier than before as < >, [ ] and { } are way easier to type as before. At least while writing code. (Dear german/austrian/swiss DEVs... try an ANSI QWERTY keyboard... brackets, braces and however they are called... are way easier to type.) Don't know how I got here but by now my full boot time is down to 11 seconds, which is nice, but overall... using lots of terminal programs my CPU load and memory usage went way down. CPU on average 10%, and RAM at about 1GB. Quite impressive on a 2015 Thinkpad with i7 with 8GB of RAM. Due to a dedicated swapfile I can almost double my RAM to 16GB in order to run Chromium, Firefox, Opera, Brave and Vivaldi, while Thunderbird, ScreamingFrog, VS Code and lots of other apps running. Git, Yarn, NPM and all the tools I almost never used running almost each and every day - in terminal but still. Still struggling to prepare my MS Surface to love Linux but... yeah... everyone needs I hobby I guess. Details can be seen in the screenshot below... otherwise... ask here or in the DMs.
  47. 4 points
    Not without a hook, but this should work: // Hook for site/ready.php that makes $page->render($fieldname) look for // its template in site/templates/$templatename/fields/$fieldname.php. // Specifying alternative files still works. // Pass a path with a leading slash as $file to go directory from the templates dir. $storedFieldTemplates = []; $this->addHookBefore("Page::renderField", function(HookEvent $event) use($storedFieldTemplates) { $page = $event->object; $file = $event->arguments(1); $storedFieldTemplates[] = $this->config->paths->fieldTemplates; $this->config->paths->fieldTemplates = substr($file, 0, 1) == '/' ? $this->config->paths->templates : $this->config->paths->templates . $page->template->name . "/fields/"; }); $this->addHookAfter("Page::renderField", function(HookEvent $event) use($storedFieldTemplates) { $this->config->paths->fieldTemplates = array_pop($storedFieldTemplates); }); Shortens it down to $article->render('article_lead', 'lead')
  48. 4 points
    Technically it's already possible — you just need to tell WireClassLoader where it can find your custom Page classes. Just gave it a try, adding this to /site/init.php, and it seemed to work fine: $classLoader->addSuffix('Page', __DIR__ . '/templates/page-classes/'); Now ProcessWire checks for Page classes from /site/templates/page-classes/. This is in addition to the default /site/classes/ directory, which still has precedence if a class is found from there.
  49. 4 points
    Use the function wireMail() or the $mail->new() to instantiate an E-Mail object, then ProcessWire will automatically look for other WireMail modules and instantiate one of them instead of the default WireMail object. You can also request a specific WireMail module by specifing it as an option. For example, for the Mailgun module, this should work: $mailgun = $mail->new(['module' => 'WireMailMailgun']); $mailgun instanceof WireMailMailgun; // true See the documentation for $mail->new().
  50. 4 points
    Have you tried it? There is already support for strtotime strings for datetime fields in PageFinder selectors, and your example query works just as you wrote it. 🙂 For in-memory (WireArray) selectors you have to use a timestamp in the selector.
  • Create New...