Leaderboard
Popular Content
Showing content with the highest reputation on 11/25/2020 in all areas
-
As we often use Matomo (former known as Piwik) instead of Google Analytics we wanted to embed Matomo not only in the template code but also via the ProcessWire backend. That's why I developed a tiny module for the implementation. The module provides the possibility to connect to an existing Matomo installation with the classical site tracking and also via the Matomo Tag Manager. If you have also PrivacyWire installed, you can tell MatomoWire to only load the script, if the user has accepted cookies via PrivacyWire. To offer an Opt-Out solution you can choose between the simple Opt-Out iFrame, delivered by your Matomo installation, or a button to choose cookies via PrivacyWire. You'll find the module both in the module directory and via github: ProcessWire Module Directory MatomoWire @ GitHub MatomoWire @ Packagist ->installable via composer require blauequelle/matomowire I'm looking forward to hear your feedback!8 points
-
Awesome — thanks Joshua! Just a heads-up: I've opened a new PR for you to check out at https://github.com/blaueQuelle/privacywire/pull/10. This is quite opinionated, so let me know if you don't feel it's a great match with the module. Basically what I've added is support for the textformatter module to replace embedded media/video iframes with PrivacyWire enabled ones. It's mainly a compatibility layer for TextformatterVideoEmbed ?3 points
-
Just want to spell out the solution to save any devs who see this post a little time and jump to the solution. As mentioned Jumplinks does not yet support multilanguage URLs. Trying to redirect "naturally" using Jumplinks will have your multilanguage page redirect to the page in the default language. You will have to create a Jumplink redirect for every language on a page (sorry big site and big language devs). Here's a quick screenshot with some explanations: Here's the gist- create your default language redirects as usual using Jumplinks as designed. For your URLs in other languages, add your source language URL as normal, but when entering the redirect destination, manually add the proper language URL and add the ? to the end of it. This "tricks" Jumplinks and creates a kind of sticky URL which Jumplinks won't replace with the default language URL. Couple of pro-tips after working through this: On your source URL, I highly recommend adding the [/] to the end of your source URLs. This makes the redirect work with URLs that end in a trailing slash and those that don't. Regardless of your chosen configuration for URLs it is always a good idea to account for possible user edge cases. Keep SEO in mind! Ensure that your destination pages have a meta canonical URL tag. Google is very literal when parsing URLs and by adding the ? to your destination page you run the risk of fragmenting your content into 2 URLs. Without your canonical tag, Google may index them separately and it is possible that your pages will compete with each other in search results and possibly replace your nice URL with the URL you appended ? As always, test, test, test. Just wanted to provide a shortcut to the solution in the Jumplinks thread. Happy redirecting!2 points
-
@teppo Thanks alot for your PR with the TextformatterVideoEmbed integration! I tested and merged your PR today. I like the idea of adding more and more integrations with other modules like TextformatterVideoEmbed.2 points
-
Note sure if it suits your needs or not, but it's really easy to include https://dibiphp.com/ into PW and then you can query those sqlite databases within your template files / modules. You can put this in your init.php file: require_once __DIR__ . '/vendor/autoload.php'; $this->wire("dibi", new Dibi\Connection([ 'driver' => 'sqlite', 'host' => hostname, 'username' => user, 'password' => pass, 'database' => dbname, ])); and then you can query using the global $dibi variable like this: $result = $dibi->query('SELECT * FROM mytable'); foreach ($result as $row) { echo $row->fieldname; }2 points
-
Thanks @teppo! I will look into this and will merge your PR then ? Sounds like a very useful addition to me2 points
-
Single Site, Developer and Agency Licenses are available via our LemonSqueezy Store >>> Please get in contact after purchasing, citing your license key & forum username, so we can add you to our support area. <<< This is a module pack by Nifty Solutions for Processwire CMF/CMS version 3.0.149 or later (running on PHP 7.2+) that extends the core features for password recovery making them more flexible and easy to use. Features Can send just the verification code in emails (removing the clickable link), and immediately show the reset verification page. This forces the reset to be completed in the same session it was started from. Allow the password reset to be initiated in one session and completed in another. You no longer have to complete the reset from the same browser and tab. There are options to allow you to still require reset completion from the same IP address. Prevention of incorrect data entry in the reset initiation step, users are warned if they enter an email in a username field. Optional customisation of the verification code. Can make manual and/or mouse-based copy-and-paste from the email easier. Optional auto-completion of the verification code field in the password reset step. This makes things easier for users as they don't have to copy-and-paste from their email client. Be warned, however, that this can facilitate automated reset attempts. Control how long reset links are valid for (sometimes an hour is much too long) and update the text of outgoing emails and reset screens to report the new value. Optionally allowing automatic user login following a successful password reset. This is not recommended but is supported. This option is never available to Superusers or users with 2-factor authentication requirements on their accounts. You can additionally limit this to users with specific roles. Allows the reset process to require input of the user's Time-based one-time (TOTP) value - if they have TOTP setup on their account. You can also mandate the entry of a valid TOTP in order to complete a password reset. The TOTP field extends ProcessForgotPassword and operates with or without NiftyPasswordsPlus. Works by extending the core ProcessForgotPassword module so it works on the Admin login page and your custom LoginRegisterPro pages. You'll also get access to NiftyHashedTokens in your template and module files - a HMAC-Hashed key-to-value store, providing tamper-detection of the key and controlling how many times it may be accessed in a given period along with IP address checking. Pre-Requisites This requires PHP7.2 or better and a recent copy of Processwire with the ProcessForgotPassword and InputfieldSelect modules installed. Installation After purchase you will have access to the latest version of the pack as a single zip file.If this is your first Nifty installation: simply unzip the file in a temporary location and transfer the resulting Nifty folder into the site/modules directory of your site. Then refresh the modules in Processwire and install the NiftyPasswordsPlus module.If you already have other Nifty products installed: unzip the file in a temporary location and look in the Nifty folder you unpacked. Copy any new subdirectories from there into your existing site/modules/Nifty directory. Log in to Processwire, refresh your modules and install NiftyPasswordsPlus. You will need to acknowledge the disclaimer, enabling the module in order to proceed. Refunds We offer a no-questions-asked refund policy in the first 14 days from the date and time of your purchase. Settings Step 1: Step 2: Gives options changing how the reset link works. Verification code customisation options: This can lead to much simpler codes in the reset emails... Step 3: If you install FieldtypeUserTOTPValue as well, you also have additional options to require TOTP 2FA for reset. Step 4: Additional settings: FieldtypeUserTOTPValue allows you to add TOTP as a confirm field in ProcessForgotPassword: Which then requires the user doing the reset to enter their TOTP 2FA code (if set on their account) in order to reset their password: If the user does not have TOTP set up on their account, they just leave this blank. If they do have TOTP set up, they need to enter the current value. If you are using this along with NiftyPasswordsPlus, then you can additionally enforce role-based requirements for entry of a correct TOTP value in order for password reset to work. It does this by hooking FieldtypeUserTOTPValue's RequireTfa() method. You can do the same from your site/ready.php file to add any additional checks you'd like for your particular site. We currently only support TOTP 2FA as it is simple, avoids sending another email (in case email is compromised) and the bar to user adoption is quite low. Finally, we have NiftyHashedTokens: Single Site, Developer and Agency Licenses are available via our LemonSqueezy Store >>> Please get in contact after purchasing, citing your license key & forum username, so we can add you to our support area. <<<1 point
-
I just took a look at your code and saw that you're already using preg_match_all so I could actually just add: \[\[([\w]+)\]\] as a non translated string and that takes care of excluding Hanna codes, so I think we are all good actually, although it might be nice to note this in the settings.1 point
-
Or perhaps you could add a little more flexibility by allowing the "Global Non-translated strings" option to support regexes so we could exclude things like hanna codes and others as needed?1 point
-
Great - thanks! I have another request for you - can you make it possible to not translate hanna codes, eg anything inside this: [[don't_translate]] - you'll want to make sure to find out what the open and close tags are for Hanna in each PW install, but that's easy. Does that make sense? Thanks again - this is really awesome!!!1 point
-
Oh now I get it. I misunderstood when you said you installed from a URL. I don't make use of that (for some reason, habit?) so I've never run into that before and it didn't hit me. I'll restructure the repo and push that out. Thanks for the heads up. edit: Doneski. Repo has been updated.1 point
-
Looking at the repo (https://gitlab.com/SkyLundy/fluency-processwire), it seems pretty clear why it's happening - you have all the files stored inside a "Fluency" folder. When PW installs from the zip file, it extracts everything into a higher level Fluency directory, which is why there end up being two. Take a look at any other PW module and you'll see that the main files are at the top level.1 point
-
@FireWire - just installed and on going to the Translation page, I get these errors: PHP Warning: file_get_contents(/site/modules/Fluency/fluency_templates/el_h1.tpl.html): failed to open stream: No such file or directory in .../Fluency/classes/FluencyTools.class.php:31 PHP Warning: file_get_contents(/site/modules/Fluency/fluency_templates/el_p.tpl.html): failed to open stream: No such file or directory in .../Fluency/classes/FluencyTools.class.php:31 I installed via the URL to the zip file and the problem is that it resulted in two "Fluency" directories such that the path is actually: /var/www/dev.grief.coach/site/modules/Fluency/Fluency/fluency_templates/el_p.tpl.html Once I moved those files and did a modules > refresh it started working as expected.1 point
-
Okay- I did misread that a bit. I will admit that my .htaccess-fu is a bit lacking when it comes to more effective redirects and I'm in a timeline-bind. Should have gotten started on that sooner... Thanks again for this info. Surely will come in handy in the future!1 point
-
Just to be clear: in my opinion it's actually perfectly fine to perform redirects in Apache config files, site-specific vhost files, or even in the .htaccess file. It's just that they should use RewriteRule (mod_rewrite) instead of Redirect (mod_alias). If a new site requires redirects for old URLs, this is typically how I handle it — this way I have full control over wildcards and such, and there's very little overhead. Nothing wrong with using Jumplinks (or ProcessRedirects), of course. That slight overhead they add (booting up ProcessWire, checking for redirects, etc.) rarely matters ?1 point
-
That's my conclusion as well. I didn't want to tinker with ProcessWire's internal workings so I left that redirect parameter alone. Also can confirm empirically that placing my redirect rules didn't stop Apache from parsing the document after the redirect, which while frustrating kind of makes sense given the gravity of important configurations contained in the file. And I agree about complexifying (new word) htaccess too much. Many thanks for the additional insights.1 point
-
the first row actually does the trick already, why do I need the second? limit=0 also works BTW Thanks!1 point
-
The problem is that $rows only holds the items of the current page, as per your pagination settings. To get all items, you need to explicitly overwrite the limit and offset resulting from your pagination settings and the current page. Then you can use that to create a complete list of categories. Something like this should work: $rows = $pages->get('path/to/parent/page')->protable('start=0, limit=9999'); $categories = array_unique(array_filter($rows->each('category'))); Note the high limit which overrides the default limit set by the pagination. Not pretty, but I don't think it's possible to override the limit to none. Just make sure the limit is higher than the number of values you ever expect to have in your field.1 point
-
Pete and I can finally announce the availability of a discounted "Early-Bird" batch of NiftyPasswordsPlus. Once this batch is gone, we will be offering one further discounted batch before the pricing reverts to normal. Details in the opening post above this. Please feel free to ask any questions you may have about the module here.1 point
-
1 point
-
Thanks for your help. Because we may end up with a lot of posts I am creating a JSON file in a hook (based on @MoritzLost's example) so there is almost no overhead on the front-end. $wire->addHookAfter('Pages::saved', function(HookEvent $event) { $page = $event->arguments(0); if ($page->template == 'news-item') { $pages = wire('pages')->find('template=news-item'); $years = []; foreach ($pages as $p) { $year = wire('datetime')->date('Y', $p->getUnformatted('newsDate')); if ($year !== null) { $years[$year] = isset($years[$year]) === false ? 1 : $years[$year] + 1; } } file_put_contents('json/news-years.json', json_encode($years, JSON_PRETTY_PRINT)); } }); Thanks. ?1 point
-
Just that and the next two posts :-). - workaround in the 2nd post. I am afraid not. Nice site, btw ?.1 point
-
I see. No, it doesn't, although someone posted a workaround here, just FYI.1 point
-
1 point
-
Hi Joshua, just an idea. If there were a counter for all closes of all finished user decisions and a separate one only for the "accept all" decisions, it would give me a perfect idea of the accept ratio of the specific site. Either generally (probably enough), or even per month in a table (to monitor changes in behaviour). In the module, or in logfiles or a CSV file with a row limit? Basically, sort of mini-statistics. I have guesswork right now regarding Analytics' / Matomo's result changes and of how many users (in percent) those analytics results represent?1 point
-
@Ivan Gretsky GitHub is a requirement for modules that are automated with regard to automatically pulling version and readme, etc. If someone needs a case where the module can't be managed at GitHub (like a commercial module or other specific case) then I would just ask them to contact me so I can add it manually. I feel it's safest for our users by having downloadable modules provided by GitHub. They have security measures in place that give me a lot more peace of mind than a link to a random ZIP file off on some site none of us know. Without GitHub as a middle man, I think there's a much higher probability of getting something questionable in a ZIP file, whether it's because of a hacked site or any number of other reasons. GitHub also provides great security options for protecting individual accounts, which I think further increases the safety for consumers of ProcessWire modules. The other side of it is that GitHub provides an API that we can read data from in order to ensure our module information is up-to-date and that users don't have to manage that information in more than one place. That API also includes a function to safely convert GitHub-flavored markdown to HTML, which is very useful for the modules directory. Presumably it would be possible to also implement this for other providers (GitLab was mentioned), so if there's significant demand for it then it would be worthwhile. But it took me a long time to implement the GitHub integration as it is, and at present I likely couldn't afford the time investment to implement another different API right now. Down the road I'm open to adding support for more Git providers. For now though I had to work within the bandwidth I could afford to devote to this project. @Mikie The module class name is used throughout, but it's true it doesn't literally say "class name:" anywhere. I think you are right it would help with clarity if it does that somewhere, so I'll plan to add it. As for version compatibility, I'm going through all of the PW 2.x modules and deleting any that aren't 3.x compatible and don't look like they will be. This will take me a little while, but basically the intention with the directory is that you can assume it's 3.x compatible. For more fine grained detail on version compatibility, it's going to read the module info array. It doesn't report that info at present, but this project isn't fully finished yet so it will be reporting more from the module info array in the coming weeks.1 point
-
Just some explanation because it is interesting... This isn't something that is specific to Repeaters - it applies to any selector used on a PageArray/WireArray (a Repeater field returns a PageArray). When you do $some_pagearray->find() this is different to a $pages->find() - the method name is the same but they are actually totally different methods. See find() method in the PageFinder class vs the WireArray class. When using $pages->find() the method refers back to the fieldtype for each queried field and the fieldtypes can do some special preparation to the queried value. In the case of a Datetime field the value is passed through strtotime() if it is a string. So this allows "today" to be converted to a timestamp. But when using $some_pagearray->find() this process does not happen, so the queried value must be a timestamp. Another gotcha to watch out for is using the page status as a string in a selector. With $pages->find() you can do something like "status!=hidden" but this won't work with a selector in $some_pagearray->find(). I think it would be nice if things like this did work with PageArrays - there is an open request for it.1 point
-
Thank you Martijn for the help. I've got it working!!! Woop. Did end up creating a page as in my opinion the client will be able to manage the content a lot easier. I'll post the full solution once I solve the final problem... This sounds extremely trivial but- the delete button isn't rendering at all. No idea why since I am using the core module. If anyone can suggest why that would be great. This is how I'm calling it, I am also including the JS file (inputfieldfile.js) on the page. $form_images = $modules->get("InputfieldFile"); $form_images->label = "Images"; $form_images->description = "Upload your images maximal 3 files."; $form_images->required = 0; $form_images->attr("name+id",'images'); $form_images->destinationPath = $upload_path; $form_images->extensions = "jpg jpeg gif png"; $form_images->maxFiles = 10; $form_images->maxFilesize = 2; $form->append($form_images);1 point