Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/24/2020 in all areas

  1. New EMO version 1.2.0 released! https://github.com/BlowbackDesign/EmailObfuscation/releases/tag/1.2.0 In this version only encryption key is stored in the emo object of html document and crypted email strings as data attributes to span elements that are used to replace found email addresses. This makes it possible to obfuscate emails generated within AJAX request. There is also a new option at module config to lock the encryption key so that it does not change on every session like it does by default. This is required if you are caching AJAX output for more than session lifetime. Otherwise this option is good leave disabled. Here is quick example of a simple AJAX request with obfuscated output: <?php namespace ProcessWire; if($config->ajax) { $str = "<p><a href='mailto:foo@bar.com'>Click to mail</a></p>"; // auto obfuscation works only when complete html document is rendered so you // need to do manual obfuscation on AJAX calls even when mode is set to auto echo $sanitizer->emo($str); return $this->halt(); } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>EMO ajax example</title> </head> <body> <p>john@doe.com</p> <div id="result"></div> <p><button onclick="sendExample()">Show me some</button></p> <script> var sendExample = function() { var xhttp = new XMLHttpRequest(); xhttp.open("POST", "<?= $page->url ?>", true); xhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); xhttp.onreadystatechange = function() { if(this.readyState == 4 && this.status == 200) { document.getElementById("result").innerHTML = xhttp.response; // run emo init when there's something new to digest emo.init(); } }; xhttp.send(); }; </script> </body> </html>
    3 points
  2. I think you might have come up against this bug (https://github.com/processwire/processwire-issues/issues/511). If you think it is related, perhaps you could nudge Ryan on that issue as he seems to be ignoring my concerns on this, especially when it's a really easy fix.
    2 points
  3. How crazy is that piece of software called ProcessWire?? Exact matches are now possible using the string notation of date ranges. Writing this down and looking at the screenshot I realize that it would make a lot of sense to be consistant in the format when transforming a RockDaterange object into a string and vice versa. Amount of code necessary to support this? 10 Lines ?
    2 points
  4. I've kept hearing that one for the last twenty years, yet here we are. I think that's enough said ?
    2 points
  5. --- Module Directory: https://modules.processwire.com/modules/privacy-wire/ Github: https://github.com/blaueQuelle/privacywire/ Packagist:https://packagist.org/packages/blauequelle/privacywire Module Class Name: PrivacyWire Changelog: https://github.com/blaueQuelle/privacywire/blob/master/Changelog.md --- This module is (yet another) way for implementing a cookie management solution. Of course there are several other possibilities: - https://processwire.com/talk/topic/22920-klaro-cookie-consent-manager/ - https://github.com/webmanufaktur/CookieManagementBanner - https://github.com/johannesdachsel/cookiemonster - https://www.oiljs.org/ - ... and so on ... In this module you can configure which kind of cookie categories you want to manage: You can also enable the support for respecting the Do-Not-Track (DNT) header to don't annoy users, who already decided for all their browsing experience. Currently there are four possible cookie groups: - Necessary (always enabled) - Functional - Statistics - Marketing - External Media All groups can be renamed, so feel free to use other cookie group names. I just haven't found a way to implement a "repeater like" field as configurable module field ... When you want to load specific scripts ( like Google Analytics, Google Maps, ...) only after the user's content to this specific category of cookies, just use the following script syntax: <script type="text/plain" data-type="text/javascript" data-category="statistics" data-src="/path/to/your/statistic/script.js"></script> <script type="text/plain" data-type="text/javascript" data-category="marketing" data-src="/path/to/your/mareketing/script.js"></script> <script type="text/plain" data-type="text/javascript" data-category="external_media" data-src="/path/to/your/external-media/script.js"></script> <script type="text/plain" data-type="text/javascript" data-category="marketing">console.log("Inline scripts are also working!");</script> The data-attributes (data-type and data-category) are required to get recognized by PrivacyWire. the data-attributes are giving hints, how the script shall be loaded, if the data-category is within the cookie consents of the user. These scripts are loaded asynchronously after the user made the decision. If you want to give the users the possibility to change their consent, you can use the following Textformatter: [[privacywire-choose-cookies]] It's planned to add also other Textformatters to opt-out of specific cookie groups or delete the whole consent cookie. You can also add a custom link to output the banner again with a link / button with following class: <a href="#" class="privacywire-show-options">Show Cookie Options</a> <button class="privacywire-show-options">Show Cookie Options</button> I would love to hear your feedback ? CHANGELOG You can find the always up-to-date changelog file here.
    1 point
  6. Plenty of posts on the forum relating to Content Security Policy (CSP) and how to integrate it with Processwire. It's not too hard to implement a decent htaccess CSP that will get you a solid B+ at Mozilla Observatory. If you're after A+ it's a little harder because of all the back-end stuff... until you realize it's surprisingly easy. After a lot of testing, the easiest way I found was to specify only what is needed in the htaccess and then add your required CSP as a meta in your page template. Plenty of people have suggested similar. Works very easily for back-end vs front-end, but gets complicated if you want front page editing. Luckily, a little php will preserve back-end and front page editing capabilities while allowing you to lock down the site for anyone not logged in. None of this is rocket science, but CSPs are a bit of a pain the rear, so the easier the better, I reckon ? The only CSP I'd suggest you include in your site htaccess is: Header set Content-Security-Policy "frame-ancestors 'self'" The reason for this is you can't set "frame-ancestors" via meta tags. In addition, you can only make your CSP more restrictive using meta tags, not less, so leaving the back-end free is a solid plan to avoid frustration. Then in your public front-facing page template/s, add your desired Content Security Policy as a meta tag. Please note: your CSP should be the first meta tag after your <head>. For example: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Security-Policy" content="Your CSP goes here"> <!-- followed by whatever your normal meta tags are --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="format-detection" content="telephone=no"> If you haven't got Front Page Editing enabled, this works fine by itself. Just one extra step is needed to make sure you don't have to worry either way. The easiest way I found to allow both CSP and front page editing capabilities is the addition of a little php, according to whatever your needs are. Basically, if the user is a guest, throw in your CSP, if they're not do nothing. It's so simple I could have kicked myself when it finally dawned on me. I wish it had clicked for me earlier in my testing, but it didn't so I'm here to try to save some other person a little time. Example: <!DOCTYPE html> <html> <head> <?php if ($user->isGuest()): ?> <meta http-equiv="Content-Security-Policy" content="Your CSP goes here"> <?php endif; ?> <!-- followed by whatever your normal meta tags are --> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="format-detection" content="telephone=no"> If you want it a bit more involved then you can add additional tests and be as specific as you like about what pages should get which CSP. For example, the following is what I use to expand the scope of the CSP only for my "map" page: <?php $loadMap = $page->name === "map"; ?> <!DOCTYPE html> <html> <head> <?php if ($user->isGuest()): ?> <meta http-equiv="Content-Security-Policy" content="default-src 'none'; base-uri 'self'; manifest-src 'self'; form-action 'self'; font-src 'self' data: https://fonts.gstatic.com; frame-src 'self' https://www.youtube.com; img-src 'self' data:<?php echo ($loadMap) ? " https://maps.googleapis.com https://maps.gstatic.com" : ""; ?> https://www.google-analytics.com; script-src 'self' <?php echo ($loadMap) ? "https://maps.googleapis.com " : ""; ?>https://www.google-analytics.com https://www.googletagmanager.com; style-src 'self' <?php echo ($loadMap) ? "'unsafe-inline' https://fonts.googleapis.com" : ""; ?>"> <?php endif; ?> Hope this saves someone a little time testing. https://observatory.mozilla.org/analyze/bene.net.au
    1 point
  7. Some time ago I created a site profile for creation of a REST API with ProcessWire. Since I kept struggeling with updating stuff between different projects which use this, I decided to convert it into a module. It is now ready for testing: https://github.com/thomasaull/RestApi Additionally I added a few small features: automatic creation of JWT Secret at module install routes can be flagged as auth: false, which makes them publicly accessible even though JWT Auth is activated in module settings To check things out, download and install the module and check the folder /site/api for examples. If you find any bugs or can think of improvements, please let me know!
    1 point
  8. Today we have a new master version released, version 3.0.148! The last master version was 3.0.123, so there are 25 new versions worth of upgrades, fixes and optimizations in this new master version, relative to the previous. In this post we’ll take a closer look at what’s new, how to upgrade, and more— https://processwire.com/blog/posts/pw-3.0.148-master/
    1 point
  9. Hi @Bacelo, I'm an artist who just coded his own website with PW. I basically learned enough PW and php to code it in the past 1.5 months. This is before I started learning about SEO...so I've been thinking about the right site construction. I might have to amend my menu links etc. I've been testing an SEO program and they linked to a number of publicly available articles. This one I think is the best. https://moz.com/blog/site-architecture-for-seo. The main takeaway from this article is that the site architecture should be as flat as possible. So keeping in mind that I'm a beginner in php and pw and all things programming: I may be misunderstanding your description, but why is a painting in two categories? Would there be an issue of duplicate content? Maybe you can solve this with the canonical link then? I like that a painting=page. That's the way I did mine as well (I'm a photographer). Image = page. I don't use the multi image field anywhere in the site (e.g. in a blog post). In learning about SEO, text is very important, will there be blog posts? In the previous website incarnations, my site had images with only title and caption, which google considered to be thin content. How is the client going to solve that? I'm still trying to solve this for myself. For now, what I've done is that when I talk about a certain image in a blog post, I will purposefully link to the image page from the blog_body. In the image page, i have Related Writing code that automatically picks up any page that links to it using pagelinks(). I think over time this will work well if I want to stay with image=page. I'm going through my past blog posts to link them over time. An alternative I've considered is not to have individual image pages (to avoid the thin content). Instead I would only have a gallery page with say all the images lazy loaded as you describe. If a user wants to see a larger version, then they click on it, and a larger version pops up (I forget the module that does this, but there's several). I ended up not doing this because I want each image to have more information displayed over time like edition, exhibition history, buy button, etc, and based on my reading of the module, you can't fit that into a pop-up (whatever you call those things). As stated the main takeaway I think is to have a flat structure for search engines while making it as pleasant for user experience. Regards,
    1 point
  10. I today integrated the multi-language support for all the config fields.
    1 point
  11. The not direct answer, but maybe you can find something that suits your request at this thread
    1 point
  12. Just updated the readme with an example of page cropping marks and bleed margins sometimes necessary for printing: Page margins for print with cropmarks // thx to https://stackoverflow.com/a/50245034/6370411 $pdf = $modules->get('RockPdf'); $pdf->settings([ 'mode' => 'utf-8', 'format' => [214, 301], 'img_dpi' => 300, ]); $pdf->write(' <style> @page { /* regular A4 paper size is 210x297 */ size: 211mm 298mm; /* trying some weird format to make sure it works */ marks: crop; } </style> Content '); d($pdf->save()); You see that the Trim Box shows our custom values 211x298 whereas the bounding box would show the paper size (214x301). Real life example using RockPdf and RockLESS // parts of RockPdfCalendar module public function init() { $this->w = $w = 420; // paper width in mm $this->h = $h = 297; // paper height in mm $this->b = $b = 2; // bleed in mm /** @var RockPdf $pdf */ $pdf = $this->modules->get('RockPdf'); $pdf->settings([ 'mode' => 'utf-8', 'format' => [($w+2*$b), ($h+2*$b)], 'dpi' => 300, 'img_dpi' => 300, ]); $this->addBackground($pdf); $this->addStyles($pdf); $this->pdf = $pdf; } /** * Add Background PDF * @return void */ public function addBackground($pdf) { $page = $this->pages->get("template=settings"); $pdfs = $page->getUnformatted('calendarbackground'); if(!$pdfs OR !$pdfs->count()) return; // no field or no file $pdf->set('SetDocTemplate', $pdfs->first()->filename); } /** * Add styles */ public function addStyles($pdf) { /** @var RockLESS $less */ $less = $this->modules->get('RockLESS'); $less->vars = [ 'w' => $this->w."mm", 'h' => $this->h."mm", 'b' => $this->b."mm", ]; $css = $less->getCSS(__DIR__ . "/style.less")->css; $pdf->write("<style>\n$css</style>"); } Then all you have to do is call $modules->get('RockPdfCalendar')->show() to render the pdf in the browser ?
    1 point
  13. Almost every time I find one of these interesting ML/AI/Science based Python projects I want to include in my own work, I run in major compatibility issues. Either a bound C library has changed its signature too much, or the Python lib never got adapted to version 3 (or 3.7 and another lib needs native types). To me it seems like Python is partly a graveyard of university projects nobody cared to continue. Not that Python is bad in general. When Google app engine support for Python came out I implemented a service together with two other devs (extending in-game functionality of a virtual world) that took up to a few million hits per day and was lots of fun to build. But developing in Python can easily become a package version nightmare, and most tutorials out there just ignore that, which adds a steep learning curve if you want to do complex projects in Python. pyenv and pipenv, which came out last year, only address parts of that. This xkcd is quite fitting I think ? I for one also have a (subjective) aversion to languages where whitespace has too much meaning. If you ever learned Cobol, you probably know what I mean...
    1 point
  14. Hi @BitPoet, excellent! So it works fine. Thank you for your help and support!
    1 point
  15. Wow... thanks @joshua for this. This is really a nice extension or more advanced and often asked for solution. I wil definitely try this and check out what is possible with your module. Great work!
    1 point
  16. I've added a feature to define the link to the issue in the fix and also the author (github user) <?php namespace ProcessWire; class Foo extends PWFix { public $label = "My foo label"; public $description = "My foo description"; public $issue = "https://github.com/processwire/processwire-issues/issues/xxx"; public $author = "BernhardBaumrock"; // github user public function init() { // fix goes here } }
    1 point
  17. @astock: I just checked the code. While the hasVoted method is called before renderPoll(), it doesn't get the current user. I have added a github branch with a fix if you want to give it a spin.
    1 point
  18. I had to do several page imports via Tracy Console today, so I had the challenge of populating the Daterange field easily via the API... I added support for basic daterange parsing from a given string: RockDaterange("22.02.2020") hasTime => false hasEnd => false fromH => "22.02.2020 00:00" (16) toH => "22.02.2020 23:59" (16) RockDaterange("22.02.2020 17:00 - 19:00") hasTime => true hasEnd => true fromH => "22.02.2020 17:00" (16) toH => "22.02.2020 19:00" (16) RockDaterange("22.02.2020 17:00 - 20-3-1 19:00") hasTime => true hasEnd => true fromH => "22.02.2020 17:00" (16) toH => "01.03.2020 19:00" (16) And it get's even better! This makes it possible to use $page->setAndSave() easily using string dateranges: $page->setAndSave('range', "2020-02-22"); // single full-day event $page->setAndSave('range', "2020-02-22 18:00"); // single day event with time $page->setAndSave('range', "2020-02-22 18:00 - 22:00"); // single day event with time range $page->setAndSave('range', "2020-02-22 - 2020-02-24"); // 3-day event (full-day) $page->setAndSave('range', "2020-02-22 06:00 - 2020-02-24 23:00"); // 3-day event with times You wonder how complicated that was to implement?! Once the parsing part was done it was nothing more than adding this one line to the sleepValue method of the fieldtype. How genius is ProcessWire?? ? public function sleepValue($page, $field, $value) { if(is_string($value)) $value = new RockDaterange($value); ... --- This is how I did the recurring events so far ? Got an excel from the client with page id of the master event and date + time of the recurring events. Using VSCode and multicursor I transferred this into a script to create pages: The save() call at the end of each line would not be necessary but triggers a hook that renames the page and adds the daterange to the URL. This prevents ugly urls like this /event-x /event-x-1 /event-x-1-1 /event-x-1-1-1 And creates URLs like this instead: /event-x-01.01.2020 /event-x-01.02.2020 /event-x-01.03.2020 /event-x-01.04.2020 There's a lot one has to think of when dealing with events ? I wonder if a "add daterange to URL" feature would make sense if a daterange field is present on a template... Would have to be optional of course.
    1 point
  19. Python has one big advantage over PHP, which people might or might not care about: It‘s widely used for devops tooling because it‘s preinstalled on so many systems and it‘s growing super fast in the space of ML/AI/Science based computing because of it‘s bindings to fast low level C code while still writing python on top. If you care about those things or you want to do them as well, but not introduce a mix of technology, then sure python is a great solution. If not I don‘t see any reason to switch from whatever one is using right now.
    1 point
  20. Exactly what BitPoet said. Over the years I've heard over and over again how PHP is a dead/dying language, and how the future is all about [insert any imaginable language here]. If anything, I've learned not to care: PHP has been around for a long time, and to date it's still a lively project with a massive ecosystem. When I started with PHP 4 (or 3 — can't remember for sure) back in the days, it was a whole different language, really. 5.x made it a viable object-oriented language, 7.x brought in massive improvements in terms of features and performance, and 8 looks like it's going to be a blast as well. So yeah, I don't see any reason to jump the ship at this point; if anything, I'm pretty sure that PHP will have a lot more to offer in the future ?
    1 point
  21. Hi guys, I was very excited for this module, but my life took a huge direction change and I no longer have the time to invest in module development. I am gonna leave the files here. You guys can take it and run. Maybe there might be something useful here. Maybe not. I still think it's a good idea to do drag and drop modal building in PW. So hopefully one day something like that can come to light. I love this community and I love ProcessWire. Live long and prosper. - Joshua Designme 2.zip
    1 point
  22. Having just wasted the best part of a day debugging an access issue because I hadn't realised that page-edit-created negated any related page-edit permissions, could I suggest that a note to this effect is included in the default title. I have amended the title on my system to read: Edit only pages user has created (IMPORTANT: This will negate any related page-edit permission - including permissions granted to a user by other roles) ..although it may be possible to make it briefer while not losing clarity and impact.
    1 point
  23. As far as I can tell, this favicon line has never been a part of the AdminThemeUikit that is shipped with ProcessWire. Are you sure this wasn't actually a local modification made by you or another developer? In either way it's never a very good idea to modify the contents of the /wire/ directory yourself, so even if there was such a line, adding your own favicon there would be a problem — partly because it will very likely get lost when you update ProcessWire.
    1 point
  24. Here's a basic example of how you could save files to a PW page via a front-end page using tus-php and Uppy. 1. Install tus-php via Composer. 2. Create a PW template that will provide the tus-php server endpoint - in this example the template is named "uppy". In the template Files tab, disable any automatically appended template file. In the template URLs tab, allow URL segments. If using Tracy Debugger, disable the debug bar in the front-end for this template because we don't want any output from Tracy being included in the response. The contents of the uppy.php template file: <?php namespace ProcessWire; // Create PW temp directory $td = $files->tempDir('uppy'); $td_path = (string) $td; // Create TusPhp server $server = new \TusPhp\Tus\Server(); // Set path to endpoint - no trailing slash here $server->setApiPath('/uppy'); // Set upload directory $server->setUploadDir($td_path); // Listener function for when an upload is completed $server->event()->addListener('tus-server.upload.complete', function(\TusPhp\Events\TusEvent $event) { // Get path of uploaded file $file_path = $event->getFile()->getFilePath(); // Add uploaded file to "files" field on Home page $p = wire('pages')->get(1); $p->of(false); $p->files->add($file_path); $p->save('files'); }); // Send response $response = $server->serve(); $response->send(); // Exit from current PHP process // Could probably use PW halt here as an alternative // return $this->halt(); exit(0); 3. Create a page using the template - in this example the page is at url http://1testing.oo/uppy/ 4. Add the Uppy assets, JS and markup to the template of the front-end page that you will upload files from. Markup Regions are used in this example. <pw-region id="scripts"> <script src="https://transloadit.edgly.net/releases/uppy/v1.4.0/uppy.min.js"></script> <script> const uppy = Uppy.Core({debug: true, autoProceed: false}) .use(Uppy.Dashboard, {target: '#uppy-box', inline: true}) .use(Uppy.Tus, {endpoint: 'http://1testing.oo/uppy/', limit:10}); </script> </pw-region><!--#scripts--> <pw-region id="stylesheets"> <link href="https://transloadit.edgly.net/releases/uppy/v1.4.0/uppy.min.css" rel="stylesheet"> </pw-region><!--#stylesheets--> <div id="body"> <div id="uppy-box"></div> </div><!--#body--> 5. Upload files via the front-end and see that they are added to the "files" field on the Home page.
    1 point
  25. ANOTHER UPDATE SnipWires Taxes (VAT) configurator is ready! I added a new custom Fieldtype FieldtypeSnipWireTaxSelector based on an idea of @BitPoet - thanks for that! Also I created a full featured repeater for module config editor including drag&drop handling. Have a look at the animated GIF below. The taxes you configure here will be available as select option list in product page editor. The first tax in the configured list will be used a s the default tax in the custom field.
    1 point
  26. You probably are using php 5.3 or lower. Change hosts or ask the current one to upgrade.
    1 point
×
×
  • Create New...