Popular Content

Showing most liked content since 02/15/2018 in all areas

  1. 14 points
    This version expands upon our recently introduced Focus Point selection feature for image fields by adding zoom support to the mix. This version also continues resolving GitHub issue reports as other recent dev versions have, while we work towards a release candidate for ProcessWire 3.1. https://processwire.com/blog/posts/pw-3.0.91/
  2. 13 points
    Yep, well took a bit longer reading the doco, experimenting etc and my site was already live. Now I know how to do it, will only take 15 minutes next time. Steps: Create your icons. I only had up to 256x256px. That's old hat. Now you need up to 1024x1024px. Decided to go with my existing website/app icon set anyway. Go to http://www.manifoldjs.com/generator and fill in the blanks Generate the files, download the kit, edit the files and/or your PW template(s) required and upload to the root directory, not /site/ directory, of your ProcessWire site Woohoo!!! Works great with a couple of provisos: The online builder does not work for Mac, iOS and Windows 10 devices, only everything else. Found it somewhat ironic it lacks Windows 10 support as this is a Microsoft product. No surprises there! For Mac, iOS and Win10 you have to use the PWABuilder CLI, almost formerly ManifoldJS CLI as it's going through a name change. Would be ever so grateful to anyone who can tell me how to do that. Followed the instructions to the letter, and also multiple variations, and could not get the CLI version to install/work and I definitely have the latest versions of Node and npm. PWABuilder delivers a manifest.json file and a couple of basic service workers, without all the fuss associated with SPAs, REST APIs etc, for small, informational websites. Watched a video recently that amongst other things, stressed PWA != SPA. Took me a while to get that. (Tip: skip the ads) While not yet perfect, PWABuilder was a good introduction for me to PWAs for ProcessWire.
  3. 12 points
    Code Blocks Textformatter is a tiny Textformatter module I cooked up to add support for code blocks to text/textarea/RTE fields on some of the sites I work with. Unlike a full-blown Markdown Textformatter – which is something that we already have in the core – this module simply adds support for fenced and inline code blocks. The syntax is based on the GitHub code block documentation, so please refer to that for additional instructions. The README at GitHub also includes some basic examples. As with any Textformatter, in order to enable this one, install it and enable it via field settings. Note that there's no syntax highlighting built in (at least for the time being), so use a tool of your choice for that – personally I prefer Prism.js. Since this module doesn't use a Markdown tool behind the scenes, but rather some home baked regular expressions, there's always the possibility that I've missed something – but please let me know if you use this module and run into any issues. On the other hand this module should be relatively fast and unobtrusive, as there are no unnecessary bits of code to run GitHub repository: https://github.com/teppokoivula/TextformatterCodeBlocks Modules directory: http://modules.processwire.com/modules/textformatter-code-blocks/
  4. 10 points
    I am happy to present you the first processwire powered page i made for a client. Some more in the pipeline, but on hold because of missing content on the client side Big thanks to this helpful and great community!! https://feuerwehr-gimbsheim.de/ my own site webgestaltung.net is online for a while already, but not holding much content yet.
  5. 8 points
    I discovered Swoole via a Quora answer to the (silly) question "Will PHP die in 2018?". https://www.swoole.co.uk/ https://github.com/swoole/swoole-src It's way above my skill level so I only have the vaguest grip on what it's all about, but it sounds pretty wild. Just thought folks here might be interested in checking it out.
  6. 7 points
    Hey all, A while back I was trying to get Processwire working on the Homestead vagrant box - a really handy vagrant box made by Taylor Otwell (Laravel creator). One cool thing about homestead is it has its own config file where you can set 'path maps' which map a folder on your computer to the vagrant box, and then also set up hostnames. So for example you can set up 10 domains pointing to different locations on your machine, making it a nice all in one vagrant development box for your sites. One thing it didn't do was support processwire. The way it works is it uses setup files for each site, and you can specify things like a site to use nginx, a site to use apache, etc. So to get round this I wrote a custom setup script for it to get processwire working, and it works really well. I've put it up on github should anyone else find it handy, it's a pretty simple little script and is based on the Laravel one included in Homestead. Hopefully it'll be useful to someone out there You can grab it here: https://github.com/rickmills/homestead-processwire
  7. 7 points
    Mastering PHP Design Patterns book from Packt Publishing is free for the next 22 hrs (as of time of posting) https://www.packtpub.com/packt/offers/free-learning
  8. 6 points
    Hmm, why? Do you have an upcoming project? Although we are in 'Off Topic', I don't get the point of starting a new thread instead of 'continuing' the discussion (if there is one), using the existing threads:
  9. 6 points
    Did you have read this? https://processwire.com/blog/posts/multi-instance-pw3/
  10. 5 points
    Not a question, but just something I discovered that I wanted to share on the forum since I haven't seen it discussed anywhere. If you are familiar with the "autojoin" option on individual ProcessWire fields, enabling this feature means that every time a page with that field on it is loaded into memory, the field will be included with it immediately. (Normally just the page's name and meta data is included, and getting a specific field from the page requires a separate trip to the database. This is to conserve memory) Normally this is fine and it keeps things simple, but occasionally you may be loading a lot of data in a consistent fashion (for, example, to populate a table) and know exactly which fields you need. With the autojoin option on fields, you would have to enable autojoin for all pages at all times, which you probably don't want. With the following code, you can do a $pages->find() and specify exactly which fields you want to autojoin with it: $pages->find("template=whatever", ['loadOptions' => ['joinFields' => ['filed1','field2','field3']]] ); I tested out in debug mode on one of my projects, and it seemed to significantly reduce the number of SQL queries required for an html data table I was building. Hope that helps someone!
  11. 5 points
    You should try the Admin on Steroids module... I only scanned your post quickly, but I guess most of your wishes would be fulfilled with it. It's one of my "must-have" default modules that I install with every new PW instance.
  12. 5 points
    There's no reason to feel sorry, we're a helpful bunch here On a sidenote: you can try the "PW custom Google search engine" I've configured some time ago: https://cse.google.com/cse/publicurl?cx=013706179141317928628:dendm4c3gpq I have used the title of this forum thread ("Restore trashed page from API") and the first result in this very thread here, and the second one is the API reference page for trash - at the bottom you'll see "related" API links, one of them being "restore". I have bookmarked this custom search so I can simply type "PW", hit enter, and search across a variety of PW-sites/resources. edit: kongondo was faster
  13. 5 points
    // Grab a page from the trash and restore it $trashedPage = $pages->get(1234); $pages->restore($trashedPage); http://processwire.com/api/ref/pages/restore/
  14. 5 points
    // inside a class e.g. modules $this->addHookAfter('Pages::trash', $this, 'myHookMethodName'); $this->addHookAfter('Pages::delete', $this, 'myHookMethodName'); public function myHookFunction($event) { // ... } // outside a class e.g. inside ready.php or templates wire()->addHookAfter('Pages::trash', null, 'myHookFunctionName'); wire()->addHookAfter('Pages::delete', null, 'myHookFunctionName'); function myHookFunction($event) { // ... }
  15. 4 points
    Hi @Ivan Gretsky Sound good to me, look like I have some work to be done! Tables are simply dropped if they exist.
  16. 4 points
    Yes, do not hesitate to share your result, try to make your best and we will try to send a Pull Request on Github ✨ PS: I forgot to send my post. I modified the module to bypass confirmation, if you wanna try and report back, rename your LoginRegister folder to .LoginRegister, then extract the zip in place of the original one in site/modules, refresh modules and check the box in the module's admin. File : LoginRegister.zip
  17. 4 points
    When $config->debug is true, you can read all fieldnames when hovering the arrow in the top right of every field. This is possible with plain PW.
  18. 4 points
    Its not exactly what you are looking for, but do you know the „Tracy Debugger“ Module from adrian? with this Module you can See all fields with names on the page (And many many other things) i think its a must have for processwire developers
  19. 4 points
    I have put it here for the moment: https://github.com/adrianbj/FieldtypeMapMarker/tree/add-address-components If more of you start wanting this, I guess I'll try to get Ryan's attention
  20. 4 points
    ahem... don't you want to use camelCase? preventDeletionLastEvent would be more readable than preventdeletionlastevent -> https://processwire.com/api/coding-style-guide/#4.6-methods
  21. 4 points
    Here's one way to enforce only a single featured item while still enabling featured status to be set while editing an item (as opposed to using a Page Reference field on some other page to select a single featured item). In /site/ready.php... $wire->addHookBefore('InputfieldCheckbox::render', function(HookEvent $event) { $inputfield = $event->object; if($this->process != 'ProcessPageEdit') return; $page = $this->process->getPage(); // If this isn't the existing featured item... if($inputfield->hasField == 'featured' && $page->template == 'news_item' && !$page->featured) { // Add a note about the existing featured item $existing_featured_item = $this->pages->get("template=news_item, featured=1"); $inputfield->description = "Only one item may have featured status. Featuring this item will un-feature '$existing_featured_item->title'."; } }); $pages->addHookAfter('saveReady', function(HookEvent $event) { $page = $event->arguments(0); // If the "featured" checkbox is checked... if($page->template == 'news_item' && $page->featured) { // Remove the featured status of any other items $existing_featured_item = $this->pages->get("template=news_item, featured=1"); if($existing_featured_item->id) $existing_featured_item->setAndSave('featured', 0); } });
  22. 4 points
    @andrew24, Moderator Note Please consider this your first and final warning against spamming in these forums. This forum is for ProcessWire jobs. You had hidden a link to your non-ProcessWire CMS behind your email address. I have removed your email and the said link.
  23. 4 points
    Interesting discussion about extra address fields. I created a fieldtype 'AddressGeoNames' that consists of separate text inputs for country, city, postcode, lat, lng etc. where field values are verified and partially auto populated through geonames.org API. This is a standalone Inputfield that geocodes through the google maps api. But it can also be connected to an InputfieldLeafletMapMarker field so that the given address will be rendered as pin on the map. The pin can also be manually repositioned and writes back lat/lng to the AddressGeonames field. I am currently using this in one live project with about 1500 users and they seem to get along fine with data input and geocoding. This is how it looks like when used next to a InputfieldLeafletMapMarker field: Planning on adding support for GoogleMapsMarker, too and eventually releasing it on github. Not quite ready yet, though. But if anyone is interested in the concept, I could share what I have so far.
  24. 4 points
    Hi! Look repeater. It's already installed in core. Good luck!
  25. 4 points
    Hey everyone! It's been a while since I last had a time to work on this module. But now I finally managed to focus on this module. So here are the latest updates. The codebase of the module grew very big and the more features I added the more time I had to spend to make sure the changes I made does not break anything. Because I had to manually verify if everything works as expected. After long night hours of trial and error I managed to setup tests for this module. Tests will help us quickly add/remove features as needed, because now there is no need for manually verifying all edge cases. Also I setup the Travis-CI so people can contribute more confidently and I can merge pull requests without worrying! There are already bunch of tests, but there is still some I'll be adding. 🎉 🎉 I will add some documentation on how to run tests locally in github wiki pages soon and let you know here. Another thing to note is that the master branch of our module no longer tracks the vendor code. This means that if you download the master branch and put it into your /site/modules directory it will not work. Instead you should use release builds that are a cleaned version of the module. It includes required vendor codes and does not have extra files that are not relevant to ProcessWire. Like presentation gif images, test files and so on. This makes the module size smaller!
  26. 3 points
    Yes it was planned to be done in first instance trough FTP protocol. Horst had give me some code to work with but since 2 months I am so busy with my works that I didn't found the time to try it. But this feature is definitely on the top of the todo list.
  27. 3 points
    Good day, @flydev! It's been a while science beta testing phase. Really glad the module is now released and gathering all the attention it deserves! May I propose a little enhancement that seems reasonable to me and just may be of use to others? I am using Duplicator to quickly create a local dev environment for a site (just not to practice cowboy coding straight on the server). When I do so the installer overrides the db settings in config file. It seems like there is not an option to later copy a locally produced package back to production and replace the installation from the admin. One has to remove all the files (and probably drop all the tables in the existing database) and run the installation "from the clean slate". And one has to remember and fill the production db credentials. Bit we could have an option to put the db credentials in the config-dev.php file instead (for local installation) and another one to remove config-dev.php from the installation if needed (for "back-to-production" installation). P.S. While writing this I realized I do not really know what happens to the existing db tables if the db is not empty. Are the being dropped?
  28. 3 points
    A few more enhancements: It now handles local links with query string parameters - the stored link is still converted to a page ID with the query string appended. You can now also paste full http(s) links and if these are local links, they will be converted to a page ID and a local link will be returned when the value is requested.
  29. 3 points
    Well, I am using this field for the first time and really wanted this functionality, so decided to fork the module here: https://github.com/adrianbj/processwire-fieldtype-assisted-url It doesn't look any different from the users perspective, but on save/sleep it stores the page ID instead of the url and then on wakeup it converts to ID back to the URL. This means that you can now move a page to a different parent, rename it, etc and the link URL will be automatically updated. It doesn't look like @wumbo is still active around here, so not sure if this will make it into the main version of the module, but it's there if others want it.
  30. 3 points
    @MarcoPLY You have to call the module by using an ajax request in order to avoid the redirection when the user click. In the following example, I am using jQuery (I'm lazy) and the modal script from w3c and a new template LoginRegister.php for the example : Code of the template : JavaScript code :
  31. 3 points
  32. 3 points
    The GDPR was approved two years ago, so how much more grace period should there be? As with each new law it's not going to come with any set of "best practices". They'll be worked out as the first lawsuits are held and concrete situations will be applied to the rules. There just isn't anyone out there to really finally interpret written law into concrete ways of handling thing besides judges in a lawsuit. It's a bummer that the ePrivacy rulings, which are supposed to go more into detail in the enforcement of gdpr in the digital world are still in the sad state of being nowhere near final. There are also various sources reporting that the ePrivacy laws won't be able to come into action until mid 2019 based on what is still to be approved by the EU and it's member countries. That might be the case in places, but as the GDPR is enforced for each company working with data of european citizens it's going to hit almost any globally active company as well as european ones. E.g. AWS is already claiming that they're gdpr compliant. For heroku I didn't find conclusive info, but salesforce (which owns heroku) does have extensive information on gdpr and how to comply when using their service. So if US companies want to make money in europe they'll have to deal with compliance.
  33. 3 points
    No worries . Btw search tip: Use this one instead: E.g., searching for restore trash page or restore trash page api returns $pages->restore() as the second result and your question as the fifth .
  34. 3 points
    I wonder why you need something like this in the first place "to have at least one date". wire()->addHookBefore('Pages::trash', null, 'hookTrashDelete'); wire()->addHookBefore('Pages::delete', null, 'hookTrashDelete'); function hookTrashDelete($event) { $page = $event->arguments("page"); //prevent deletion of last child $preventTpls = [ 'single-date', 'single-event', 'single-business-vacation', 'single-special-business-hours' ]; if(in_array($page->template, $preventTpls)) { preventDeleteDateEntry($event, $page); } } function preventDeleteDateEntry($event, $page){ if($page->parent->numChildren() === 1) { $event->replace = true; // now original function won't be called wire()->warning(__("Deleting of the last date is not allowed. There must be at least 1 date.")); } else { wire()->message(__("1 date was deleted.")); } } I would code it like this. So the hook could be used for different things. Also some code formatting for better reading. Use $page->numChildren(), in case you have thousands/millions of children you'd get a server out of memory Don't use $event->return = error.
  35. 3 points
    I recently started to build Vue SPAs with ProcessWire as the backend, connected with a REST API. Thanks to code and the help of @LostKobrakai (How to use FastRoute with ProcessWire) and @clsource (REST-Helper) I got it up and running pretty quickly and now have put all of it in a site profile for others to use. It includes the REST API with routing for different endpoints, JWT Auth and a simple Vue SPA which shows the process of logging in a user (nevertheless, you don't have to use the Vue part, the API will work on it's own). Check it out here: https://github.com/thomasaull/RestApiProfile I'm pretty sure, it's not the perfect or most sophisticsted solution, but it gets the job done for me… Feedback or Improvements are very welcome
  36. 3 points
    I built a simple cart system using JS + Local Storage; works perfectly and the cart contents last a long time; This is for visitors to collect swatch samples and then be able to request those samples in a form; there is no ecommerce in this case, but once you have the cart, it shouldn't be hard to use that data to interact with a 3rd party payment system.
  37. 3 points
    I've done a simple cart functionality with sessions. Works great. However, if you want to keep the infos longer than the browser session, you should use cookies instead. One thing to consider, however (mainly from a usability POV): Users tend to switch devices constantly. They browsed the product catalogue yesterday on their laptop, and want to continue browsing your site today on their tablet or phone. If you don't want to use registration / login, you could implement a simple bookmarking feature: Let the user create an individual bookmark (URL) for his selection, so he can continue on another device and even with another browser. This could also be used as a feature for wishlists, or product comparison tables which have become standard features in today's e-commerce world.
  38. 3 points
    for the most part, the hidden field option i think is best, but does take some logic and page saving; If you do want to have them be virtual, then you can do a hook wire()->addHookProperty('Page(template=product)::rating', function($event) { $product = $event->object; $event->return = $product->points / $product->votes; }); but you will be limited to in-memory selection, since the property is not in the database
  39. 3 points
  40. 3 points
    don't know if this site was already posted or where they get their data from, but maybe it is interesting for someone: https://trends.builtwith.com/cms/ProcessWire/Market-Share
  41. 3 points
    That's the whole point of this thread I don't think there necessarily needs to be a plugin for outputting legal stuff. Considering the basic contact form, there should be a privacy policy page somewhere that describes what happens to the data, and we have some guidance for writing that up here: https://ec.europa.eu/info/law/law-topic/data-protection/reform/rules-business-and-organisations/principles-gdpr/what-information-must-be-given-individuals-whose-data-collected_en. But that's our clients' responsibility, not ours. Of course, this will vary greatly from site to site. It's not the same as the cookie consent message. The company has to describe exactly what they will to do with the information and how long they'll keep it. We should also add the "I accept the terms of this site's privacy policy" checkbox on any forms that ask for private data, and the words "privacy policy" linking to the page where it's all described. There shouldn't be a problem stating that the form submits the data to our email for appropriate response, that no data is stored permanently on our servers, and should you require the right to be forgotten, please submit your request to the email xxx. This and all the rest that's stated in the link above. But so far this isn't more than a disclaimer and examples will start popping up everywhere on the web in no time. What worries me more is when the data stays in our PW. If the server is hacked and info is leaked, there can be an investigation that will evaluate how careful we were with the way we've built the site. They mention database encryption, security by design, and keeping the data for the least possible time. For me this is where one or two new modules may come in handy. Not keeping the CMS updated can theoretically burn someone. Example: We have a jobs form that stores a user's CV. In a year that CV will be outdated and would serve no use. A module that automatically manages that content's (page) date of expiration and deletion could be useful. Another example: A site that has a private area that a user can register to gain access to. After X months without logging in, the data is deleted. Maybe even notify the person that it will happen unless they log in before day X. Doesn't sound too complex to do. Now, security by design... I'm clueless. I saw a mention of stuff like scattering personal data in more than one DB and only by comparing a blind ID you can tie the info together. I can see the coolness, but can't see it as something viable for smallish sites.
  42. 3 points
    And that is why companies will not be able to fully comply even if they wanted to. Most people cannot even find an old email, they do not properly know how Outlook works, and on top of that they use Windows, the most hackable widely used OS on the planet. So now what? While the intention of GDPR is OK, it has been written by lawyers who live in their dream world not knowing anything about IT. Do they care if they ask the impossible? Of course they don't. Anyway, we need to do our best, so I propose to start writing a module that helps generating the legal stuff (privacy policy, etc...) that must be outputted somewhere so we do not have to reinvent the wheel. For other systems people are already writing plugins that test the CMS and look for possible issues, eg: https://www.opencart.com/index.php?route=marketplace/extension/info&extension_id=32993&sort=date_added https://wordpress.org/plugins/tags/gdpr/ I guess none of us wants to spend a lot of time on it, so why don't we help each other?
  43. 2 points
    Thank you @flydev! Yes this it's other option and works. You put me again on the right way, thank you! Only I have to load just a part of the page, the form in #LoginRegister. So I have did this: $.ajax({ url: './', // target url (selff here) type: "get", // GET because LoginRegister use GET variables data: 'register=1', // url param success: function(data){ $('#LoginRegisterDiv').html($(data).find('#LoginRegister').html()); }, }) About the module, now it asks to be confirmed before activating the account. It's possible pass this function? and make active the account after the registration, and maybe just add a confirmed screen for let be more clear. Thank you flydev, you help me a lot!
  44. 2 points
    Hi guys, sorry for the delay in replying. I am going over the following details from this thread and will post an update ASAP: Install issues - blank file path, notices. UIKIT theme CSS conflicts. returning data on non-recurring events all day toggle render methods and output overrides. As soon as I have an update, I will post it here to the forum.
  45. 2 points
    Forgot to show where $forum is defined in your example code? Would be good to show the complete, correct code to help others, thanks.
  46. 2 points
    $bool = $user->isLoggedin(); https://processwire.com/api/ref/user/is-loggedin/
  47. 2 points
    Yep, that's how it is often. Also I tried to bookmark all interersting stuff (with several systems of subfolders), it ever ended up unusable, just because of the amount of bookmarks collected by the time.
  48. 2 points
    Quote from page 9 of the book: "Technical debt, the eventual consequence of poor system design, is something that I've found comes with the career of a PHP developer. This has been true for me whether it has been dealing with systems that provide advanced functionality or simple websites. It usually arises because a developer elects to implement a bad design for a variety of reasons; this is when adding functionality to an existing codebase or taking poor design decisions during the initial construction of software. Refactoring can help us address these issues. SensioLabs (the creators of the Symfony framework) have a tool called Insight that allows developers to calculate the technical debt in their own code. In 2011, they did an evaluation of technical debt in various projects using this tool; rather unsurprisingly they found that WordPress 4.1 topped the chart of all platforms they evaluated with them claiming it would take 20.1 years to resolve the technical debt that the project contains."
  49. 2 points
    Here is my code for others who also deals with the same issue. This little function prevents the deletion of the last child page if page has a certain template. Code runs inside ready.php. //prevent deletion of last child function wire()->addHookBefore('Pages::trash', null, 'preventdeletionlastevent'); wire()->addHookBefore('Pages::delete', null, 'preventdeletionlastevent'); function preventdeletionlastevent($event) { $page = $event->arguments(0); if(!in_array($page->template->name, ['single-date', 'single-event', 'single-business-vacation', 'single-special-business-hours'])) return; $parent = $page->parent; $childrennumber = count($page->parent->children); if($childrennumber === 1) { $event->replace = true; // now original function won't be called $event->return = wire()->warning(__("Deleting of the last date is not allowed. There must be at least 1 date.")); } else { wire()->message(__("1 date was deleted.")); } }
  50. 2 points
    By the way, has anyone seen a website that already takes steps to comply with this? I'm seeing a page for a webinar on the subject with a registration form and no consent warning or even privacy policy link anywhere. I'm clicking google ads for companies selling consulting services that don't seem to have anything in place either.