Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/06/2017 in all areas

  1. Good point - then simply do this: $e = class_exists("\ProcessWire\HookEvent") ? new \ProcessWire\HookEvent() : new HookEvent(); I know that feeling very well - rest up!
    4 points
  2. Just another way in case someone finds this thread and needs an alternative HTML output. There's also a 'currentItemClass' setting which I had to use when I had this exact same problem, those spans being in there were an issue. With an active class on the list item or the anchor tag they are unnecessary. I tried to find a way to just remove them but ended up doing this instead. Also using BS4, except I did it like this (using BS4 variables + extending a custom border class): <div class="pager-nav pb-5"> <?php echo $entries->renderPager(array( 'nextItemLabel' => "Next", 'previousItemLabel' => "Prev", 'listMarkup' => "<ul>{out}</ul>", 'itemMarkup' => "<li class='{class}'>{out}</li>", 'linkMarkup' => "<a href='{url}'>{out}</a>", 'currentItemClass' => "active" )); ?> </div> and the styles: .default-border { border: $border-width solid; border-color: $card-border-color; border-radius: 10px; } /* Pager */ .pager-nav { display: flex; justify-content: center; ul { display: flex; list-style-type: none; margin: 0; padding: 0; @extend .default-border; li { flex: 1 1 auto; &.MarkupPagerNavFirst a { border-radius: $border-radius 0 0 $border-radius; } &.MarkupPagerNavLast a { border-radius: 0 $border-radius $border-radius 0; } a { font-weight: bold; font-size: $font-size-base * 0.9; color: $gray; background-color: $white; display: block; padding: 0.5rem 1rem; } &.active a { background: $main-color; color: $white; } } } } ...outputs: ...html output: <div class="pager-nav pb-5"> <ul> <li class='active MarkupPagerNavFirst MarkupPagerNavFirstNum'> <a href='/processwire-tutorials/'> <span>1</span> </a> </li> <li class='MarkupPagerNavLastNum'> <a href='/processwire-tutorials/page2/'>2</a> </li> <li class='MarkupPagerNavNext MarkupPagerNavLast'> <a href='/processwire-tutorials/page2/'>Next</a> </li> </ul> </div> It's a different approach so I think it's worth sharing.
    4 points
  3. Add this to the array: 'currentLinkMarkup' => "<a class='page-link' href='{url}'>{out}</a>",
    4 points
  4. I will add this check, it make sense to me. Also it might be worth to check if the backup destination is being included - e.g. the destination is in the webroot but not excluded - then if yes, the warning appear, as the package will be saved and the ZIP file will grow. As you said, the last package will be saved and the oldest package is removed if the limit is reach. Now I am thinking to make those two settings checking each other giving the priority to the "Remove backup packages older than" setting. I will test it more closely as I would like to keep the compatibility to ProcessWire 2.x in case some people want backup their pw2 website for an eventual upgrade. My brain is overheating today, I'll read again your comments into an hour or so
    3 points
  5. Quick update: there's now a 2.0 branch and 2.0 milestone for this module at GitHub. For the time being the 2.0 branch is identical with master branch, but it's a start. I'm going to get another project I've been working on out there today, and after that I should have some time to work on VersionControl 2.0
    3 points
  6. There are as always Pros and Cons about using a CDN. One of the thing I like with CDN is the multiple-request capability. But on other hand, in a security point-of-view, using a CDN if you are paranoïd will make you crazy knowing that someone could modify the delivered JS code to collect data from your users...
    2 points
  7. Same here. Also, I like to minify + concat everything and deliver just one css and one js file. (AIOM is handy for that, or you can use any Grunt/Gulp task for that) But when I'm in the early stages of setting up a site / app, or just want to play around with different libraries, I usually load everything from CDNs. Also, when it comes to upgrading frontend assets, I don't monitor every new release and run for the latest version. Priority number one is stability. Only when there's a good reason (security bugfixes or major new features that I know I will use), I upgrade JS stuff.
    2 points
  8. My approach for reliably sending out system-based/transactional emails is to signup for Mailgun.com. It's free if you're sending out less than 10,000 emails per month. It will require you to put a credit card on file. I then use the Swift Mailer module to customize the SMTP settings and such: https://modules.processwire.com/modules/wire-mail-swift-mailer/ Make sure to setup the TXT records as well that Mailgun recommends. For example, if your site uses G-Suite for regular email and Mailgun for transactional emails, then this is what you'd need (refer to what Mailgun tells you upon signup; replace the IP with your server IP address, or adjust accordingly): v=spf1 ip4:123.456.789.123 include:_spf.google.com ~all v=spf1 include:mailgun.org ~all I've found this method to be extremely reliable, quick, painless and I like that the account is not tied to what might be a site's overall email system like G-Suite. It keeps things separate to prevent situations like this. (definitely read that link)
    2 points
  9. There are also a few javascript based wizards you could use, such as jquery smart wizard, steps, form to wizard, etc. Depending on your needs, you can use processwire to create the appropriate data for whichever wizard, and then save and track the results.
    2 points
  10. Hi, yes you can work with simple repeaters for all questions of a form. For yes/no answers you can use a pagefield or fieldtypeoptions (pagefield would be more flexible if you need more features)... So you could render the form inputfields from the repeater field on frontend. You are on the right track. Best regards mr-fan
    2 points
  11. @drjones, you could add a "sort_name" field (hidden perhaps) to your template to store the number with leading zeros added. You would populate this field in a hook to Pages::added in /site/ready.php $pages->addHookAfter('added', function(HookEvent $event) { $page = $event->arguments(0); if($page->template == 'stick') { $page->setAndSave('sort_name', str_pad($page->name, 8, '0', STR_PAD_LEFT)); } }); Then you would use the sort settings of the parent page to sort its children by sort_name.
    2 points
  12. For fun, you could also create a wp-login.php file in your PW root directory so that hackbots get confused (or redirected away, or just show a blank page). Here's an example of some random website that implements this technique: http://processwire.com/wp-login.php If you've ever looked at a website's access log files, you'll see that that URL is hit all the time. Easy way to prevent a bunch of 404s.
    2 points
  13. Not really at the moment. Just an idea JWT is just a communication system. If you look at the profile is the Processwire auth system that is used at the end. Instead of using oAuth or Basic Authentication JWT can be used for getting user roles and data without requiring to log in the user on every request, saving server resources
    2 points
  14. @flydev - I set up the system cron last night and didn't think too much about, but checking today I see that it didn't work. It turns out the issue is: $e = new HookEvent(); You just need to add the ProcessWire namespace to the top of the cron.php file and everything works as expected.
    2 points
  15. I've just recently used barba.js when relaunching the frontend of https://www.priotas.de/ (a processwire based website). As teppo mentioned: That's pretty much what you're looking for.
    2 points
  16. here is the blogpost just for reference https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/
    2 points
  17. This week we have a guest post from Bernhard Baumrock that is a nice introduction to creating Process modules in ProcessWire. Bernhard covers a lot of useful material here and we hope you enjoy it. Big thanks to him for his contribution this week. I've been traveling (Ryan) for the last two weeks, but arrived back in town last night, so next week we'll be back to our regular PW core updates and schedule. https://processwire.com/blog/posts/building-custom-admin-pages-with-process-modules/
    2 points
  18. If you have an array from wire/config.php like the imageSizerOptions: $config->adminThumbOptions = array( 'width' => 0, // max width of admin thumbnail or 0 for proportional to height (@deprecated, for legacy use) 'height' => 100, // max height of admin thumbnail or 0 for proportional to width (@deprecated, for legacy use) 'gridSize' => 130, // Squared grid size for images (replaces the 'width' and 'height' settings) 'scale' => 1, // admin thumb scale (1=allow hidpi, 0.5=always hidpi, 1.0=force non-hidpi) 'upscaling' => false, 'cropping' => true, 'autoRotation' => true, // automatically correct orientation? 'sharpening' => 'soft', // sharpening: none | soft | medium | strong 'quality' => 90, 'suffix' => '', ); and you then attach a new array to $config->imageSizerOptions with a smaller set of key/value pairs, you wipe out: width, height, gridSize, scale, upscaling, autoRotation, suffix. Besides using PHP function array_merge, you also may use this to override your desired keys without deleting the others: (THE FOLLOWING IS WRONG)
    1 point
  19. Thank you Adrian, this is what I need. I've long forgotten about it even though I did read your post. I've just refactored my code to take advantage of it and everything works as expected, great module as always! As for $u->sendEmail = true; I do not need it because my frontend form is not for creating new users but for sending an email to existing users. Why sending the same email? Because already registered users might have long forgotten how to login to the system so I want to send the same instructions no matter what. I will probably introduce a slight difference based on some simple logic but most part of the email body will be the same. For this reason I use the hook to completely overwrite $htmlBody which I find easier to implement than using str_replace and such to change something created in the RTE.
    1 point
  20. The js wouldn't be loaded from that url, but from another url, so more dns resolvement and traffic from another server. Same like dragan I go for stability and not for every latest and newest.
    1 point
  21. The problem I see with your approach is that you need a new field for each question - I actually did this on my first ever PW site - it works, but it's a lot of fields to maintain and requires a dev to add new questions. If you make each question a page, then anyone can add new questions. I would also be worried about that lister view - won't there be a lot of horizontal scrolling if there are lots of questions?
    1 point
  22. Hi @szabesz - if I understand correctly, I think you could make use of this module instead of your custom site_email_user_login_info() function. Via the API you can use: $u->sendEmail = true; If you need to adjust the body of the email (both via admin and frontent/API), you can hook into: EmailNewUser:: parseBody - you could add your own logic for dynamically building the http://example.com/?user={id}&token={login_token} link without hardcoding anything. https://processwire.com/talk/topic/7051-email-new-user/?do=findComment&comment=136252 Let me know how you go.
    1 point
  23. On a sidenote jwt is perfect when things need to "scale" (i.e. in a microservice architecture). Just share the secret across multiple instances and you don't have to care about syncing sessions and related data. The backend thus can be "stateless" (regarding logins) and just used to deliver data.
    1 point
  24. 1 point
  25. If you have a working Apache webserver where the site runs without issues, you could try converting its htaccess file to web.config. Here are some resources : https://blogs.msdn.microsoft.com/azureossds/2015/04/23/converting-apache-htaccess-rules-to-iis-web-config-using-iis-manager-for-azure-websites/ http://cbsa.com.br/tools/online-convert-htaccess-to-web-config.aspx If you are able to browse to these locations, you should definitely try and have a look at the logs> https://stackoverflow.com/questions/6426375/where-can-i-find-the-iis-logs
    1 point
  26. It's not necessary, just one way of authentication. Basic Auth is perfectly fine aswell
    1 point
  27. Hi flydev, I'm so stu... my brain must had been behind the moon yesterday. That's for what I've searched some time. It's so simple and the solution so near. Thank you, you have solved my problem.
    1 point
  28. @Robin S, that did the trick. Thank you.
    1 point
  29. A little information for the observers here: The feature to view a secret file beside the forced download is now available in version 1.0.3. Thanks @Macrura! I introduced an additional setting on field level to toggle the "View" possibility. Cheers
    1 point
  30. Hi Jonathan, thank you for your answer. That solved the problem! The code looks now like this: echo $images_posts->renderPager(array( 'nextItemLabel' => "Vorwärts", 'previousItemLabel' => "Zurück", 'listMarkup' => "<nav aria-label='Page navigation'><ul class='MarkupPagerNav pagination'>{out}</ul></nav>", 'itemMarkup' => "<li class='{class} page-item'>{out}</li>", 'linkMarkup' => "<a class='page-link' href='{url}'>{out}</a>", 'currentLinkMarkup' => "<a class='page-link' href='{url}'>{out}</a>" ));
    1 point
  31. Welcome to the forums @adiemus The description field is named "description" and you can include it as a subfield of an images field in your selector. So for a repeater field named "repeater" containing an images field named "images" your selector would be something like: $matches = $pages->find("repeater.images.description~=foo");
    1 point
  32. Mystery solved: https://github.com/processwire/processwire-issues/issues/430
    1 point
  33. The resolution to this: https://github.com/processwire/processwire-issues/issues/430
    1 point
  34. Sorry, I forgot that Duplicator of course also handles DB backup
    1 point
  35. Got to agree with @Pixrael. While page.js seems nice, it's probably overkill in this case, and since you already have ProcessWire to provide routing, it makes sense to just add JavaScript-powered transitions on top of that. I've used http://barbajs.org/ in the past for this purpose. As a bonus compared to pure JavaScript approach you won't have to worry about search engines, non-JS enabled browsers, etc. as they'll still get the "regular page load experience"
    1 point
  36. processwire already makes it very hard for attackers to just guess username+password. and you can even adjust those settings:
    1 point
  37. maybe using hooks and url segments you can throw a 404 if someone visit /admin (trying to guess) but show the login form if they visit /admin/123PIN with a secret PIN for editors..
    1 point
  38. i have a similar need, and have a 'roll your own' pagetable setup, using Runtime Markup; i think once i implement the Datatables Editor (if that ends up being possible), it will be really cool, and much less screen-estate than a repeater interface.
    1 point
  39. Glad I read through this thread, Robin S's version works great! Thanks so much.
    1 point
  40. Hi @Vigilante Take a look at this page to find out all available options how you can build your URL https://processwire.com/api/ref/page/url/ You can get current URL by $input->url and get current URL with query string by @input->url(true). Take a look at this https://processwire.com/api/ref/input/url/ and https://processwire.com/api/ref/input/query-string/
    1 point
  41. Hi @Vigilante $selector = "template=category"; if($var) { $selector = "template=category, field=$var"; } $arr = $pages->find("$selector");
    1 point
  42. I know this is an old thread, but if someone finds this, I also would absolutely recommend this module if you're working with tagging pages: I use it on pwtuts.com and it makes it very easy. In the footer of the aforementioned site, there is a tag list, which is pulled from this file /includes/tags-list.php: <?php namespace ProcessWire; ?> <h2>Tags / <a href="/tags/">See all</a></h2> <ul class="tag-block list-unstyled"> <?php $tags = $pages->get("/tags/")->children; foreach ($tags as $tag): if (count($tag->blogPosts)): ?> <li>#<a href="<?= $tag->url; ?>" class="<?= $tag->name; ?>"><?= str_replace("-", "", $tag->name) ?> (<?= $tag->blogPosts->count ?>)</a></li> <?php endif; endforeach; ?> </ul> ...because the blogPosts fields are connected to the tags, it's just a case of using count() on the tag i.e. if it has page ref fields (blogPosts), print them. Count is used again to output how many posts are associated with each tag. This would have been more awkward for sure without this module, you'd have to get each tag, then find the number of posts that have that tag etc...
    1 point
  43. If using the old style, what you need is the method getModuleConfigInputfields(). I think it used to be a static method so no $this, etc, but that could have changed at some point I. Here's how we do it in the Blog module (static method). For that specific case we jump through a couple of hoops but it need not be that complicated in normal use. You can also look at other examples to get the gist of it (e.g. Tracy, [non-static method] and some core modules. Invariably, these will be Process modules, e.g ProcessPageSearch.). Your module will have to implement the ConfigurableModule interface. The Module interface is a good read.. In the links above, see also the code for retrieving saved values. Here are some old links on this topic: Possibly related Edit: see next post if you already know above; my bad; just re-read your post.
    1 point
  44. thank you all, we decided to go for an automated page creation through a json import script. a dear friend helped me with this. perhaps some one in the future stumbles across this topic and finds this helpful, below the import script <?php $TEMPLATE_COUNTRY = "country"; $TEMPLATE_REGION = "region"; $TEMPLATE_SUPPLIER = "supplier"; $TEMPLATE_WINE = "wine"; $rootid = wire('pages')->get('title=wines')->id; // All Wines: $file = "./lijst.json"; $raw = file_get_contents($file); // clean: replaces newlines in strings with \n and some other $raw2 = preg_replace('/\n(\w*)([^ \t\]\[{}"])/', '\\n$1$2', $raw); $data = json_decode($raw2, TRUE); $wines = $data['data']; // trash country pages + children before import $pages = wire('pages')->find('template=' . $TEMPLATE_COUNTRY); foreach($pages as $p) { $p->trash(); } foreach($wines as $wine) { // do the country pages $country = $wine['country']; // create new page is not exists $country_pages = wire('pages')->find('title="' . $country . '"'); if ($country_pages->count == 0) { $country_page = new Page(); $country_page->template = $TEMPLATE_COUNTRY; $country_page->title = $country; $country_page->parent = $rootid; $country_page->country_text = $wine["country_text"]; $country_page->save(); } // update exsiting else { $country_page = $country_pages[0]; } // do region pages $region = $wine['region']; if (!$region) { $region = "Other"; } $region_pages = wire('pages')->find('title="' . $region . '"'); if ($region_pages->count == 0) { $region_page = new Page(); $region_page->template = $TEMPLATE_REGION; $region_page->parent = $country_page->id; $region_page->title = $region; $region_page->region_text = $wine['region_text']; $region_page->save(); } else { $region_page = $region_pages[0]; } // do supplier pages $supplier = $wine['supplier']; // outlyer: wine without region ... should fix in source json if (!$supplier) { $supplier = "Other"; } $supplier_pages = wire('pages')->find('title="' . $supplier.'", parent='.$region_page->id); if ($supplier_pages->count == 0) { $supplier_page = new Page(); $supplier_page->template = $TEMPLATE_SUPPLIER; $supplier_page->parent = $region_page->id; $supplier_page->title = $supplier; $supplier_page->supplier_text = $wine['supplier_description']; $supplier_page->save(); } else { $supplier_page = $supplier_pages[0]; } // do wine pages $wine_page = new Page(); $wine_page->template = $TEMPLATE_WINE; $wine_page->parent = $supplier_page->id; $wine_page->title = $wine['wine']; $wine_page->wine_text = $wine['wijnomschrijving']; // same wine ... multiple years $year = $wine['year']; if (!$year) { $year = ''; } $wine_page->year = $year; // add 00s after comma if not there $price = preg_replace('/\.[0-9]$/', '${0}0', ''.$wine['price']); $price = preg_replace('/^[0-9]+$/', '${0}.00', ''.$price); $wine_page->prijs = $price; $wine_page->save(); } ?> curious to hear if any one wants to improve/comment on this thanks again!
    1 point
  45. This is an interesting point that could fit very well, thank you. I'll try to include that in my post btw, the first two points are already finished.
    1 point
  46. I have a forked version at https://github.com/matjazpotocnik/ProcessWire-AIOM-All-In-One-Minify that includes a lot of pull requests and fixes from several contributors. Test on dev site first!!!
    1 point
  47. This seems to work $implements = wireClassImplements($field->type); $isMulti = in_array('FieldtypeLanguageInterface', $implements); // OR $isMulti = $field->type instanceof FieldtypeLanguageInterface; Adapting to your code: $data = []; foreach ($page->template->fieldgroup as $field) { // check if field is multi language if ($field->type instanceof FieldtypeLanguageInterface) { continue; } $data[] = $field; } return $data;
    1 point
  48. I normally store my page references in a section of the main website page tree. I give this section a name that contains the word "Configuration ". I also store the results of Page Tables in this section.
    1 point
  49. i mainly use the options fieldtype for non relational type selects with huge numbers of options, such as countries, cities, states, and such where i just don't want those things showing up as pages..
    1 point
  50. Try: $mail = new \PHPMailer(); The backslash at the front tells it not to use the ProcessWire namespace
    1 point
×
×
  • Create New...