Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/16/2020 in all areas

  1. Hey there! Just wanted to drop a quick comment ? SearchEngine provides two built-in methods for search form rendering: Highly customizable "basic form". You can probably get the best idea of this by taking a look at these lines in SearchEngine.module.php. I'd actually be surprised if there's something you can't customize. Less customizable (unless you really enjoy hooking into form rendering) "native ProcessWire form". I know that some folks prefer these (I don't), so I thought it would be a nice addition. ... and, of course, you don't have to use either one. Bring your own markup. SearchEngine doesn't really care about the form — there's no CSRF or anything involved, it's just a search feature ? As for the results list, there's the "easy way" where you let SearchEngine handle everything for you. Again, this is quite customizable via config settings and hooks, if you've got something specific in mind. JSON is also an option, but this is mostly intended for cases where you want to utilize SearchEngine as a part of an API, or perhaps create a fully customized JS search form feature. The biggest things lacking form SearchEngine (in comparison to tools like Meilisearch, or more heavy-weight indexers such as Solr, Elasticsearch, RediSearch, etc.) are the ability to normalize queries, perform complex lookups from the index (SE is basically just using ProcessWire's selectors and that's it), smart weighting of results based on relevance (this is on my to-do list), and perhaps really snappy real-time results (you can perform asynchronous queries, but they go through your site, which means that they have some overhead; tools like Meilisearch can do this much more efficiently). Anyway, just wanted to let you know that there are different options there. I don't actually know your case well and can't say if SearchEngine is the correct solution, but if it's UI level customization you're after, that shouldn't be an issue. And if it is, please let me know what's missing and I'll be happy to take a closer look; perhaps it's something that others might find useful as well ?
    4 points
  2. BETA: SplashAndGrab https://github.com/madebymats/InputfieldSplashAndGrab This module attaches a search input to selected image fields that lets you search and download images from Unsplash. (Unsplash is a stock photo service where you can download images for free and use as you wish. No strings attached.) You can search by string, colors, orientation/crop and order by relevance or time published I find Unsplash useful both for placeholder images when building sites but also as a time saver for editors if they don’t have any images at hand, just search, download and publish. Thanks to @apeisa for building the FlickrInputField Module and @Robin S for AddImageUrls, took a lot ideas and code from those modules.
    3 points
  3. One thing is to load the search result in memory on PHP side on a $pages->find, another is render the HTML in the browser. There's no way to render a HTML node tree of that size without some solutions like image lazy loading through a script, especially on mobile browsers. Nowadays it's partially supported natively, but for most cases you need to rely on Javascript. Google Images loads more images as you scroll the page, you can see this better if you slow down your connection using Chrome Devtools, for instance.
    3 points
  4. There's no need at all to understand the PW architecture or database structure and relations - or even to think about these things. Stick to using PW selectors (https://processwire.com/docs/selectors/) and all the hard work is done for you. Selectors are one of the really great features of PW! (Note that if you later decide to use RockFinder for the extra speed, it also understands the PW database structure so that you don't have to.)
    2 points
  5. = I have not thought about that, but it's a good idea and easy to implement. = I have not thought about that and I'm not willing to add any other services. ? ?
    2 points
  6. Hah, I had forgotten this one. SplashAndGrab looks (and sounds) great!
    2 points
  7. In the near future I plan to study on using Teppo's module to build an index directly to a Meilisearch instance running on the same server. I used it on a recent Laravel project and, although I only scratched the surface of its capabilities, the partial match and typo toleration is worth a try IMHO. Also it was a breeze configuring it.
    2 points
  8. There's also this cool module by @teppo that let you create a search index to speed up things immensely on some cases. https://modules.processwire.com/modules/search-engine/
    2 points
  9. Note that legislation may differ from country to country. For an example here in Finland one apparently still has to document the cookies, even though "necessary" ones don't require opt-in (or opt-out). IANAL etc. but that seems to be the common consensus anyway ? Here's a rough translation of the descriptions we've been using: wires ProcessWire session identifier. First-party session cookie, expires when the browser is closed. wires_challenge ProcessWire session cookie used to verify the validity of a session. First-party persistent cookie, expires after 30 days.
    2 points
  10. I've been using Fathom Analytics for a while now and on a growing number of sites, so thought it was about time there was a PW module for it. WayFathomAnalytics WayFathomAnalytics is a group of modules which will allow you to view your Fathom Analytics dashboard in the PW admin panel and (optionally) automatically add and configure the tracking code on front-end pages. Links GitHub Readme & documentation Download Zip Modules directory Module settings screenshot What is Fathom Analytics? Fathom Analytics is a simple, privacy-focused website analytics tool for bloggers and businesses. Stop scrolling through pages of reports and collecting gobs of personal data about your visitors, both of which you probably don't need. Fathom is a simple and private website analytics platform that lets you focus on what's important: your business. Privacy focused Fast-loading dashboards, all data is on a single screen Easy to get what you need, no training required Unlimited email reports Private or public dashboard sharing Cookie notices not required (it doesn't use cookies or collect personal data) Displays: top content, top referrers, top goals and more
    1 point
  11. @Crowdland Technology Many thanks. I have fixed it in the Github Repo.
    1 point
  12. = I have not thought about that and I don't know how o add any other service. ? This uses a fixed api key.
    1 point
  13. Hi! I just found a problem adding a watermar when 2 different images have the same name but the extensions are jpg and jpeg the result is only one image. I fixed it commenting lines 554 to 556 on ImageManipulator02.class.php file. Eg: "photo1.jpg" and "photo1.jpeg" foreach ($images as $img){ $img->pim2Load("wtmd", true)->height(480)->watermarkLogo($watermark, $position = 'center', $padding = 2)->pimSave()->httpUrl; } // The result is photo1.jpg
    1 point
  14. Hi Dean, Hopefully you've already found the answer, but you need to also visit Modules > Configure > LoginRegister and add those new user fields to "Registration form fields" so they display during registration.
    1 point
  15. Hi @Mats thanks for your module!.. very useful for quick blog posting or a lading page / blocks builder.. and will be perfect if integrate something like this https://glide.thephpleague.com/ ?
    1 point
  16. Cool - i was building this, but i got stuck on the Unsplah api which was telling me they didn't like downloads and wanted to only allow usage that would use the source image from them, and this wouldn't work with an images inputfield, or imagesizer engine, or any other image manipulation like srcsets etc; So i gave up... Looks like somehow you solved all of this, so thanks! Does this use a fixed api key, or will that api key need to be configurable at some point?
    1 point
  17. Hi @Mats thx, this has been on my wishlist for quite some time ? Have you thought about also integrating other services like https://www.pexels.com or https://pixabay.com ?
    1 point
  18. This is a module I made as an experiment a while ago and never got around to releasing publicly. At the time it was prompted by discussions around using Repeater fields for "page builder" purposes, where the depth feature could possibly be used for elements that would be nested inside other elements. I thought it would be useful to enforce some depth rules and translate the depth data into a multi-dimensional array structure. I'm not using this module anywhere myself but maybe it's useful to somebody. Repeater Depth Helper This module does two things relating to Repeater fields that have the "Item depth" option enabled: It enforces some depth rules for Repeater fields on save. Those rules are: The first item must have a depth of zero. Each item depth must not be more than one greater than previous item depth. It provides a RepeaterPageArray::getDepthStructure helper method that returns a nested depth structure for a Repeater field value. Helper method The module adds a RepeaterPageArray::getDepthStructure method that returns a multi-dimensional array where the key is the page ID and the value is an array of nested "child" items, or null if there are no nested children. Example The module doesn't make any assumptions about how you might want to use the depth structure array, but here is a way you might use it to output a nested unordered list. // Output a nested unordered list from a depth structure array function outputNestedList($depth_structure, $repeater_items) { $out = "<ul>"; foreach($depth_structure as $page_id => $nested_children) { $out .= "<li>" . $repeater_items->get("id=$page_id")->title; // Go recursive if there are nested children if(is_array($nested_children)) $out .= outputNestedList($nested_children, $repeater_items); $out .= "</li>"; } $out .= "</ul>"; return $out; } $repeater_items = $page->my_repeater; $depth_structure = $repeater_items->getDepthStructure(); echo outputNestedList($depth_structure, $repeater_items); https://github.com/Toutouwai/RepeaterDepthHelper https://modules.processwire.com/modules/repeater-depth-helper/
    1 point
  19. @bernhard Grateful for the offer to help, however on a tight schedule and managed to get the solution to my query using a normal PW selector with the very helpful and hard to find gem "repeater_field.owner.field_name'. It enabled me to get the repeater field, it's originating page and the individual repeater item data. The selector returns a WireArray of repeater fields which are then manipulated into a flat array for RockTabulator. From what I could see in the SQL statement from RF3, the field table aliases are getting mixed up when both the first and main RF3 queries have the same field name, eg 'title' - some have the unique id twice and then the LEFT JOIN 'title' gets the wrong one which then fails.
    1 point
  20. I've just noticed an issue thats cropped up before in other modules: Processwire allows mixed case field names, however they are always converted to lowercase in mySQL. If you use a mixed case field name eg in addColumns(['mixedCase']) you will get an SQL error, but if you do addColumns('mixedcase') you get no error, but a column of data with Field Not Found as contents. Changing this line in Rockfinder3.module.php seems to fix it: // add this column to columns array $colname = (string) strtolower($column); I'm about to see if I find any other instances.
    1 point
  21. v0.0.11 adds support for repeater matrix fields ? Thx to @aComAdi of https://www.a-commerce.ch/ for sponsoring this update! ? $rm->setMatrixItems('your_matrix_field', [ 'foo' => [ 'label' => 'foo label', 'fields' => ['field1', 'field2'], ], 'bar' => [ 'label' => 'bar label', 'fields' => ['field1', 'field3'], ], ]);
    1 point
  22. As i mentioned before; I started my own e-commerce project and had to say i was afraid at beginning. This is my first OOP project, so i spent some time to find my way. But i am very happy when i see my progress and the results step by step... It will surely not as future rich as Padloper but my clients do not use many futures anyway. Mainly the general things.... Hope to present my first Ecommerce project on PW here soon....
    1 point
  23. Tested 0.0.2 on 2 sites with ProcessWire < 3.0.139(no toggle) and it works like a charm!
    1 point
  24. @Klenkes I've updated the module to version 0.0.2 now which uses InputfieldRadios when InputfieldToggle isn't available. Please give it a go and let me know if that's solved it for you!
    1 point
  25. I am a huge Fathom fan myself and I was happy when I read that a module exists. But I hate it when I am the first to complain... After the the module install I get the following screen: I am unable to configure the module ? What can I do? PW 3.0.123 | PHP 7.3.18
    1 point
  26. I don't know if I understood correctly, but it looks like you can also use $files->include() or $files->render() methods in your _main.php file. A simple example from the Regular Uikit 3 profile, which we will include the _header.php inside file _main.php with some variables: <?php namespace ProcessWire; // _main.php template file, called after a page’s template file $home = pages()->get('/'); // homepage $siteTitle = 'Regular'; $siteTagline = $home->summary; // as a convenience, set location of our 3rd party resources (Uikit and jQuery)... urls()->set('uikit', 'wire/modules/AdminTheme/AdminThemeUikit/uikit/dist/'); urls()->set('jquery', 'wire/modules/Jquery/JqueryCore/JqueryCore.js'); // ...or if you prefer to use CDN hosted resources, use these instead: // urls()->set('uikit', 'https://cdnjs.cloudflare.com/ajax/libs/uikit/3.0.0-beta.40/'); // urls()->set('jquery', 'https://code.jquery.com/jquery-2.2.4.min.js'); ?> <!-- HEADER --> <?php $files->include('_header', ['home' => $home, 'siteTitle' => $siteTitle, 'siteTagline' => $siteTagline]); // echo $files->render('_header', ['home' => $home, 'siteTitle' => $siteTitle, 'siteTagline' => $siteTagline]); ?> _header.php: <?php namespace ProcessWire; // _header.php file ?> <!DOCTYPE html> <html lang='en'> <head id='html-head'> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title id='html-title'><?=page()->title?></title> <meta name="description" content="<?=page()->summary?>"> <link rel="stylesheet" href="<?=urls()->uikit?>css/uikit.min.css" /> <link rel="stylesheet" href="<?=urls()->templates?>styles/main.css"> <script src="<?=urls()->jquery?>"></script> <script src="<?=urls()->uikit?>js/uikit.min.js"></script> <script src="<?=urls()->uikit?>js/uikit-icons.min.js"></script> </head> <body id='html-body'> <!-- MASTHEAD --> <header class='uk-background-muted'> <div id='masthead' class="uk-container"> <h2 id='masthead-logo' class='uk-text-center uk-margin-medium-top uk-margin-small-bottom'> <a href='<?=urls()->root?>'> <img src='<?=urls()->templates?>styles/images/coffee4.svg' alt='coffee'><br /> </a> <?=$siteTitle?> </h2> <p id='masthead-tagline' class='uk-text-center uk-text-small uk-text-muted uk-margin-remove'> <?=$siteTagline?> </p> <nav id='masthead-navbar' class="uk-navbar-container" uk-navbar> <div class="uk-navbar-center uk-visible@m"> <?=ukNavbarNav($home->and($home->children), [ 'dropdown' => [ 'basic-page', 'categories' ] ])?> </div> </nav> </div> </header> It is also important to include <?php namespace ProcessWire; ?> in each of template files. Sometimes it also helps to enable $config->useFunctionsAPI in the config.php file ( Allow most API variables to be accessed as functions? ), this will be more useful in your custom functions, where for example you can call page()->title instead of $page->title, which will not work inside a your custom function if you do not enter any arguments, as in the example below: <?php function showTitle() { echo '<h1>' . page()->title . '</h1>'; // This work // echo $page->title; // This not work } // Show Title showTitle(); ?> The setting() helper function is a good addition to the _init.php file, to which I usually attach the most important page options, which are also available in custom functions without entering arguments such as the init.php file: <?php namespace ProcessWire; /** * * This _init.php file is called automatically by ProcessWire before every page render * * Get or set a runtime site setting * @link https://processwire.com/api/ref/functions/setting/ * */ /** @var ProcessWire $wire */ // set or replace multiple settings setting([ 'siteTitle' => 'ProcessWire CMS / CMF', 'siteDescription' => 'ProcessWire is like a power tool for your website, able to deliver any output, at any scale, to any number of people. ', ]); // Your custom functions that are better placed in the _func.php or _uikit.php file (this is just an example) function siteBranding() { echo "<h1>" . setting('siteTitle') . "</h1>"; echo "<h2>" . setting('siteDescription') . "</h2>"; } include_once('./_uikit.php'); Now you can display the function wherever you want: <?php siteBranding() ?> For example, in this Site Profile I have put site options or translations inside file _init.php: <?php namespace ProcessWire; /** * * This _init.php file is called automatically by ProcessWire before every page render * * Get or set a runtime site setting * @link https://processwire.com/api/ref/functions/setting/ * */ // as a convenience, set location of our 3rd party resources (jQuery)... urls()->set('jquery', 'https://code.jquery.com/jquery-3.4.1.min.js'); $home = pages('/'); $blog = pages()->get("template=blog"); $options = pages()->get('/options/'); // Basic Settings setting([ // Custom html classes 'htmlClasses' => WireArray([ 'template-' . page()->template->name, 'page-' . page()->id, ]), // Basic 'home' => $home, 'privacyPolicy' => pages()->get("template=privacy"), 'options' => $options, 'siteName' => $options->text, 'logo' => $options->logo, 'favicon' => $options->favicon, 'socialProfiles' =>$options->social_profiles, 'metaTitle' => page('meta_title|title'), 'metaDescription' => page()->meta_description, 'noindex' => false, 'poweredUrl' => 'https://processwire.com', // Home Sections 'hero' => $home, 'about' => pages()->get("template=about"), 'projects'=> pages()->get("template=projects"), 'recent' => $blog->child(), // Path to template parts 'homeParts' => 'parts/home', 'blogParts' => 'parts/blog', // Blog 'blog' => $blog, 'disableComments' => $options->more_options->get("name=disable-comments"), // Contact Page 'saveMessages' => $options->more_options->get("name=save-messages"), // Images 'img' => page()->images && page()->images->count() ? page()->images : '', // Main 'mainTitle' => page('title'), 'mainImage' => true, // Set basic background image for all pages // Bottom Panel 'bottomPanel' => $options->bottom_panel, // Basic Translations 'lang' => __('en'), 'edit' => __('Edit'), 'next' => __('Next'), 'previous' => __('Previous'), 'search' => __('Search'), 'search-site' => __('Search the entire site'), 'found-matches' => __('Found %d page(s)'), 'no-results' => __('Sorry, no results were found.'), 'maintenance-mode' => __('Maintenance Mode'), 'site-disabled' => __('Our site is currently disabled.'), 'to-top' => __('To top'), 'we-sociable' => __('We are sociable'), 'powered' => __('Probably supported by ProcessWire CMS'), // Contact Page Translate 'message-error' => __('Some errors, please update your form'), 'message-success' => __('Success, your message has been sent'), 'txt-from' => __('From'), 'form-legend' => __('Contact Us'), 'form-name' => __('Name'), 'form-email' => __('Email'), 'form-privacy' => __('I agree with the %s terms.'), 'form-message' => __('Message'), 'form-spam' => __('To help prevent automated spam, please answer this question'), 'fs-placeholder' => __('* Using only numbers, what is 10 plus 15?'), 'fs-error' => __('Fill out the spam prevention box correctly'), 'form-submit' => __('Submit'), // Blog Translate 'in-blog' => __('In the blog'), 'posted-in' => __('Posted in'), 'all-posts' => __('All posts'), 'recent-posts' => __('Recent posts'), 'read-more' => __('Read More'), 'written-on' => __('Written on'), 'byline-text' => __('Posted by %1$s on %2$s'), 'also-like' => __('You might also like:'), 'author' => __('Author'), 'authors' => __('Authors'), // is also url segments ( blog/authors/author-mame ) 'category' => __('Category'), 'tag' => __('Tag'), 'author-checkbox' => __('You probably need to check the author checkbox in your user profile'), 'rss' => __('RSS'), 'recent-entries' => __('Recent entries'), // Comments Form Translate 'previous-comments' => __('Previous Comments'), 'next-comments' => __('Next Comments'), 'post-comment' => __('Post a comment'), 'comment' => __('Comment'), 'comments' => __('Comments'), 'no-comments' => __('No Comments'), 'comments-closed' => __('Comments are closed'), 'comment-header' => __('Posted by {cite} on {created}'), 'success-message' => __('Thank you, your comment has been posted.'), 'pending-message' => __('Your comment has been submitted and will appear once approved by the moderator.'), 'error-message' => __('Your comment was not saved due to one or more errors.') . ' ' . __('Please check that you have completed all fields before submitting again.'), 'comment-cite' => __('Your Name'), 'comment-email' => __('Your E-Mail'), 'comment-website' => __('Website'), 'comment-stars' => __('Your Rating'), 'submit' => __('Submit'), 'stars-required' => __('Please select a star rating'), 'reply' => __('Reply') ]); include_once('./_func.php');
    1 point
  27. @ryan, would you consider adding the ability for PW to split database connections for read and write? I think it will be really useful, especially for high-traffic sites. Something like this (https://laravel.com/docs/master/database#using-multiple-database-connections) or WordPress HyperDB (https://wordpress.org/plugins/hyperdb/) Thanks Rudy
    1 point
  28. is_int() & is_null() if(is_null($page->cruise_spaces)) if(!is_int($page->cruise_spaces)) if($page->cruise_spaces === NULL) if($page->cruise_spaces !== NULL)
    1 point
  29. Looking at your error message, I see where it came from. There was an error in my earlier example (sorry). At the end of it, it should be: // output the pagination navigation echo $a->renderPager(); rather than $images->renderPager();
    1 point
  30. I've not tried seddass's solution, but it looks right on. I'm using some of his code in my example too. So here's another option, which is to piggyback onto the MarkupPagerNav module, even though you aren't dealing with pages. <?php // get the images you are going to display $items_per_page = 4; $start = ($input->pageNum - 1) * $items_per_page; $total = count($page->images); $images = $page->images->slice($start, $items_per_page); // make this to give MarkupPagerNav what it needs $a = new PageArray(); // add in some generic placeholder pages foreach($images as $unused) $a->add(new Page()); // tell the PageArray some details it needs for pagination // (something that PW usually does internally, for pages it loads) $a->setTotal($total); $a->setLimit($items_per_page); $a->setStart($start); // output your images foreach($images as $p) { $img = $p->img; echo "<img src='{$img->url}' alt='{$img->description}' />"; } // output the pagination navigation echo $a->renderPager(); Btw, an images field on a page isn't going to scale infinitely. At some point, you are going to find it difficult to manage, sort, etc. So I would still place some limits on yourself for the max number of images you are going to attach to a single page.
    1 point
×
×
  • Create New...