Leaderboard
Popular Content
Showing content with the highest reputation on 11/26/2020 in all areas
-
This site has been a long time in the making. Back story: Was first developed in PW 2.something many years ago. Around 5yrs ago, it underwent a major upgrade. The look was very 90's and the booking page had around 50 input fields on the one page. See screenshots. Original dev, who did a great job with web technology at the time, went AWOL Business was sold to a new owner New owner engaged me to revamp the site. I laugh & laugh & laugh. If only I knew then what I know now! It was crucial that the years of historical data be kept and accessible Busy period is November to February (Aussie summer). And then came COVID. Victoria was the state hardest hit with C19 in Australia and lockdowns were harsh. Definitely no parties. The possible product configurations, hire rates & rules (all with 'except for this one') had me melt into a puddle at times. Pricing is shown on product pages only when a valid venue postcode & event date entered and can change depending on the surface type (eg concrete attracts a $50 surcharge) One of the biggest things that tripped me up was the previous dev combined data/module logic with presentation HTML. I had to rewrite all the old code to adapt to the new layout. Would have been much easier to have logic & presentation separated. A while ago I chose to stop using CSS frameworks to dig deep into how CSS really works. Much of what I have learnt is in the site frontend code. The site is fully responsive and the only JS used is on the View Booking page when a customer alters the booking item qty. There is NO frontend presentation JS, including the dropdown & mobile menus. Where it stands today: There are still some things to do, including implementing a very sensible change recommended by @ryan. In addition to the frontend, there are a number of new backend/admin reports Victoria is coming out of C19 hell and getting back to normal The site is live and online bookings are rolling in New modules added: ProCache FormBuilder + StripePayment + Page Break CampaignMonitorAPI ProFields - Functional Fields ProFields - Repeater Matrix RockMarkup2 Database Backups Upgrades SeoMaestro TracyDebugger Page View Statistic Big shout out 'Thank you' to all the PW devs who responded when I reached out for help in the forum. Check out the new look www.aaronsamusements.com.au4 points
-
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!3 points
-
You can use subfield selectors (works both with regular fields and system properties, like template). Either of those should work: $result = $pages->find('parent.template!=your_excluded_template'); $result = $pages->find('parent.template.name!=your_excluded_template');2 points
-
I tried to disable or hide a "Remember me" checkbox. My HTML is <div class="field has-text-right"> <label class="checkbox"> <input type="checkbox" name="rememberme" value="<?=(int) input()->cookie->rememberme?>"> <?=__('Remember me')?> </label> </div> The code I'd prefer would be (notice the two "disabled" attributes on the label and the input) <div class="field has-text-right"> <label class="checkbox" disabled> <input type="checkbox" name="rememberme" value="<?=(int) input()->cookie->rememberme?>" disabled> <?=__('Remember me')?> </label> </div> Although I could live with only hiding it, which is what I've tried by adding data-category="functional" data-ask-consent="0" data-ask-consent-rendered="1" to the div, the label or the checkbox. And it hides them all right. The issue is that PrivacyWire does not care about innerHTML of my poor div, or about its class. I changed o.innerText=e.innerText with o.innerHTML=e.innerHTML directly into js/PrivacyWireUnstyled.js and I got my checkbox back, but without its initial class. I think it is the code at line 231 in src/js/PrivacyWire.js. I know almost no JavaScript, so start throwing tomatoes - in the priw_updateAllowedElement there is no way to let the old element live instead of copy into a new one > insert the new one in the DOM > delete the old one? Also, it feels to me that flipping between two attributes or two CSS classes should be all PrivacyWire needs to do in regard to the elements that need consent. LATER: hmm, maybe not in regard to scripts. Leaving for the coffee machine...2 points
-
I've added an example how this can be done using RockFinder3 in the related thread:2 points
-
I was mentioned in this post by @MoritzLost and thought that would be a nice challenge and a nice little tutorial. I've updated the docs: https://github.com/baumrock/rockfinder3#example-group-by-date Example: Group by date As an example we will create a list of the count of cats and dogs related to their page-creation day. We start with a simple list of all ids of cats and dogs: $rf = $rockfinder->find("template=cat|dog"); $rf->dumpSQL(); $rf->dump(); We can't simply add the created column because this is a timestamp. We need a formatted date, so we add it as custom SQL: $rf = $rockfinder->find("template=cat|dog"); $rf->query->select("DATE_FORMAT(pages.created, '%Y-%m-%d') as created"); $rf->dumpSQL(); $rf->dump(); Great! Now we need to group the result by the date string: $rf = $rockfinder->find("template=cat|dog"); $rf->query->select("DATE_FORMAT(pages.created, '%Y-%m-%d') as created"); $rf->query->select("COUNT(id) as cnt"); $rf->query->groupby("DATE_FORMAT(pages.created, '%Y-%m-%d')"); $rf->dumpSQL(); $rf->dump(); Wait... That's not what we expected, right? That's because we still have the pages.id column in our SELECT and GROUP BY statement and therefore we end up with all the cats and dogs as unique rows. To get rid of that column we make one important change: Instead of adding the SELECT and GROUP BY statement to the query we overwrite it: $rf = $rockfinder->find("template=cat|dog"); $rf->query->set('select', [ "DATE_FORMAT(pages.created, '%Y-%m-%d') as created", "COUNT(id) as cnt", ]); $rf->query->set('groupby', [ "DATE_FORMAT(pages.created, '%Y-%m-%d')", ]); $rf->dumpSQL(); $rf->dump(); Not too complicated, right? You want yearly stats? Easy! Simply change the date format string to %Y:2 points
-
Hello friends! I have another module for you, which will make your daily work as a Processwire developer easier. Introducing: AppApi This module helps you to create api-endpoints, to which an app or an external service can connect to. Features Simple routing definition Authentication - Three different authentication-mechanisms are ready to use. Access-management via UI Multiple different applications with unique access-rights and authentication-mechanisms can be defined The documentation has become quite extensive, so have a look at the Github repository for details: Installation Defining Applications Api-Keys PHP-Session (Recommended for on-site usage) Single JWT (Recommended for external server-calls) Double JWT (Recommended for apps) Creating Endpoints Output Formatting Error Handling Example: Listing Users Example: Universal Twack Api Routes Page Handlers File Handlers A special thanks goes to Thomas Aull , whose module RestApi was the starting point to this project. This module is not meant to replace this module because it does a great job. But if you want to connect and manage multiple apps or need other authentication methods, this module might help you. I am already very curious about your feedback and would be glad if the module helps you a little bit.1 point
-
Hello, I would like to present you a new module which aim to facilitate the productivity of your editors/publishers when working on ProcessWire. The idea begun when my co-worker told me that when typing in ProcessWire CkEditor field he was feeling "loosing motivation" when writing big wall of text and/or inspiration. So he opened his web-browser and show me a site looking to Wordpress - feel free to put your preferred emoji here - then he opened Gutenberg... typed some text and moving some "blocks". I understood immediately why he got this feeling with CkEditor. If you or your client feel like this guy, then you will love this module ! What is currently supported ? Features Auto-save Medias upload support HannaCode support Blocks Implemented Heading Image Paragraph Embed Quote Code Link Table (beta) Block Delimiter Raw HTML Note (custom block markup) Feature Request Frontend Edition And there you go for the preview - sorry I am to lazy and bad at typing text so I had a copy/pasta moment : Module featured in the ProcessWire Weekly #317 - Thanks @teppo1 point
-
This module will log information about all mails that are sent via WireMail to the PW logs From PW Weekly: https://github.com/BernhardBaumrock/RockMailLogger https://modules.processwire.com/modules/rock-mail-logger/1 point
-
Thanks! As and FYI and a question to any Spanish / French / Italian (and any other languages that have gender specific nouns / verbs), I submitted a support ticket to DeepL yesterday asking about a way to specify the gender of names because of this scenario. my friend John -> mi amigo John my friend Jenny -> mi amiga Jenny my friend Jody -> what do we do here - DeepL doesn't know if Jody is male or female because it is used as both. I proposed to them that it might be nice to be able to send something like this to be translated: my friend <male>Jody</male> Of course this is a very simple example of gender translation issues (there are verb conjugation / contraction issues like ayudarle / ayudarla), but you get the idea. Actually, I barely know what I am talking about with this stuff but the process of investigating is helping my very limited spanish. DeepL is actually very impressive with this stuff. Anyone out there with any more experience have any thoughts?1 point
-
I'm here! ? Hi @benbyf, I'm glad that your using AppApi! Let me clear this up a little: 1. It's a bug, I am linking to a protocol named 'app_api' in the module's settings, but the actual logs are written in a log named 'appapi-exception'. I will create an issue for that... 2. @thomasaull is exactly right. Currently there is no way to connect to the api without an api-key. It is necessary, because the key is needed to identify which application-configuration should be used. I am definitely planning to make it possible to define a "default"-application, that handles requests without an apikey, but it will need some time...an 3. I would generally create new apikeys, even for small version-steps. If you need to block an old version, you can set the accessable-until field of the apikey or simply delete it. What I don't fully understand is what you mean by "form_version", @benbyf. You can define an endpoint api/v1/test and api/test and let them handle requests from different versions. But the module does not automatically handle versions, add v1 to your path or something like that. Maybe you can specify what you are trying to achieve here? Lastly, I must honestly state, that I am very busy with a very time-consuming project at work, which is why I do not find much time to work on module-updates. It will probably take until Christmas until i can put time into the project again. So if you understand the module's internal logic, I would be thankful for your pull-requests...1 point
-
Heck. I'm just going to modify the module so that all (or as many as possible) API parameters can be accessed/configured in the module. The developer should have as much control as possible.1 point
-
@netcarver 's answer pretty much covers this. My advice would be to watch out for anything involving counting, such as pagination and complex selectors using the Selector API.1 point
-
Wow thanks man! ? I already tried that, and it didn't work, guess I did something wrong, this worked fine ? Thanks! (Y)1 point
-
That's basically impossible for anyone to answer as there are so many other variables involved than just the row count and your machine specs. It will also depend on how much of that data needs to be loaded per page view, how many requests per second you expect to handle, will you be using caching, are there background updates happening, are the tables correctly indexed and using the most suitable storage engine, how many sessions will be active at peak, will you be triggering external API calls as part of the page views, what about asset loading - all assets optimised, and how often you'll need to be updating rows in the DB, do the pages involve JS rendering anything on the frontend etc. etc. I think you'd be better off setting a target for acceptable page loading times and then asking "What do I need to do to get 80% of my page loads to this time or better?" You also need to consider if PW's API is a good fit for your programming needs and if the Admin interface is suitable for you and any users who may need access to the admin. I'd suggest setting your speed goals and then trying an import of a subset of your data and then seeing how your resource needs and page speeds scale going from say 100 thousand to 200 thousand rows and then extrapolating from that. If you do try out PW, please keep us updated with your results.1 point
-
Hi @The G, thanks for noticing this behavior! During the development of PrivacyWire I never thought of showing or hiding divs or "regular" elements - only thought of scripts, videos, media ... So, good catch! I refactored that part of the priw_updateAllowedElement function to fix this bug. Cloning is required for everything, where media, scripts or other external stuff gets loaded... Waaaait a minute... While I was writing these lines of nonesense, I realized that this idea is wrong! ? You're right - keeping the elements alive and just update the attributes works for scripts, images, iframes and of course divs and other elements, too. I refactored again and tested the new version with all kind of elements and media... Only script tags need to be a new added element, as they will not run otherwise: https://html.spec.whatwg.org/multipage/scripting.html#script-processing-model 0.4.2 fixed it!1 point
-
I fixed that missing semicolon and made the translate method public and pushed it to dev- excellent feedback. Apologies for the missed semicolon and wrong parameter explanation. I was coding and pushing without testing since I wasn't able to do that at the moment. My goal is to make the Fluency->translate() method a more refined way to call the DeepL API. For instance, if you use the Fluency->translate() method, it will always account for the settings made in the module's PW config screen whereas a direct DeepL->translate() call won't. There could be advantages to using either depending on your use case, but the methods will also always take the same arguments so that either can be used interchangeably and predictably. And- as you noted, calling the Fluency->translate() method requires no manual API key insertion. I personally don't like having to stuff empty arguments into a method call, like how you had to provide an empty "[]" array before adding the config argument. The ignored strings array may be something I merge into the config parameter. It makes sense to me since if you're calling the Fluency->translate() method and have ignored strings configured then you might be passing an empty array more often than not, or the DeepL->translate() method and do not require ignored strings. This may be a breaking change coming up, so I'll post back here when that gets pushed to master. I want to do some more research on the preserve_formatting parameter and consider if it should be set to true by default. Since we're working with CMS input there should be a level of expectation that the translation service does not try to correct the user but rather deliver a more direct translation which would prevent the situation you saw. Overall, if there's anything set by default in the module I want to add a config screen toggle for it so that the developer can make the ultimate choice and be able to control how the module works.1 point
-
Yes!! Thank you, that's exactly what I need. I can also leave away the userid/created_users_id check that I had in my template php-file. The hook is also providing for that. Thanks again for this very educating reply (for me at least).1 point
-
Just wondering if the translate method in the Fluency class should be public so we can call the translate method more easily. I made that change locally, and now I can do: As you can see, now I can load the module and call translate directly, without the need to get and apply the API key. I guess this has more overhead but not really sure if it is significant. What do you think?1 point
-
@adrian I just pushed an update to the dev branch. It adds a 4th parameter to the translate() method in both Fluency and DeepL classes. You can pass a key/value with any additional DeepL API parameters to experiment with. There's a DeepL API parameter called preserve_formatting, and by default it is off- so it will try to correct punctuation. Try the dev branch and update your call with this then pass it the string that was giving you problems and see if it helps: That should tell DeepL to stop trying to correct you. Let me know if that does anything for you.1 point
-
Yep. That's a proper syntax to make a call. The text string for translating can also be an array of strings (either/or) which will be returned in the same order as you submitted, good for bulk translation. The DeepL class is and will be wrapper for the DeepL API so it should be as predictable as using it directly. The added period is not something I've seen during my usage so unfortunately I don't have experience. We've been translating one and two word strings, such as text for buttons, and they've never come back with any additional punctuation. The API has additional parameters which seem to be much more granular but I wanted to see how basic translation works out for PW implementation and then add additional features as necessary rather than fully integrating the API with things that would go unused. Also, since you're calling the API directly, you can wrap text to be ignored like this: <fluency-ignore>Don't translate me!</fluency-ignore> That's what's used in the DeepL class to ignore strings configured in PW. If you add them yourself the DeepL class will remove them automatically after translation.1 point
-
Hi @ryan, The new modules directory is looking great and what I've used so far has worked great ? I've a request for you to consider. Would it be possible to mark major version changes as not backwards compatible? The use case: We have a module PageimageSrcset, that contains a number of features that I thought would be useful at the time of writing, but I myself have never/rarely used (e.g. generating the sizes attribute value from an array of UIkit classes). In a future version I'd like to remove these features, and have the module be more in line with its purpose. I have enquired on the board, but not had any response to say that any of the features are being used. The solution as I see it, would be to release a new 2.0.0 version (currently 1.1.0) which removes these features, and any users with 1.1.0 installed would either not be able to upgrade directly (would require manual upload), or would be given an additional warning that the version introduces breaking changes and to check GitHub/support board before upgrading. Is this possible? Cheers, Chris1 point
-
I don't think you can do counts aggregated columns with ProcessWire selectors. There's Pages::count of course, but that only returns a single count. This isn't the most efficient solution, but should be fine for a couple hundred or thousand pages: $results = $pages->find('template=your_template'); $years = array_filter(array_map(function ($p) { $year = $p->getUnformatted('your_date_field'); return $year ? wire('datetime')->date('Y', $year) : null; }, $results->getArray())); $pagesPerYear = array_count_values($years); Below that you'll have to use raw SQL I think. Might also be possible with RockFinder3, not sure (@bernhard?)1 point
-
Today, I am glad to announce that the module support the native image field ??1 point