Jump to content


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by dragan

  1. You don't need PHP at all. I'd suggest to use Google Optimize (and a linked Google Analytics account where you set up your goals) instead. Here's a nice tutorial. (you can skip more or less to step 3 "Create an Experiment" - and make sure you also include the "anti-flicker" stuff at the end of step 2)
  2. I agree too that this should be added to the styleguide, and I also configured my IDE to strip trailing whitespace on save. However, if we're talking about diff tools, it's just as easy to configure them to ignore whitespace (and even empty lines). PHPStorm Git has the option --ignore-whitespace you can use. VSCode: File => Preferences => Settings => Diff Editor => Ignore Trim Whitespace.
  3. @joshua Nice! Thanks for sharing. Can this module be used for multi-lingual sites? i.e. If I wanted to translate the banner texts and labels, is that possible out of the box? Or would I have to manually re-define the module's text fields as text/textarea language?
  4. OMG... wish I knew that some such shortcut existed before.
  5. @wesp Well, that ain't so easy. If you wanted to make it behave like that - and make sure you don't break user's back-button in the process, and make sure people actually scroll to the section if they share/bookmark such a pseudo-link - you should use an SPA framework like Vue instead, where you have such custom routing functionality already built-in. otoh, it's quite easy to hide / remove the #section1 completely from the location bar - but that's not what you're after.
  6. @wesp You don't need the Functions API for the functionality you asked for - it's just the syntax Zeka used that requires it, e.g. pages() instead of $pages etc. I have tried this combination here, and it works fine: // at the very top of home.php if ($input->urlSegment1) { $pagename = $input->urlSegment1; $match = $pages->findOne("template=article, name=$pagename"); if (!$match->id) { throw new Wire404Exception(); } echo $match->render(); return $this->halt(); } // site/ready.php // taken from this great case study: https://processwire.com/talk/topic/3987-cmscritic-development-case-study/ wire()->addHookBefore('Page::path', function($event) { $page = $event->object; if($page->template == 'article') { $event->replace = true; $event->return = "/$page->name/"; } }); If you copy-and-paste, pls note that my template is called 'article', not 'article-page' ? Attached also the home template URL segment settings.
  7. @uncle_bobson Another way to achieve more or less the same thing, is to use PW's markup cache. Perhaps not suitable if you have intervals of just seconds, but for other use-cases. Of course, that approach won't help if you expect the data to update without page-refresh. But maybe helpful if you have a lot of traffic, and want to reduce "behind-the-scenes" queries.
  8. @nabo What's your use-case? From a security point of view it's not a good idea to allow everything. Surely you have an idea what kind of file-types will be used? I found another forum thread where basically the same question was asked, and the gist of it was: No, you can't. Leaving the allowed extension config list empty makes it unusable, and just entering a wildcard * won't work either. @ryan takes security matters very seriously, and personally, I wouldn't want to have such a "everything goes" option built-in the core, too. If you have to, for some reason, import data from another system, and create / populate fields via API (batch actions), you can temporarily allow each file extension that comes your way, and then switch back to a "normal" default set after save. But I guess you were asking about using the GUI options.
  9. basic example / ideas: document.addEventListener("DOMContentLoaded", function (event) { const trackedLinks = document.querySelectorAll("#content a"); // adjust selector as needed trackedLinks.forEach(function (n) { n.addEventListener("click", function (e) { e.preventDefault(); const href = e.target.getAttribute('href'); console.log(href); // api = special page with tpl and URL-segments enabled: fetch(`/api/linktracker/?url=${href}` , { method: "GET" }) window.location = href; }); }); }); (That's vanilla JS / ES6) if ($input->urlSegment1 === 'linktracker' && isset($_GET['url'])) { $url = trim($_GET['url']; // save to a textarea inside PW: $pg = $pages->get("123"); $pg->of(false); $pg->linktracker = $pg->linktracker . "\n" . $url); $pg->save(); // save to a custom DB table: $myDB = new PDO("mysql:dbname=linktracker;host=localhost", "root", "******", array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'")); $trackLinkQuery = "UPDATE tablename SET click_count = click_count + 1 WHERE url=`$url`"; $query = $myDB->prepare($trackLinkQuery); $query->execute(); // udpate a text-file file_put_contents('path/to/file.log', $url); // if those links are saved inside repeaters or similar, add one int field that you can increment / update: $pg = $pages->get("123"); $pg->of(false); $pg->linktracker = $pg->linktracker +1; // or whatever / wherever your field is.... $pg->save(); } These are 4 basic ways how you could handle it - there are certainly more ? Hope that gives you some ideas.
  10. That's a classic use-case for Google Tag Manager. But you can do it yourself with a bit of JS + PHP. Basically: assign a CSS class to these links, and write a litte function that posts the link href attribute to a PHP script, which in turn updates a field in PW.
  11. Indeed. It once took me ages to find out why. Since then I keep it installed, but only activated for certain templates ?
  12. Well, you can build just about anything with any (or without) frameworks. Now I'm even more confused. You certainly don't need PW just to "send JSON files". Perhaps you'll get more productive tips and pointers if you describe what it is that you are actually trying to achieve. That's as vague as it can get. So it's now PW, but... what? Perhaps you should take some time and describe what you actually need to accomplish. And what this "backend" looks like (technically).
  13. @manlio If you want to enhance PW's backend, you're free to use whatever you find useful. Depending on the actual task / use-case, adding Vue.js or a similar SPA framework may be overkill. But if you need to build a fancy dashboard / complicated admin pages, then Vue can perhaps add some nice extras. Care to elaborate on this? You mean "where should these extra frontend assets be stored?" Typically under site/templates. Static assets maybe rather in site/assets/. Make sure to check out @bernhard's epic tutorial about building your own PW module / dashboard. There's a lot of stuff "under the hood" to discover, with functionalities already available out of the box. So if you think about building something along those lines, adding a big JS framework might be overkill, too. Generally speaking it's best to get a solid grasp of vanilla JS. Frameworks tend to make you lazy - e.g. when you're using frameworks to solve problems that vanilla JS can solve just fine by itself. A little recommendation: Here's an excellent tutorial where you learn (among other things): Nuxt Vue.js Dynamic routing (pages, categories) Axios Frontend communicating with a headless CMS (I have re-written the relevant code-bits to work with PW instead of Cockpit) Dynamically setting title tag + meta (stuff that some frontend devs often don't care about - but your customer surely will) Deployment on Netlify (not that I would actually need that - but I guess it's nice to know what the fuss is all about) I skipped several parts... Markdown, Tailwind... and I'm only done with half of it. But it's fun to see how easy it is to have PW generate one or two JSON files, and you're good to go (especially when you have a PW site already with lots of content to play around with). It depends if you really want to learn about all these things ("Developing website is not my primary job"), but it can't hurt.
  14. Sorry, I know it's beta, I read (and can only imagine) how much work was involved. And as I stated before, it really is a nice touch to have that luxury of installing a few test pages instead of having to create them manually from scratch - just with a few clicks. And I was seriously impressed by the feature-set, the dashboard etc. However, uninstalling a PW module (no matter how big, if free or commercial) shouldn't be something that takes more than 2-3 minutes. I'm probably spoiled, but I just thought I'd mention it here anyway.
  15. @Gadgetto OK, since I don't really need any kind of shop solution, I decided to uninstall SnipWire. That was... an unpleasant experience. This took me about half an hour. The regular module uninstall routine didn't work for anything SnipWire-related. There were warning about pages or fields or templates having the system-flag. The page under admin > setup was undeleteable. In the end I had to delete two pages that were in the trash directly in the database. I hope there is nothing else left in the PW installation now in some hidden corners...
  16. @tpr I don't remember if I have posted this already some time ago... The option "disable all admin animations" practically makes the vec-dialogs unusable. The dialog will appear, but won't disappear when you choose either of the options. You then have no choice than to hard-reload the page. Maybe a word of caution would be nice in the settings. I stumbled over this a long time ago, and recently forget how to fix it.
  17. hmmm, so I rewrote the templates, and made sure the three required frontend assets are loaded (Snipcart JS + CSS + jQuery), but it looks completely un-styled, and there is no quantity-stepper anywhere. I've even added UIKit CSS + JS now... it looks a bit different, but still... far from the screens you posted. Maybe I'll try on a new PW installation with the regular profile. While it's certainly nice that you provided such a test-setup with templates and dummy products, I think it shouldn't be dependant on what site profile you used when installing PW. If I inspect certain elements that have classed, I don't see any style definitions. But maybe the problem is elsewhere... here are the (probably) relevant settings on the product page: But I guess what I see is "stackable" variety... When I inspect the button, I see: <button class="snipcart-add-item uk-button uk-button-primary" title="Add to cart" aria-label="Add item to cart" data-item-name="Axolotl Juicer" data-item-id="JUICER_123" data-item-price="{&quot;chf&quot;:&quot;10&quot;,&quot;eur&quot;:&quot;8.50&quot;,&quot;usd&quot;:&quot;10&quot;}" data-item-url="http://pw.test/en/snipcart-shop/axolotl-juicer/" data-item-description="Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." data-item-image="http://pw.test/site/assets/files/23131/beer3.65x65-hidpi.jpg" data-item-metadata="{&quot;id&quot;:23131,&quot;created&quot;:1581076192,&quot;modified&quot;:1581078285,&quot;published&quot;:1581076192,&quot;created_users_id&quot;:41,&quot;modified_users_id&quot;:41}" data-item-quantity="1" data-item-quantity-step="1" data-item-stackable="false" data-item-taxable="true" data-item-taxes="CH" data-item-has-taxes-included="true" data-item-shippable="true"><span uk-icon="icon: cart" class="uk-icon"></span> Add to cart</button> but no quantity stepper markup anywhere.
  18. OK, I guess it has to do with what you mentioned earlier: I am using delayed output... Guess I have to rewrite the test templates.
  19. Well, the first thing that springs to mind is: Can I add a quantity in the frontend? I don't see a possibility to change the quantity either in the cart (select or number input field, or stepper). btw: I got a JS error re: jQuery - I had to remove the jQuery integrity hash from the module settings
  20. Thank you. I'm using the multilanguage as base... getting the _uikit.php from Github did the trick!
  21. @Gadgetto First of all a big thank you for creating such a module! I have installed it just now for the first time. I followed the installation / configuration steps, defined templates etc. But in the frontend I get an error when trying to access mysite.com/snipcart-shop/ Any ideas what went wrong? I'm using latest PW dev, and AdminTheme UIKit is installed + active.
  22. try has() $segment = $sanitizer->int($input->urlSegment1); if($allguests->has($pages->get($segment))) { echo "yep"; }
  23. I'm not sure what the missing piece of the puzzle is. But I managed to put together a similar setup in a few minutes, and it all works as expected. Perhaps you can compare your setup with mine and you'll find out what you're missing. Here's what I did: Create a role "member" Create a login page with template "login". In that tpl I basically have if($user->isLoggedin() && !$input->get('profile') && !$input->get('logout')) { $goto = $pages->get(23115)->url; // the restricted page $session->redirect($goto); } else { echo $modules->get('LoginRegister')->execute(); } I'm too tired atm to write the rest all down, but here are screenshots. I'm not sure if a separate role than login-register is really required, but it's likely that login-register is going to be used by more than one user-type, and I guess it's good practice to handle permission stuff as granular as possible, to avoid headaches down the road.
  24. It's a shame though he doesn't allow search engines to index the site: https://pwgeeks.com/robots.txt </derail>
  25. I'm not surprised, actually. Most people have never heard of it, and if they did, were only more confused than before. btw, how are you tracking PWA installs? With Google Tag Manager or similar?
  • Create New...