Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


joshua last won the day on February 17

joshua had the most liked content!

Community Reputation

82 Excellent

About joshua

  • Rank
    Distinguished Member
  • Birthday 01/14/1993

Contact Methods

  • Website URL

Profile Information

  • Gender
  • Location
    Göttingen, Germany
  • Interests
    Next to web development? :D
    Mountainbiking and Lindy Hop

Recent Profile Visitors

2,268 profile views
  1. Thank you for the PR and the idea! Of course it's a good think to have the render function hookable. I also like the idea of @horst with an hookable output file. I would definitely like to spend some time soon to refactor / optimize PrivacyWire.
  2. Good question! I don't know a native "processwirish" procedure for this yet. Your solution like a good start. Does anyone else knows a processwirish way of doing this?
  3. Thank you for all your input! I've been quite busy the last weeks, sorry for my delay in answering your requests. During the last couple of days I refactored some code and implemented an suggested feature by @horst (to call a custom js function after saving the consent). As this version might not be as stable as the current version, you'll find it currently in a separate branch. The following updates are also only in this branch at the moment. I agree on that and just added this category to PrivacyWire (in the V2-Branch). In the new branch I switched to save the consent information in LocalStorage instead of Cookies. Now the lifetime in all browsers should be 365 days. About the details about cookies / categories: I also agree that there should be an option to display more details. The idea of a Textformatter for this purpose sounds good. Haven't got the time though to implement it right away. I'm open for PullRequests with improvements, if you want 😉 The styling is currently applied directly within the js file. To add the option to disable loading the stylesheet, I could exclude this from the js file and add an option to the module config.
  4. That's an interesting point. As I understood the GDPR (but I'm not a lawyer, so not sure about that) a listing of the single cookies is not mandatory right now - but the upcoming ePrivacy could change that. When you want/need to implement this solution, KLARO could be a better choice at the moment. Currently this feature isn't included in PrivacyWire and I'm not sure if or when I could implement it. Or you could fork PrivacyWire and add the feature with a PR? 😉 Best, Joshua
  5. Hi Montero, thank you for your feedback. I just looked into this and fixed the bug in the new release. Best, Joshua
  6. Thank you! 🙂 Yes, sure, I can give some examples. The workflow is getting refactored right now, so I can't show any specific details, but I'll describe the process. A quite simple example for a tiny helper class is this Headline Class for rendering headlines without risking to use more than one <h1> tag per page call: I like to use this on content heavy pages (e.g. within RepeaterMatrix Elements) where I want to be sure to not have more than one <h1>. By default only the first call of this helper method returns the <h1> tag, all the others an <h2> (unless otherwise specified with $sizeTag). To output a headline with this, simply use <?php echo Headline::render($page->headline); ?> I also have some helpers for rendering responsive (lazy loading) images or buttons and in this project most of the business logic of the "magic link" login is within one of these helper functions. Currently I require these classes manuelly within the ready.php include_once($_SERVER['DOCUMENT_ROOT'] . "/site/templates/helpers/Headline.php"); include_once($_SERVER['DOCUMENT_ROOT'] . "/site/templates/helpers/Image.php"); include_once($_SERVER['DOCUMENT_ROOT'] . "/site/templates/helpers/Link.php"); include_once($_SERVER['DOCUMENT_ROOT'] . "/site/templates/helpers/FrontendUserManagement.php"); include_once($_SERVER['DOCUMENT_ROOT'] . "/site/templates/helpers/CopeCartHandler.php"); But I definitely want to dig deeper into autoloading them. I want to refactor especially my Link and Image helper soon, perhaps I'll explain them afterwards further... As example for the custom Page Class here is an extract from my SpeakerPage: My Workflow Local <-> Stage <-> Live Our webserver uses Plesk Onyx as the hosting control panel. For each web project we create a separate "subscription" where the stage and live domain will live. For the dev / stage domain we use the plesk integrated git repo as dev branch. The live domain gets connected to the master branch of the same repo. As we exclude a lot of files in git (e.g. the whole /wire/ directory or the assets and module directories) we had to find a solution to copy them between stages. I'll come to that point later again. In my local environment I'm using MAMP Pro for the server environment. After pulling everything from the dev branch, we need also pull the database and exluded files / directories. To do so, the python script connects itself via SSH to the server and dumps the database, creates the same database locally and imports its contents. The files / directories will be pulled as zip files and extracted locally. Our first try here was to use rsync, but with asset-heavy pages this can take quite a while to copy... During development we usually do all the database-related stuff in the staging environment and just pull the database with our Python CLI script. When we need to pull also modules or the wire dir, our CLI script can handle that as well. Our content-editors mostly work in the staging environment ( on new web projects) or directly in the live environment (on existing projects). I'll definitely write an in-depth article about this, as soon as we have refactored it completely! Then I can also show some code snippets or even publish it, we'll see.
  7. We recently launched the website “Resilienz-Kongress”, which is kind of an online summit / online conference about resilience (only in German language). The users can register as a participant and will receive daily emails during the conference timeframe with a conference room link for each day. Within this virtual conference room the participants can watch several interviews with experts and exchange ideas via comments. This concept is especially during the COVID-19 lockdown an interesting possibility for idea exchanges. Some technical details: • ProcessWire 3.0.155+ • ProCache • ProFields (RepeaterMatrix) • PrivacyWire • Seo Maestro • WireMail SendGrid • CodyFrame UI Framework • CopeCart (as the E-Commerce API) • Git, Node, Yarn, Gulp, PostCSS, Autoprefixer for a modern workflow combined with our individual local <-> stage <-> live environment and sync helper build with Python We heavily used the ability to specify custom Page classes (introduced in PW 3.0.152) and a lot of custom helper classes for cleaner code. Every frontend user registration with double opt-in is linked with the SendGrid API. The login process for frontend users is quite individual as we wanted to integrate a password-free login method similar to “Magic Links”. To achieve this we developed a “FrontendUserManagement” Class, which takes care of all the magic in the background. I’ll write another article about this topic as soon as I find the time, as I like the idea to implement this solution also as an open-source ProcessWire module. For the after-selling area we used CopeCart as our cart system with their IPN. With this combination we don’t have to handle the billing process at all. Also a clean cross-device affiliate tracking system between CopeCart, ProcessWire and SendGrid is integrated even though we’re currently not using the affiliate system at all. As frontend framework we used CodyFrame with an intense usage of CSS Custom Properties (for modern browsers with a classic fallback CSS for old browsers). https://www.resilienz-kongress.de/
  8. I've updated the module today to add the W3C validation. Starting now the type can be "text/plain" instead of "optin", the js will detect the elements via the data-category attribute. I will update the documentation. That's a good point. Right now there isn't a detection for this but I'll think about a way to implement this. When you add a button to change cookie preferences in your privacy policy, the selected options are pre-selected, so one could say it's "documented". I'm not sure if this is sufficient for your case? That will not work, as the loading works via javascript. When javascript is disabled (and the <noscript> tag comes into play), PrivacyWire isn't loaded as well so it cannot load the <noscript> tag.
  9. That's right, currently the W3C does not validate. @gebeer also mentioned this with the possible solution to use "text/plain" instead of "optin". I'm planning to implement this solution, but as an optional addition to keep backwards compatibility for the users who already use the "optin" variant.
  10. Thanks again for your feedback. I tested the privacy & imprint URLs and there really was a small bug about the multi language URLs. When you update the module the multi language URLs should work now. Example of external media: <!-- This is the output container --> <div id="player"></div> <script type="optin" data-type="text/javascript" data-category="external_media"> // 2. This code loads the IFrame Player API code asynchronously. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // 3. This function creates an <iframe> (and YouTube player) // after the API code downloads. var player; function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: '360', width: '640', videoId: 'M7lc1UVf-VE', events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { event.target.playVideo(); } // 5. The API calls this function when the player's state changes. // The function indicates that when playing a video (state=1), // the player should play for six seconds and then stop. var done = false; function onPlayerStateChange(event) { if (event.data == YT.PlayerState.PLAYING && !done) { setTimeout(stopVideo, 6000); done = true; } } function stopVideo() { player.stopVideo(); } </script> See this for more info about the YouTube API. The code above is from their example.
  11. Thanks for your feedback! I'll look into bug about the privacy URL in different languages later today. For embedding videos I'll also write an example and update the main post later with this.
  12. Hi Sergio, thank you! 🙂 Glad you like the module. I actually never thought about the "opt out" approach as our customers or their "Data protection officer" requested the opt-in version. Do you mean this approach for "pre-selecting" the checkboxes within the choose-window? That would be not to hard to implement, I could add an option for this to the module config. More difficult would it be to automatically load all scripts on page load and only stop specific categories, when the user choose to opt-out. About the Google Tag Manager: I have no experience in this kind of granular control within the GTM. Maybe this article could help?
  13. Update - Version 0.0.6 Minor CSS-Debugging (hiding the choose button when no cookie group is selected) Added ProCache support for the script tag, when ProCache is installed
  14. I today integrated the multi-language support for all the config fields.
  15. You can simply write your own CSS. In the module included are only some basic styles (less than 500 byte) which are directly included via JS. I tried to keep the module as slim as possible, the javascript has only 3.05 kb (gzipped) with all the functionality. You can see an example of styling at our website or this website. I usually only style the div.privacywire and the buttons to match the website styles.
  • Create New...