Jump to content


Popular Content

Showing content with the highest reputation since 03/07/2020 in Posts

  1. 36 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. 21 points
    I guess we have all been there... We need to store a price to a product. "Ok, easy, let's create a new field for that in the PW backend!" might be the first thought. But then the headache starts... What about TAX? What about NET and GROSS values? And what about rounding problems when not using the correct float or decimal values ( https://processwire.com/talk/topic/7542-development-fieldtypefloat-fieldtypedecimal/ )? Meet RockPrice - a brand new (and not well tested!) module to save you from those headaches and make the UI more compact and reactive (nobody wants to calc tax/net/gross manually!). If you discover any issues or have suggestions for improvement please let me know! 🙂 --- Download: https://github.com/BernhardBaumrock/RockPrice --- RockPrice Price Fieldtype + Inputfield for ProcessWire CMS Settings Usage The field always returns a RockPriceMulti object. This object contains an array of items and the totals vor vat, net and gross (where tax stands for the tax rate in percent and vat for the actual tax value, eg. Euros or Dollars): d($page->price); d($page->price->items->first()); API Saving field value: $page->setAndSave('price', [1000, 20]); $page->setAndSave('price', [ [1000, 20], [3000, 10], ]); Comparisons $p1 = new RockPrice(1000, 20); $p2 = new RockPrice(1000, 10); d($p1->equals($p2)); // false $m1 = new RockPriceMulti([$p1, $p2]); $m2 = new RockPriceMulti([$p1, $p2]); $m3 = new RockPriceMulti([$p2, $p1]); // flipped! d($m1->equals($m2)); // true d($m1->equals($m3)); // false d($m1->equals($m3, true)); // true (ignoring sort order)
  3. 19 points
    This week we’ve got a few new and interesting core updates in progress, though none quite ready to release just yet. So rather than releasing version 3.0.154 today, I thought we'd instead take a brief look at what’s coming over the next few weeks… https://processwire.com/blog/posts/processwire-updates-and-additions-in-progress/
  4. 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
  5. 18 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. 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.
  7. 15 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/
  8. 13 points
    TrelloWire This is a module that allows you to automatically create Trello cards for ProcessWire pages and update them when the pages are updated. This allows you to setup connected workflows. Card properties and change handling behaviour can be customized through the extensive module configuration. Every action the module performs is hookable, so you can modify when and how cards are created as much as you need to. The module also contains an API-component that makes it easy to make requests to the Trello API and build your own connected ProcessWire-Trello workflows. Features All the things the module can do for you without any custom code: Create a new card on Trello whenever a page is added or published (you can select applicable templates). Configure the target board, target list, name and description for new cards. Add default labels and checklists to the card. Update the card whenever the page is updated (optional). When the status of the card changes (published / unpublished, hidden / unhidden, trashed / restored or deleted), move the card to a different list or archive or delete it (configurable). You can extend this through hooks in many ways: Modifiy when and how cards are created. Modify the card properties (Target board & list, title, description, et c.) before they are sent to Trello. Create your own workflows by utilizing an API helper class with many convenient utility methods to access the Trello API directly. Feedback & Future Plans Let me know what you think! In particular: If you find any bugs report them here or on Github, I'll try to fix them. This module was born out of a use-case for a client project where we manage new form submissions through Trello. I'm not sure how many use-cases there are for this module. If you do use it, tell me about it! The Trello API is pretty extensive, I'll try to add some more helper methods to the TrelloWireApi class (let me know if you need anything in particular). I'll think about how the module can support different workflows that include Twig – talk to me if you have a use-case! Next steps could be a dashboard to manage pages that are connected to a Trello card, or a new section in the settings tab to manage the Trello connection. But it depends on whether there is any interest in this 🙂 Links Repository on Github Complete module documentation (getting started, configuration & API documentation) [Module directory pending approval] Module configuration
  9. 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
  10. 11 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/
  11. 9 points
    Hi huseyin, just to put things into the right perspective. I studied design with an emphasis on concepting digital media and I am a certified scrum product owner. My projects are in the range of 100 - 500 dev days with usually 5 - 10 project members and a variety of stakeholders on top. Usually I start with a blank piece of paper writing down my ideas, thoughts, possible workflows etc. call it a typical mindmap. This should give me a brief understanding of the problem we try to solve. From this first rough idea I iterate into several pieces our project may need, something trivial like a login or newsletter register. The output of the second phase usually are all needed views and workflows we try to tackle. This could but doesnt have to include wireframes. Lets call it the refined product/project concept. Depending on the team, client and project we involve UI/UX for information architecture and design or use an existing Frontend Framework. But, not involving UI/UX doesnt mean we dont need a rough Design Wireframe. It is in yours, your developers and your clients best interest to atleast provide rough wireframes of every single view. At this point we should have the following documents project mindmap Initial concept with workflows wireframes for every view What could help to understand your project/product better is to create a product canvas. I attached 2 examples below. I highly recommend to try this method out. It helps to communicate, share and maintain a general overview of your project troughout the whole team including your client. Next we start to refine the concept into a technical concept, which means my developers have to provide an architecture blueprint. What servers are needed? How do they communicate? etc... What we also need is a planned database, how do our models look like? How are they organized? What services do we need? You get the point. This looks like a lot of work and it is. Usually 30-40% of our billable time is from concepting. If your client says a conecpt isnt needed, he knows what he wants. Believe me, he dont and he needs. Do yourself a flavor and plan your projects èn detail before touching your IDE. It will save you a lot in the longrun. [edit] You asked about tools, we use the following JIRA Confluence Slack good ol Excel If you need any help I would be happy to anyswer your questions.
  12. 9 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/
  13. 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
  14. 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/
  15. 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).
  16. 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.
  17. 8 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.
  18. 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.
  19. 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!
  20. 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? 🙂
  21. 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.
  22. 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
  23. 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.
  24. 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.
  25. 6 points
    This is a very early realease and at the moment more of a proof of concept that needs some more work (not a lot though!). Currently it adds VSCode snippets for all hookable methods and adds proper variable type declarations so that we get intellisense automatically: This module was easy to build thx to @adrian's work on TracyDebugger (Tracy is a dependency for the module). What I'm missing at the moment and where @adrian could hopefully provide some help: I'd like to list the arguments of the hookable method automatically. As you can see in the screencast I have to type $event->arguments(0) manually all the time. Does tracy's api explorer know something about the used arguments? If yes it would be trivial to add this to the snippets generator 🙂 PS: It adds two versions of all hooks: One regular hook that adds a separate function and one inline hook that does the same inline (as shown in the GIF). PPS: Currently the module does build the snippets file automatically only if it does not exist. It would be great if the module recreated the file whenever the api changed. @adrian any hints what the easiest way would be to achieve that? https://github.com/BernhardBaumrock/RockHookSnippets
  26. 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
  27. 6 points
    PageArray inherits from PaginatedArray which inherits from WireArray. WireArray checks for duplicates by default. You can change this behaviour through setDuplicateChecking!
  28. 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); } });
  29. 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.
  30. 5 points
    To elaborate a lil bit more on this topic 😄 yeah yeah yeah I know I know. Project Management sucks and we have a self-organized team yada yada... Could be but...who is the person communicating with clients and stakeholders? This should be the project lead. Therefor you should always have a good understanding about project progress. Lets asume you are not a freelancer and have to manage a dedicated developer team or ui team or whatever. Try to have a minimum viable project (MVP) defined and refined. What does this mean? You have carefully planned and refined a piece of software which is able to provide the basic feature set to satisfy the End-Users needs. In case of an eCommerce project this could be a piece of software with the following set of methods a cart a product page the possibility to create a product the possibility to put a product into the cart the possibility to order the items in your cart We try to cut out every single thing which is not needed to have a running eCommerce system. Things like newsletters, categories, payment methods via modules etc etc. Why should I do this you may ask, well we are humans and we have simple minds. The greater and more complex a problem is, the more problems we have to understand the system. Next comes an refinement. Tackle each component and identify sub-components. Something like this CART Order button -> createOrder() Remove Product -> removeItemFromCart() List my Products -> getCartItems() Every bits and pieces we need to develop a basic version of our Cart. Next should be an estimation meeting. What do we think each component of our MVP would take to be completed? Depending how granular you have been in your refinement you could come up with something like this (estimation in hours, you could use days, story points, apples, eggs what ever) CART Order button - 4h Remove Product -> 2h List my Products -> 2h Total: 8h Do this for every single component! You, your team and your client now know what it takes to create V1.0. But be carefull, v1.0 doenst necessary mean you have a shippable product. We just try to cut out complexity 🙂 Once done with every component create an estimation matrix, example below. The power of project management starts to unfold 🙂 You can start to create tasks based on your refinement and estimation and furthermore you can prioritize. You have to discipline yourself to do all this work, I know. It could be a bit tedious and boring, but once implemented you have the knowledge and the insights about project progress AND your project is well planned, well tought and manageable.
  31. 5 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.
  32. 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.
  33. 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.
  34. 5 points
    From Tracy's Captain Hook panel:
  35. 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).
  36. 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)
  37. 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
  38. 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.
  39. 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; }
  40. 5 points
    You could use a hook... $wire->addHookBefore('ProcessPageList::find', function(HookEvent $event) { $selector = $event->arguments(0); /* @var Page $page */ $page = $event->arguments(1); if($page->template == 'your_parent_template') { $selector .= ", sort=date, sort=title"; $event->arguments(0, $selector); } }); ...or this module: https://modules.processwire.com/modules/process-page-list-multiple-sorting/
  41. 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 🙂
  42. 4 points
    And the next piece of information... Have you ever asked yourself on mondays, what should I do now with my project? Could I start with $method1 or would I like to do $method2? The right answer is, none of them! PLAN YOUR TIME AND TASKS! So far we have learned about basic conceptional work, estimation matrix and components/sub-components. The next logical step would be to use this knowledge and start to manage ourself. Lets say we have 183 Tasks as a result from all our work we have done upfront. Great. We also know how long each and every task would possible take. Better. We can now use a method called TimeBoxing. If you are familiar with Scrum you probably know about sprints. Which is nothing else than a timebox. I dont want to dig deep into the Scrum Framework. So lets take this method and use it for ourself. The typical dev timebox in my teams runs for 2 Weeks. So on mondays we plan what we want to achieve in the next 2 weeks. How can I timebox myself? Lets assume you work 40h a week, for a 2-week timebox we have 80h pure worktime. Typically you dont work 8h straight on your tasks. Maybe your phone rings, you have to answer some emails or you help a colleague. We assume a "task efficency" of 80%. So 80% of our time could be put straight into tasks. Which means 80h * 0.8eff = 64h of effective Worktime for our project in a 2-week timebox. Lets have a look at our tasks now. There are 183 Tasks in our "Backlog". Wow thats a lot. Lets start to prioritize them. What is essential for our project and so on. Once done, great. But there are still 183 Tasks?! You remember our estimation we did? Create a new Backlog for the next 2 Weeks. This could be a Excel file or what ever. Take all your prioritized tasks which fit into your 64h. Congratulations you have now planned your very first timebox. Your timebox should now include so much work to keep you busy for the next 2 Weeks. The core concept of project management is to break complex systems into smaller much more easier and understandable fragments. Therefor, see yourself as a project which has to be managed 🙂 An example Project Backlog and Timebox Backlog down below. Left is the timebox, right is the project
  43. 4 points
    This markup actually belongs to InputfieldWrapper rather than individual inputfield renders. There is the InputfieldWrapper::setMarkup method that you can use to customise the markup that is rendered by InputfieldWrapper. See the defaultMarkup property as a starting point for what can be customised: /** * Markup used during the render() method - customize with InputfieldWrapper::setMarkup($array) * */ static protected $defaultMarkup = array( 'list' => "<ul {attrs}>{out}</ul>", 'item' => "<li {attrs}>{out}</li>", 'item_label' => "<label class='InputfieldHeader ui-widget-header{class}' for='{for}'>{out}</label>", 'item_label_hidden' => "<label class='InputfieldHeader InputfieldHeaderHidden ui-widget-header{class}'><span>{out}</span></label>", 'item_content' => "<div class='InputfieldContent ui-widget-content{class}'>{out}</div>", 'item_error' => "<p class='InputfieldError ui-state-error'><i class='fa fa-fw fa-flash'></i><span>{out}</span></p>", 'item_description' => "<p class='description'>{out}</p>", 'item_head' => "<h2>{out}</h2>", 'item_notes' => "<p class='notes'>{out}</p>", 'item_detail' => "<p class='detail'>{out}</p>", 'item_icon' => "<i class='fa fa-fw fa-{name}'></i> ", 'item_toggle' => "<i class='toggle-icon fa fa-fw fa-angle-down' data-to='fa-angle-down fa-angle-right'></i>", // ALSO: // InputfieldAnything => array( any of the properties above to override on a per-Inputifeld basis) ); But this applies to the whole InputfieldWrapper. In terms of making it more targeted you can set markup for individual inputfield types by using the inputfield class name as a key: $wrapper->setMarkup([ 'InputfieldText' => [ 'item' => '<li {attrs}><p>Markup before</p>{out}<p>Markup after</p></li>', ], ]); But you can't target individual inputfields by name or something like that. LoginRegisterPro has a similar setMarkup() method but has the added feature of letting you use "name=some_inputfield_name" as a key: https://processwire.com/store/login-register-pro/docs/#customizing-markup-and-or-class-attributes-html It would be cool if a feature like that was added to the core InputfieldWrapper::setMarkup method.
  44. 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 😄
  45. 4 points
    @ryan, great timing on the $pages->has() method - I requested essentially this just the other day: https://github.com/processwire/processwire-requests/issues/358 But the method name has() seems not so intuitive - if you didn't know better you would think this returns a true/false value. I think $pages->getID() would be more intuitive - maybe that could be added as an alias?
  46. 4 points
    Hi @kongondo just very curious as a padloper customer. Would it be possible for you to communicate a tiny bit more about what is happening maybe when to expect the fruit of all your hard work just so we know when to budget our sending you money for the upgrade to the next version thanks!
  47. 4 points
    Thanks for the comments system upgrades. Any chance while you're still in that space that you'd consider taking another look at the enhancement this PR (https://github.com/ryancramerdesign/ProcessWire/pull/954) added so that logged in users don't need to fill out name, email fields etc? Thanks.
  48. 4 points
    I once asked Ryan if he plans to add language files to his Pro modules. He doesn't plan to do so. His reply was (more or less) that most people using these modules were developers, not authors (clients), and a developer surely understands English. Fact is, many of the Pro modules are not only being used by superusers, so that's kind of a weak excuse. It's a lot of work translating e.g. a Lister Pro language file. Of course, for German, I only did it once, and then copy files over. Other eco-systems have solved this way better imho... On a side-note: Ryan is maybe missing out on marketing arguments here... it would be easy for him to aggregate at least a dozen translations for his modules from existing developers / agencies who bought a license and translated everything on their own. In return, he could give away licenses or free access to the VIP support boards to those ppl who translate Pro module JSON files ( A classical win-win situation 🙂). For some ppl, it makes a difference if a module is already translated in x languages or just English. That's a robust sales argument right there.
  49. 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.
  50. 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.
  • Create New...