Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/14/2018 in Posts

  1. Easiest, fastest, most reliable framework. Considering my workload this past weeks, I'm considering on switching. It supports a wide range of applications:
    12 points
  2. I just want to remind everyone that we have established guidelines that need to be adhered to on the Forum. If you have forgotten what the guidelines are, please take some time to review them again. es
    6 points
  3. 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!
    5 points
  4. Not sure if anyone is interested, but I just extended this to support address component fields. Now you can enter the various address components individually and it will automatically populate the final combined address field and geocode the address to lat/long. I wanted this so I could grab the individual components for displaying a business address in a specific format, rather than relying on what the site editor entered into the combined address field. You can of course call the components like this: $page->address->street $page->address->additional $page->address->city $page->address->state $page->address->postcode $page->address->country These are in addition to the existing: $page->address->address // the combined version $page->address->lat $page->address->lng $page->address->zoom Is anyone interested in this version? Not sure if @ryan would accept a PR or not?
    4 points
  5. $key = $wireArray->getItemKey($item);
    3 points
  6. Markup Cache for products cards, some static parts of pages and WireCache for searches. https://processwire.com/api/ref/cache/ Page cache and ProCache are options if you can implement ajax loading for dynamic parts, but definitely more work.
    2 points
  7. Hello again, folks. As my project is close to the end and I am on the stage of implementing schema.org markup, I decided to revisit my old post and share the code that suits my needs so far. So as previously mentioned, I am having numeric fields holding the prep_time & cook_time interval in minutes. I decided to have that instead of going to a text field and entering the values manually (1h 25min) as to standardize and unify the appearance in case different people would be allowed to share content. So here is my final code that I used to convert from minutes to X d Yh Zmin ZZsec (original source provided for further reference and explanations ) So far so good, however for the itemprop I needed to convert the fields values from minutes to ISO 8601 values that can be then populated. To do so, I used the following function: So to speak, if my prep_time field holds 75min, this would be converted to PT1H15M. If someone knows a shorter/more elegant way of converting minutes to days:hours:min:sec (eliminating the 0 values) and converting the time to ISO 8601 it would be great to hear about it P.S. Forgot to mention that the minutes-to-human readable timing function uses seconds conversion so in my template I call the function: <?php convert($page->prep_time * 60); ?> Not sure if it is the best way, but I know for sure it works
    2 points
  8. No way am I going to use a framework with such a truckload of unresolved issues
    2 points
  9. These topics might be of interest, especially Macrura's dashboard And this module (page list hidden by default)
    2 points
  10. It's aimed at protecting EU citizens' privacy and therefore I don't know if you'd be able to take a dispute to court. Yesterday I read somewhere that was the worry that storing info on the cloud could mean that it's not in a server within the EU jurisdiction. I bet this will mean companies like google and facebook are forced to have european users' data in a european datacenter and comply to these rules.
    2 points
  11. I guess I should do the same. It's just that Google is so convenient. I can see some benefits in having some introductory documentation that skips over the details. The earlier documentation was a bit like that and it's still useful. But for the v3 API Reference I think the more comprehensive the better. Having detailed and comprehensive documentation is not only useful to current users but it also boosts PW's credibility for potential users, particularly for experienced devs who I'm sure would find PW a pleasure to use and could make some valuable contributions to the community. The richness of the API is something we should show off rather than hide.
    2 points
  12. Today I had an idea and wanted to try out if that could work... A little later I had a little module as a working prototype and I want to share it with you to start some discussion: Idea: The idea is to have a simple interface that provides some helpers for copying/modifying/deleting elements in any HTML page. For now it is bundled to processwire but generally it would be possible to use this tool combined with any HTML that you provide. Why? I think that mockups can really speed up development and - maybe even more important - can also serve as a tool for better communication between us and our clients. There are several tools for this usecase but all that I know (like https://pencil.evolus.vn/ ) have a totally different look and feel than the final software has. So I thought why not use the look and feel of ProcessWire when developing something for ProcessWire? I've built some simple mockups sometimes with my browsers devtools and this works - but it is not really fast (and therefore not fun). Thats why I started this module today. Usage: After installation the module monitors your mouse and highlights all hovered elements inside the #main div. Then you have several keyboard shortcuts: c --> copy element r --> remove element arrow left --> previous sibling arrow up --> parent element arrow right --> next sibling arrow down --> first child e --> edit content with ckeditor ctrl + enter --> save edit Quite selfexplaining, isn't it? Roadmap/Vision: Save/Load For now the module does not save anything. You can modify content as you like and then do a screenshot, but of course it would be great to save your mockups somewhere. And continue work afterwards. Undo/Redo UI-Element Library It would be great to have a sidebar with common pw elements like inputfields and buttons to add via click to your mockup. Copy feature from other sites For example you could copy markup from any other website (like the UIKit docs) and paste that markup to your mockup. Or you could open another site in the pw backend that has UI elements that are similar to your needs and just copy them over. Use it with any HTML The module could be packed into a single JS file and then be used to modify any HTML content (like themes from themeforest or the like). This would be an awesome tool for creating quick mockups of any page, moving around elements, copying things, removing items, changing texts etc. Download: You can download the module here: https://gitlab.com/baumrock/RockMockup (have a look at the code, it's really really simple and everybody is welcome to contribute!) Use ProcessWire Kickstart for a One-Click-Installation: <?php $password = $this->randomPassword(); return [ 'pw' =>'https://github.com/processwire/processwire/archive/dev.zip', 'profile' => 'site-default', 'settings' => [ 'timezone' => 368, // vienna 'dbName' => 'yourdbname', 'dbUser' => 'root', 'dbPass' => $this->randomPassword(), 'admin_name' => 'youradminurl', 'username' => 'youradminusername', 'userpass' => $password, 'userpass_confirm' => $password, //'dbTablesAction' => 'remove', // overwrite existing tables? ], 'recipes' => [ function() { $this->msg('Installing RockMockup...'); $this->installModule('RockMockup', 'https://gitlab.com/baumrock/RockMockup/repository/master/archive.zip'); $this->succ('RockMockup installation completed'); }, ], ]; What do you think? Would you use such a tool? Do you maybe know any existing tools that do a similar thing?
    1 point
  13. I've been working on an experimental module set that adds 2-factor authentication to ProcessWire with the help of Steve Gibson's PPP one-time-pad system. This is split into two modules; a CryptoPPP library that implements the otp system and a 2-factor authentication module that uses it to add 2-factor authentication to ProcessWire. The 2-factor module adds an additional "Login Token" field to the login page into which the authenticating user will need to enter the next unused token from their one-time-pad. Pages from their pad can either be printed out in advance in a credit-card sized format (with codes being crossed out as they are used as shown here) or the required token can be sent to their registered email address so they don't need to print anything out. This second option requires a good email address be present in the user's account in order for them to be sent the token. Email Delivery To set up email delivery go to the 2-factor module's config page and choose "token delivery via email" and save the settings. Next, make sure that every user who will use the system has a valid email address set up in their account. Upon the first failed user login attempt, the required token will be emailed to the user’s email address and they should then be able to log in. Printing Pages From The Pad If you prefer to print the tokens in a handy credit-card sized format then… Go to your profile screen Expand the “PPP Initialisation Vector” field Hit the “Show Token Cards” button to open a new browser window with the next 3 useful cards Use your browser’s print option to print these out Trim them to size and store ...but make sure you print these out before you enable 2-factor authentication on your account. If you cross out your used codes, you will always know which code to use when logging back in -- and if you forget, the first login attempt will fail and the token field will then prompt you with the location of the correct code to use. Why would I ever want to use 2-factor authentication? If your site is only for you or for people you know use good passwords then you probably never will need a 2-factor authentication system. But it has been shown that many users use passwords that are, well, rubbish not very good and having a second factor can be useful in mitigating poor passwords. As the second factor in this system comes out of a one-time-pad system (meaning it will not be reused) then having the user's password leaked or guessed should not compromise their account nor will having someone spy out the token they are using to log-in as tokens are not re-used (well, not for a very long time.) Known Problems You need to hit the save button after you install the 2-factor module to get it to remember the initial settings. (I guess I'm not setting the defaults correctly at present but pressing the button will allow you to move forward for now) Uninstall of the 2-factor module leads to a lot of warnings. Attachments
    1 point
  14. Velotraum is a small German manufacturer, building rather costly, individually manufactured bicycles for both globetrotters and everyday bikers. We use RepeaterMatrix for long structured texts, and we use a lot of individual fields for metadata. We even built our own "preview" function for blog comments and included Textile light for blog comments, too. Have a look: velotraum.de
    1 point
  15. Hey community! Anybody worried about the new regulation? From May 25th on, we better start complying, otherwise there's an "up to 4% of the year's turnover or 20 Million euro fine, whichever greatest" hanging over our heads. Most my projects don't store any data and the forms only submit to email. I can't find any information regarding this scenario, but I'm guessing we'll need to add disclaimers in a privacy policy that clearly answers these questions: https://goo.gl/iczesa, and a checkbox for accepting the terms. I'm curious though about how something like privacy by design could be implemented in PW. Looks like it's time to send proposals to all our previous clients
    1 point
  16. @OllieMackJames, just a note about Page Reference fields: Where you have a "single" Page Reference field... ...when that field has a page selected its value is a Page object. So rather than this... /* fill in pageid of page to be used for content homepage*/ if($page->id == 1 && $page->page2use4homepage) { $p = $page->page2use4homepage->id; $page = $pages($p); } ...you can just do this... if($page->id == 1 && $page->page2use4homepage) { $page = $page->page2use4homepage; }
    1 point
  17. I really like this!! I just thought of using this module in the following case: I have some big configuration screens (in page edit screen) that I want to reorganize, so I thought of doing it with this mockup tool prior to actually editing fieldset/fielsettabs setup, get user to approve it and write the migration script (this same template configuration migrates to around 20 or so other sites). I also use PW's admin as dashboard for different types of applications (and try to use the API as much as I can) so mocking up all this stuff would be super useful for me, and the roadmap does seem too look like a perfect fit for the type of activity I do. (I was writing a big wishlist until i realised it was all on the roadmap :D)
    1 point
  18. Soma got one of the last Green Cards and moved from Switzerland to Atlanta? I must have missed a memo
    1 point
  19. There's a million ways to do something like this. An easy and straightforward way is to add a data-attribute (YYYY) to your campaign wrapper div. Then use a few lines of JS to hide every campaign year item except the selected one. Examples: https://www.sitepoint.com/jquery-filter-objects-data-attribute/
    1 point
  20. Whether I like it or not, I have to deal with this nonsense. Small sites have been fined in my country already for not having clear refund policies par example. What I do is have a contract with a third party who keeps all legal stuff for websites that are working in the EU up to date to EU laws. They tell me what kind of legal pages, privacy statements etc. etc. to have in place. They are also now working on checking what to do with the new privacy regulation. Once they have that ready, I'll just add or adjust what I currently have on my site. Of course this is not for free, but 80 euros or something around that order, is not too bad for some peace of mind. This is what I work with: https://www.webwinkelkeur.nl/ it is a Dutch site.
    1 point
  21. You have two good answers here Soma's answer on Adrian's link does more or less what you propose in your last pseudo-code.
    1 point
  22. I ended up with the following simple template since I was just looking for a csv export/ download option. It works without any errors for any kind of field (repeaters included) <?php // template provides file download of some children data in csv format // export as CSV if $_GET['csv_export‘] == 1 is in url if(isset($input->get->csv_export) && $input->get->csv_export == 1) { // create data array $data = $page->children->explode(function($item){ return array( 'ID'=> $item->id, // page property 'Author' => $item->author->first()->name, // page field 'Length' => $item->timeslots? $item->timeslots * 30 : 0, // integer field 'Info' => $item->info // runtime markup field ); }); // set header header("Content-type: text/csv"); header("Content-Disposition: attachment; filename=file.csv"); header("Pragma: no-cache"); header("Expires: 0"); $output = fopen("php://output", "wb"); foreach ($data as $fields) fputcsv($output, $fields); fclose($output); exit; } // display content of template with link to same page with appended csv_export=1 else { $page->_content = "<a href='./?csv_export=1'>Export Child Pages as CSV</a>"; //link to initiate export }
    1 point
  23. 1 point
  24. @adrian Thanks for that works prefect
    1 point
  25. @lpa 1) I'll look at the hierarchy you described in a minute 2) You can check if a page is protected by checking $page->protected eg: if(!$page->protected) { //show in navigation } 3) I have just made the message function hookable, so you will be able to put this is your ready.php file: $this->addHookAfter("PageProtector::getMessage", function($event) { $event->return = 'My custom message'; }); I'll commit this once I look at your first issue.
    1 point
  26. I expect you are changing the main default in the module settings. This populates the value on the Settings tab of the page that is being protected, but if a page has already been protected, you will need to change the value for that page. It allows for different messages for different pages. Does that make sense?
    1 point
  27. As before, you can't easily modify ProcessPageList for this purpose. But you can use Lister (Pages > Find). So in your case you would filter according to some parent or some template, plus filter by "title starts with" some character. I have a module under development that will allow for a list/tree that dynamically changes the selector used by Lister. Not sure when it will be ready but that might end up being helpful for your scenario.
    1 point
  28. I doubt it makes any difference if data is stored in an email inbox or on some webserver's database. The regulations apply to any data you store or process (storing and processing are clearly separated roles) if that's digital or analog or on post-its. To the contrary I'd even prefer the database in cases of form submits, because an email is easily forwarded to different people in a company and complying to a "request to be forgotten" can result in hunting down all the inboxes where submitted personal data are stored, while deleting a record in a db can be a lot easier.
    1 point
  29. No harm done of course but on mobile there's usually no "hover".
    1 point
  30. https://cse.google.com/cse/publicurl?cx=014789015761400632609:fxrf0rj4wr4 FTW
    1 point
  31. Nice. Did you build the configurator yourself, with PW too? http://wp10757029.server-he.de/konfigurator/public/index.php/konfigurator/konfiguration
    1 point
  32. Geil! Why the arrow icon when hovering the expanded mobile menu?
    1 point
  33. @Loges: Somewhere in the middle of my (unfortunately growing) todo list is a field encryption module (or, precisely, a whole set of them for different scenarios). The bad news is that it's been there for a while and regularly been overtaken by reality (speak crypto api changes, now a badly under-documented libsodium, breached algorithms, etc.) and I've been hesitant to roll out something that might not be future-proof. You should be able to implement something quickly though if you don't aim for a generic, fool-proof-in-any-environment solution. With PW's hooks api, you could even add encryption to existing field types like FieldtypeText and its descendants. Here's a short rundown of my thoughts that might get you started with your own module: Use symmetric encryption, store your key in a property in site/config.php, make sure to avoid insecure combinations like AES256 with ECB You need at a minimum the following hooks: FieldtypeText::sleepValue where you encrypt the field values for storage in the DB. Be aware that the value passed to that might either be a string or an array of strings (in multi language sites), each of which you need to encrypt. FieldtypeText::wakeupValue where you decrypt the db values for use inside PW. You get either a string value or a LanguagesPageFieldValue object (multi language sites) for which you need to decrypt the value for every language (use getLanguageValue/setLanguageValue). FieldtypeText::getConfigInputfields to add a property (InputfieldCheckbox) that determines whether to use encryption (and is checked inside sleepValue/wakeupValue) in the field's configuration Use a truly random initialization vector (IV) for encryption, which is, depending on PHP version and configuration, sometimes harder than it sounds. Of course, back up your encryption/decryption key really good
    1 point
  34. GDPR itself is mandatory, but there was a confusion about storing personal data in an encrypted way only as it was supposed to be necessary to comply. Being a European developer, I will spend a considerable amount of time to help my clients out with GDPR and I'm still learning the details... However, this encryption issue seemed to be a huge technical problem if it is mandatory. Since it is not, now I can concentrate on the other issues GDPR generates. I think this confusion about encryption was the biggest issue so I though I would post some links to show that is in a non-issue after all. There are good resources about GDPR about there, but here is a brief introduction to check out first: http://ec.europa.eu/justice/smedataprotect/index_en.htm Also note that: "Where does GDPR apply? If you sell any products to customers based in the EU, or have EU visitors to your site, you’ll need to make sure your site complies with GDPR. It applies to all 28 EU member states and to entities and organisations outside the EU when processing the data of citizens within it. IMPORTANT to note: Google Analytics and others ARE personal data collectors too! Eg: Statistics apps like cPanel apps, similar CMS plugins, custom solutions like Piwik", etc. And this means not European websites should also consider complying to avoid yet to be seen possible legal issues. The good thing is that the silly automatic cookie consent does not seem to apply anymore, as setting cookies is not data collection in itself. In GDPR there is only one sentence where cookies are mentioned: https://gdpr-info.eu/recitals/no-30/ And it is just about listing a few technical possibilities of possible personal profile building. However, if there is no profile building – meaning there is no data collection this way – then cookies are non-issues. I still need to read up on this one, but this is my current understanding. Of course, if cookies are used for profiling then it is a different story and they must be considered when dealing with GDPR. There is a lot to consider regarding GDPR. As you can imagine, complying is a time consuming process, a real PITA
    1 point
  35. Hi there. Not a complete answer, but first of all I'd suggest taking a closer look at this post, which has a link to an article hopefully resolving some worries regarding encryption of data: Other than what you've described above I don't have a rock-solid solution for you. I would assume that, as long as you're taking care of other parts of the regulation – such as breach reporting, removal of data on request, and so on – and you encrypt all traffic targeted at personal data (HTTPS), you should be safe. But then again: IANAL, so please don't take my word for it. I'm just assuming some common sense, really. With current technology it would be next to impossible to encrypt all personal data, while still collecting all the necessary data in the first place. Think of things like server log files etc.
    1 point
  36. Here is the text, in a gitbook; hopefully nothing too controversial... https://outflux3.gitbooks.io/why-choose-processwire/content/ If anyone wants to edit, feel free; Also, i want to add some images – screenshots of admin, some gtmetrix scores of really fast sites, and icons here and there (that are in the original but didn't make it to the gitbook).
    1 point
  37. Hi @adrianmak You can achieve this by using hooks and my ReCaptcha module. First install the MarkupGoogleReCaptcha module then in file ready.php, write the following code : /* * replace the LAST occurence of $search by $replace in $subject */ function str_lreplace($search, $replace, $subject) { return preg_replace('~(.*)' . preg_quote($search, '~') . '~', '$1' . $replace, $subject, 1); } /* * replace the FIRST occurence of $search by $replace in $subject */ function str_freplace($search, $replace, $subject) { $from = '/'.preg_quote($search, '/').'/'; return preg_replace($from, $replace, $subject, 1); } $captchamod = wire('modules')->get("MarkupGoogleRecaptcha"); wire()->addHookProperty('Page::captcha', function($event) use ($captchamod) { $event->return = $captchamod; }); wire()->addHookAfter('Page::render', function($event) { $template = $event->object->template; $page = $event->object; if ($template == 'admin' && !wire('user')->isLoggedin()) { $captchaScript = $page->captcha->getScript() . '</body>'; $captchaHtml = $page->captcha->render() . '</form>'; $event->return = str_freplace('</form>', $captchaHtml, $event->return); $event->return = str_lreplace('</body>', $captchaScript, $event->return); } }); wire()->addHookAfter('Session::authenticate', function($event) { $page = wire('page'); $template = $page->template; if ($template == 'admin') { if ($page->captcha->verifyResponse() == false) { wire('session')->logout(); wire('session')->redirect(wire('config')->urls->admin); } } });
    1 point
  38. If you need to use pagination (limit=XX) for the resulted pages you'd need to resort to something like this: https://github.com/ryancramerdesign/ProcessWire/issues/556 If you're not using limit in your selector I'd suggest using sort in the $pages->find() selector if possible and fall back to runtime sorting only if needed. Edit: The difference between find() and sort() is, that find() will sort results in mysql and therefore (in conjuction with limit) will only load actually displayed pages, whereas sort() does only sort pages in php (loaded to memory), which might draw a lot of performance if done on a large set of pages.
    1 point
  39. Too simple to be a module, consider a script like this: $array = $pages->find("template=basic-page")->explode(function($item){ return array( 'id'=> $item->id, 'title' => $item->title ); }); $fp = fopen('file.csv', 'w'); foreach ($array as $fields) fputcsv($fp, $fields); fclose($fp); Note, $pagearray->explode() used here is only available in 2.4 (2.3 dev) http://cheatsheet.processwire.com/pagearray-wirearray/getting-items/a-explode/ And the anonymous functions requires php >= 5.3 http://php.net/manual/de/functions.anonymous.php
    1 point
×
×
  • Create New...