Jump to content


Popular Content

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

  1. 19 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)
  2. 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/
  3. 11 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
  4. 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.
  5. 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
  6. 5 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
  7. 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.
  8. 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.
  9. 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.
  10. 4 points
  11. 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
  12. 4 points
    I now have played with Custom Page Classes too. I successfully have created a cascading hierarchy for a sort of mvc system of mine: I make massive use of templates, where most of them are simple clones. I do this to have bullet-proofed identification of specific pages, but give the clients the opportunity to change title, name, and also the ID, if he once deleted a specific page and created a new one. (Template family is set to onlyOne!) All the public viewable pages are set to the same template filename (basic-page), which previously was my controller file with all the rendering stuff. Now it's content is reduced to 4 lines only, and all render stuff is included into custom page classes, whereas it now is much cleaner to read and follow compared to before, because now I can overwrite the basic render method in custom page classes for specific pages. I created a BasicPagePage as base: <?php namespace ProcessWire; class BasicPagePage extends Page { public function renderSections() { // ... } } This one is used from all other public pages and extended only where needed: <?php namespace ProcessWire; if(!class_exists('ProcessWire\BasicPagePage')) require_once(__DIR__ . '/BasicPagePage.php'); class LegalpagePage extends BasicPagePage { public function renderSections() { // override parent method here, if needed } } Here is a debug list of a few pages The basic-page.php controller now: <?php namespace ProcessWire; // load header with navbar and footer with links, hamburger, scroll-to-top item, etc. include(__DIR__ . '/includes/_header.php'); include(__DIR__ . '/includes/_footer.php'); include(__DIR__ . '/includes/_absolute-positioned-elements.php'); // call method in CustomPageClasses to render all public viewable sections of the current page $page->renderSections();
  13. 4 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!
  14. 3 points
    https://www.pluralsight.com/ "#FREEapril Stay home. Skill up. Build in-demand tech skills without leaving your house. Get free access to 7,000+ expert-led video courses and more all month long." Note: last September's free week was OK, it WAS free of charge, really.
  15. 3 points
    Thanks! I was hoping the screenshot would do that 😆 Maybe I can give the screencast a go this weekend ... though I'm just now realizing I don't even have a headset any more 😅 Lockdown because of Covid-19 mostly 😅 No but really, the README on Github has two examples, and the first one is basically the client project that started this off. This project is a lead generation platform with multiple contact / data collection forms. Our client's team manages all requests on a Trello board. This works really well once everybody is used to it, they use many custom labels and lists to organize all requests / leads. Currently all the new leads are entered manually, but after the relaunch every request will create both a ProcessWire page and a Trello card for the lead. After additional data is entered through one of the forms, the cards are updates with more information and appropriate labels. This is what the status change handling options are for; if the ProcessWire page is trashed, the Trello card can be archived and so on ...
  16. 3 points
    And some background on why you built this would be really interesting too! Looks great!
  17. 3 points
    I have now integrated the ProCache branch into the module and released it as version 1.0.0! I have tested the module on multiple sites and it's pretty stable now. But if you do run into bugs, let me know! The ProCache integration is now included, so you can clear out the ProCache page render cache alongside all other caches. Hopefully we can resolve the issue with minified assets, see the previous post. The documentation is now updated with information on all the new methods added in the previous release. Let me know if something isn't working for you!
  18. 3 points
    Below is what we had changed in the MarkupRecurme.module file. As @adrian posted, our version has had a number of tweaks. So perhaps have a closer look before implementing these changes. Hopefully this helps. Line 271 $m = date('m', strtotime($date[3])); To $m = date('m', strtotime("1st " . $date[3])); AND Line 864 $m = date('m', strtotime($date[3])); $y = $date[4]; To $m = date('m', strtotime("1st " . $exclude[3])); $y = $exclude[4];
  19. 3 points
    We have also noticed issues w/ Recurme dates displaying incorrectly. Similar idea as Arcturus, nothing had changed in months. What we found was the issue was triggered on a month that contained 31 days. From my re-collection it might have also affected the month by bumping it by one month. I'll post the fix that worked for us a bit later this evening.
  20. 3 points
    Hi there, If I understand correctly you don't want to have selected none page? If that is the case, just drop down pages for select, find that one which is selected and choose "unselect".
  21. 3 points
    @Robin S Awesome module. I never understood why this functionality is not in the core. 🤷‍♂️ Thank you for implementing this feature! I sent you a pull request on GitHub, with a bugfix regarding multilanguage setups and float conversion, small performance tweaks, and support for repeaters! Best regards. https://github.com/Toutouwai/ImageCropRatios/pull/2
  22. 3 points
    https://maquiladorademuebles.com/ Here I did a very rough integration of the Shopify Js SDK with ProcessWire, so that I could add more specific things to each product, when I talked to the client it was more important to have the potential to have more flexibility when uploading the product's content so we went this way of using Shopify inside PW. My first mistake was rolling my own Js integration when I could have just used the Buy Button SDK (instead I used the Js SDK with Vue). Second mistake. One thing I didn't anticipate that turned into a mess: discounts. I had to setup fields in Pw where I had to set the discounts (after setting them up on shopify), so a lot of double data entry on some cases. I've done also things the other way around, setting up ProcessWire as an application that launches within Shopify, so that I could use PW pages as extra content management for Shopify product pages. (very complex product descriptions) unfortunately the project I did this for never launched. Agree with @Pixrael the Shopify API is really easy to work with.
  23. 3 points
    Thanks again for your feedback. I tested the privacy & imprint URLs and there really was a small bug about the multi language URLs. When you update the module the multi language URLs should work now. Example of external media: <!-- This is the output container --> <div id="player"></div> <script type="optin" data-type="text/javascript" data-category="external_media"> // 2. This code loads the IFrame Player API code asynchronously. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // 3. This function creates an <iframe> (and YouTube player) // after the API code downloads. var player; function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: '360', width: '640', videoId: 'M7lc1UVf-VE', events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { event.target.playVideo(); } // 5. The API calls this function when the player's state changes. // The function indicates that when playing a video (state=1), // the player should play for six seconds and then stop. var done = false; function onPlayerStateChange(event) { if (event.data == YT.PlayerState.PLAYING && !done) { setTimeout(stopVideo, 6000); done = true; } } function stopVideo() { player.stopVideo(); } </script> See this for more info about the YouTube API. The code above is from their example.
  24. 2 points
    Insane output of great modules! 👍
  25. 2 points
    v0.0.3 adds user templates to restore complicated recurring prices (I was too lazy to always input the same complicated numbers for my internet invoice 🙂 ) User templates You can save custom user templates to easily restore complicated recurring pricings:
  26. 2 points
    Turns out that things were not as easy as I first thought 😄 After the input of several invoices I came to a case I didn't think of (or didn't want to think of): Having multiple different tax values for one invoice 😝 I totally refactored the module and the result does have more features and is also a lot nicer from the code. The field's value is now always a RockPriceMulti object that can hold any number of RockPrice objects. v0.0.2 - Initial post is updated!
  27. 2 points
    Looks great! Let me know how it's faring and I'm happy to use that instead of the page's process setting. You're doing a good job convincing me here. It does make sense conceptually and thinking about the module ecosystem as a whole. That said, the module is currently at a point where I'm not missing much in terms of functionality and am not that keen on re-writing the whole output layer with no new features to show for it. And it's not like I have the time, with everybody currently wanting to expand their online stores... If anything, I'd put that on the list for version 1.0 as a summer/fall project since it'd be a breaking change either way. If you definitely need this and need it soon, I'm happy to accept a pull request. But why would you want to re-use a dashboard panel in another module? That doesn't make sense to me. The way I see a dashboard working is the other way around: it displays a condensed form of information found elsewhere, e.g. shortcuts from all possible admin views, a single chart from a whole host of data, the most recent news pages from a whole archive of them, and so on. If anything, you'd re-use a fieldset from one of your modules in the dashboard. Using markup from an existing module in a dashboard panel is working just fine — with the exception of granular access control and conditional visibility. Which to me seem minor but might be a deal-breaker for more corporate-y types of applications.
  28. 2 points
    You can use a hook to redirect after "Save & Exit": // the hook in a location like _init.php or in a module's init function $this->addHookBefore('ProcessPageEdit::processSaveRedirect', $this, 'redirectAfterSave'); /** * redirects to the main ListerPro "Raumdatenblätter" after saving a page with template raum * @param HookEvent $event * @throws WireException * @throws WirePermissionException */ public function redirectAfterSave(HookEvent $event) { $url = $event->arguments(0); $page = $event->object->getPage(); if ($page->template == "raum" && !$page->isTrash()) { if ($url == "../") { $goto = wire("pages")->get('/raumdatenblatt/raumdatenblaetter/')->url; $event->arguments = array($goto); } } }
  29. 2 points
    In case you're using Page Autocomplete for the inputfield, this might be related: https://github.com/processwire/processwire-issues/issues/550. Either way, you'll likely have to switch from "custom find" to "selector string" and include "check_access=0" in your selector to get this working 🙂
  30. 2 points
    During testing of the https://processwire.com/talk/topic/22847-processwire-dashboard/ module I've created this simple demo inputfield to show how Inputfields can be used as presentation blocks in ProcessModules. The result is this little inputfield that shows the getting started chart of chartjs: https://www.chartjs.org/docs/latest/ https://github.com/BernhardBaumrock/InputfieldChartDemo It comes with 2 ProcessModules 1) One single chart inputfield 2) Grid Demo Creating an Inputfield is really nothing more than creating a module file having 3 methods: <?php namespace ProcessWire; class InputfieldChartDemo extends InputfieldMarkup { public static function getModuleInfo() { ... } public function ___render() { ... } public function ___processInput($input) { return false; } } Place this in /site/modules/YourModuleName, name the class exactly the same as your folder and you get an installable Inputfield that you can use everywhere in your admin and share across projects! Creating a ProcessModule is also very simple (see this old post): You do even need only 2 methods in this module! <?php namespace ProcessWire; class ProcessInputfieldChartDemo extends Process { public static function getModuleInfo() { ... } public function execute() { ... } } Using these internal tools it is really easy to create totally tailored user experiences for your clients in the PW backend!
  31. 2 points
    This sounds great, even though I don't use trello 🙂 A short screencast would be great to get a quick impression 🙂
  32. 2 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/
  33. 2 points
    Oh my... I loved Textpattern so much back in the days. I used to use it for everything and it was a joy. Then... as projects became larger and more complex I found ProcessWire. I migrated all my sites over and it was pretty easy - at least in my case. First of all I migrated all the templates for sections and articles over. Rebuild the logic like posts per pages, custom article views, listings and those things. It took a while because ProcessWire was still new to me then. But after that it was pretty easy. I created custom templates to create CSV exports of all my content (maybe a total of 300 pages and 10 sections). Afterwards I imported everything from my CSV files, put everything in place, created lots of redirects and done. The one thing that was quite work intensive... image migration. I did it for each and every site manually. Wouldn't be a problem today but at that time I wasn't that good in handling files. 🙂 ProcessWire modules I used: https://modules.processwire.com/modules/process-jumplinks/ https://modules.processwire.com/modules/import-pages-csv/
  34. 2 points
    Found the solution 🙂 /** * Modify submit button on doc-import pages */ $wire->addHookAfter('ProcessPageEdit::getSubmitActions', function(HookEvent $event) { $page = $this->pages->get($this->input->get('id')); if(!$page->id OR !$page->template == 'docimport') return; $event->return = []; }); $wire->addHookAfter("ProcessPageEdit::buildForm", function(HookEvent $event) { $form = $event->arguments(0); $page = $this->pages->get($this->input->get('id')); if(!$page->id OR !$page->template == 'docimport') return; $s = $form->getChildByName('submit_save'); $s->value = 'Import starten'; $s->icon = 'download'; }); 🙂 Does anybody know how I can remove the dropdown items from the page edit submit_save button? As I didn't find a solution quickly I wanted to replace the button entirely, but this results in the following markup: $wire->addHookAfter('ProcessPageEdit::buildForm', function(HookEvent $event) { $form = $event->arguments(0); /** @var InputfieldForm $form */ $s = $form->getChildByName('submit_save'); /** @var InputfieldSubmit $s */ $form->remove($s); }); This hook results in this output: I could hide this markup via CSS but I'd prefer a clean solution 🙂 Thx!
  35. 2 points
    Not me. It sounds like a recipe for headache, frankly speaking. It really depends on lots of things... You should tell us more about your current site. What does it do? How complex is it? How many templates do you have now? How dynamic is it - or needs to be in the future? (for visitors and editors) How much functionality is there currently in terms of users interacting with the site (register, login, user profiles, voting / commenting....) ? Is it really just a "brochure" site (mostly static content for frontend-users, but manageable by editors) ? Or really more like a web-application? A redesign is not the same as porting content from CMS A to CMS B. If the site architecture will most likely remain, then I'd talk to the client and persuade them to allow budget to transfer the entire site in one go from Textpattern to PW (using the same frontend markup). In the long run, this would probably be more efficient. Once everything is running in PW, you could then later discuss about a redesign.
  36. 2 points
  37. 2 points
    Since get_magic_quotes_gpc returns FALSE from PHP 5.4, the installer line $value = get_magic_quotes_gpc() ? stripslashes($_POST[$field]) : $_POST[$field]; safely could be replaced with $value = $_POST[$field]; (assuming you are not installing on a legacy platform)
  38. 2 points
    For those who are interested, here is an explanation of why: https://www.php.net/manual/en/function.strtotime.php#92600 You need to add either the day or the year to the month to get it to work correctly. There are also some alternative fixes listed in this thread: https://stackoverflow.com/questions/3283550/convert-month-from-name-to-number
  39. 2 points
    v0.1.1 released with support for Repeaters and comma as decimal separator. Thanks @David Karich!
  40. 2 points
    I've used this library with success to import products or update them regularly like on a cron job: https://github.com/donutdan4114/shopify Takes care of rate throttling too which is nice!
  41. 2 points
    Yes, of course ... check the documentation page, you can get all or just one product, create a new one, modify it or delete it etc. PRODUCT: https://shopify.dev/docs/admin-api/rest/reference/products/product You can do this simply using WireHttp, I think if you want to add much more information to the product than Shopify allows or to relate it directly to other PW pages, then it makes sense to have a copy in PW and keep the synchronization between them, but if you only want to display products in a section of your website like a regular store only for selling, then you can simply query the API from your template file and process/display the answer on your website. When you check the DOC page you will see very clear examples of how to use the queries, you will see that you can use filters, and the answer is JSON that you can easily manipulate in PW. For the synchronization issue you can export the list of products to a CSV file and import it in PW, in my tests I used Ryan's module and it worked perfectly. Shopify also has Webhooks that allow you to update PW from Shopify according to events in the store such as new product, modifying or deleting it, new order etc. WEBHOOK: https://shopify.dev/docs/admin-api/rest/reference/events/webhook In other words, there are many ways to interact with Shopify and they are all very simple, well.. it seems to me, that I'm a graphic designer and not a professional programmer.
  42. 2 points
    Do you know if there's a way to query some Shopify API to get all the IDs and titles of products that exist in the Shopify store? So that a client only needs to maintain products in Shopify but the PW site could run a cron job where every day it gets all the product IDs and titles and automatically creates pages for them?
  43. 2 points
    The best educational videos on covid-19 I have yet seen:
  44. 2 points
    no problem at all. You gave me an idea actually, maybe we could try ProFields:Tables and setup a simple set of fields for each form element–might contrains the types of inputs you could use but might be a start... maybe wth a set of defaults that can be stored somewhere else.
  45. 2 points
    I needed to create some Fields and Templates via API and it was always a pain to get the right settings (like columwith, field context settings and so on). With the brand new (and ALPHA) RockSVN Module you can create your fields via the backend and then show a diff of your changes. Please see the comments on top of the module for todos and limitations. I'm not totally happy with the diff tool, so if anybody knows a better one or knows ho to change the behaviour to line-based diff (that would be better in this case i guess) feel free to comment. As @ryan is using the same diff tool in ProDrafts i guess there's not too much hope... anyway - i think the module can be a big timesaver and also help you to keep track of changes - an often requested feature and maybe also a good companion for @LostKobrakai s Migrations module! (Benjamin, jump in ) The module will create some Fields, Templates and Pages for you. All properly tagged and hidden, so it should not mess up things more than needed. Caution: Currently the module removes all those pages, templates and fields on uninstall! Requires my new basemodule called RockTools RockSVN.zip
  46. 2 points
    Hello @CalleRosa40 and @Brian Williamson! And thanks for the notice! The logic with EMO insert changed at 1.2.x update and I haven't got time to push the update yet so in a meantime please use the version 1.1.1 instead as it works without any issues. I'll try to find some time to fix the script insert to head ASAP! https://github.com/BlowbackDesign/EmailObfuscation/releases/tag/1.1.1
  47. 2 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.
  48. 2 points
    That's right, currently the W3C does not validate. @gebeer also mentioned this with the possible solution to use "text/plain" instead of "optin". I'm planning to implement this solution, but as an optional addition to keep backwards compatibility for the users who already use the "optin" variant.
  49. 2 points
    From Tracy's Captain Hook panel:
  50. 2 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/
  • Create New...