Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/11/2018 in all areas

  1. I'd like to share with you guys our latest published project. This time a website for a German Food Photographer based in Cologne: http://www.elaruether.de/ Ela is an interesting case. Her relation with food started as a chef and evolved to blogging and later photography. She's now a professional food photographer. The only 3rd party modules that we installed were Admin on steroids and Tracy debugger (thanks to @tpr and @adrian for the continuous great work). Admin on steroids was particularly handy to invert the order of the blog posts and to add thumbnails to the portfolio pages on the admin: For the slideshows and project pages we used a heavy customised version of the excellent Owl Caroussel
    10 points
  2. Hello there, I've started using ProcessWire at work a while ago and I have been really enjoying building modular, clean and fast sites based on the CMS (at work, I usually post as @schwarzdesign). While building my first couple of websites with ProcessWire, I have written some useful helper functions for repetitive tasks. In this post I want to showcase and explain a particular function that generates a responsive image tag based on an image field, in the hope that some of you will find it useful :) I'll give a short explanation of responsive images and then walk through the different steps involved in generating the necessary markup & image variations. I want to keep this beginner-friendly, so most of you can probably skip over some parts. What are responsive images I want to keep this part short, there's a really good in-depth article about responsive images on MDN if you are interested in the details. The short version is that a responsive image tag is simply an <img>-tag that includes a couple of alternative image sources with different resolutions for the browser to choose from. This way, smaller screens can download the small image variant and save data, whereas high-resolution retina displays can download the extra-large variants for a crisp display experience. This information is contained in two special attributes: srcset - This attribute contains a list of source URLs for this image. For each source, the width of the image in pixels is specified. sizes - This attribute tells the browser how wide a space is available for the image, based on media queries (usually the width of the viewport). This is what a complete responsive image tag may look like: <img srcset="/site/assets/files/1015/happy_sheep_07.300x0.jpg 300w, /site/assets/files/1015/happy_sheep_07.600x0.jpg 600w, /site/assets/files/1015/happy_sheep_07.900x0.jpg 900w, /site/assets/files/1015/happy_sheep_07.1200x0.jpg 1200w, /site/assets/files/1015/happy_sheep_07.1800x0.jpg 1800w, /site/assets/files/1015/happy_sheep_07.2400x0.jpg 2400w" sizes="(min-width: 1140px) 350px, (min-width: 992px) 480px, (min-width: 576px) 540px, 100vw" src="/site/assets/files/1015/happy_sheep_07.1200x0.jpg" alt="One sheep"> This tells the browser that there are six different sources for this image available, ranging from 300px to 2400px wide variants (those are all the same image, just in different resolutions). It also tells the browser how wide the space for the image will be: 350px for viewports >= 1140px 480px for viewports >= 992px 540px for viewports >= 576px 100vw (full viewport width) for smaller viewports The sizes queries are checked in order of appearance and the browser uses the first one that matches. So now, the browser can calculate how large the image needs to be and then select the best fit from the srcset list to download. For browsers that don't support responsive images, a medium-sized variant is included as the normal src-Attribute. This is quite a lot of markup which I don't want to write by hand every time I want to place an image in a ProcessWire template. The helper function will need to generate both the markup and the variations of the original image. Building a reusable responsive image function Let's start with a function that takes two parameters: a Pageimage object and a standard width. Every time you access an image field through the API in a template (e.g. $page->my_image_field), you get a Pageimage object. Let's start with a skeleton for our function: function buildResponsiveImage( Pageimage $img, int $standard_width ): string { $default_img = $img->maxWidth($standard_width); return '<img src="' . $default_img->url() . '" alt="' . $img->description() . '">'; } // usage example echo buildResponsiveImage($page->my_image_field, 1200); This is already enough for a normal img tag (and it will serve as a fallback for older browsers). Now let's start adding to this, trying to keep the function as flexible and reusable as possible. Generating alternate resolutions We want to add a parameter that will allow the caller to specify in what sizes the alternatives should be generated. We could just accept an array parameter that contains the desired sizes as integers. But that is not very extendible, as we'll need to specify those sizes in each function call and change them all if the normal size of the image in the layout changes. Instead, we can use an array of factors; that will allow us to set a reasonable default, and still enable us to manually overwrite it. In the following, the function gets an optional parameter $variant_factor. // get the original image in full size $original_img = $img->getOriginal() ?? $img; // the default image for the src attribute, it wont be upscaled $default_image = $original_img->width($standard_width, ['upscaling' => false]); // the maximum size for our generated images $full_image_width = $original_img->width(); // fill the variant factors with defaults if not set if (empty($variant_factors)) { $variant_factors = [0.25, 0.5, 0.75, 1, 1.5, 2]; } // build the srcset attribute string, and generate the corresponding widths $srcset = []; foreach ($variant_factors as $factor) { // round up, srcset doesn't allow fractions $width = ceil($standard_width * $factor); // we won't upscale images if ($width <= $full_image_width) { $srcset[] = $original_img->width($width)->url() . " {$width}w"; } } $srcset = implode(', ', $srcset); // example usage echo buildResponsiveImage($page->my_image_field, 1200, [0.4, 0.5, 0.6, 0.8, 1, 1.25, 1.5, 2]); Note that for resizing purposes, we want to get the original image through the API first, as we will generate some larger alternatives of the images for retina displays. We also don't want to generate upscaled versions of the image if the original image isn't wide enough, so I added a constraint for that. The great thing about the foreach-loop is that it generates the markup and the images on the server at the same time. When we call $original_img->width($width), ProcessWire automatically generates a variant of the image in that size if it doesn't exist already. So we need to do little work in terms of image manipulation. Generating the sizes attribute markup For this, we could build elaborate abstractions of the normal media queries, but for now, I've kept it very simple. The sizes attribute is defined through another array parameter that contains the media queries as strings in order of appearance. $sizes_attribute = implode(', ', $sizes_queries); The media queries are always separated by commas followed by a space character, so that part can be handled by the function. We'll still need to manually write the media queries when calling the function though, so that is something that can be improved upon. Finetuning & improvements This is what the function looks like now: function buildResponsiveImage( Pageimage $img, int $standard_width, array $sizes_queries, ?array $variant_factors = [] ): string { // get the original image in full size $original_img = $img->getOriginal() ?? $img; // the default image for the src attribute, it wont be upscaled $default_image = $original_img->width($standard_width, ['upscaling' => false]); // the maximum size for our generated images $full_image_width = $original_img->width(); // fill the variant factors with defaults if not set if (empty($variant_factors)) { $variant_factors = [0.25, 0.5, 0.75, 1, 1.5, 2]; } // build the srcset attribute string, and generate the corresponding widths $srcset = []; foreach ($variant_factors as $factor) { // round up, srcset doesn't allow fractions $width = ceil($standard_width * $factor); // we won't upscale images if ($width <= $full_image_width) { $srcset[] = $original_img->width($width)->url() . " {$width}w"; } } $srcset = implode(', ', $srcset); return '<img src="' . $default_img->url() . '" alt="' . $img->description() . '" sizes="' . $sizes_attribute . '" srcset="' . $srcset . '">'; } It contains all the part we need, but there are some optimizations to make. First, we can make the $sizes_queries parameters optional. The sizes attribute default to 100vw (so the browser will always download an image large enough to fill the entire viewport width). This isn't optimal as it wastes bandwidth if the image doesn't fill the viewport, but it's good enough as a fallback. We can also make the width optional. When I have used this function in a project, the image I passed in was oftentimes already resized to the correct size. So we can make $standard_width an optional parameter that defaults to the width of the passed image. if (empty($standard_width)) { $standard_width = $img->width(); } Finally, we want to be able to pass in arbitrary attributes that will be added to the element. For now, we can just add a parameter $attributes that will be an associative array of attribute => value pairs. Then we need to collapse those into html markup. $attr_string = implode( ' ', array_map( function($attr, $value) { return $attr . '="' . $value . '"'; }, array_keys($attributes), $attributes ) ); This will also allow for some cleanup in the way the other attributes are generated, as we can simply add those to the $attributes array along the way. Here's the final version of this function with typehints and PHPDoc. Feel free to use this is your own projects. /** * Builds a responsive image element including different resolutions * of the passed image and optionally a sizes attribute build from * the passed queries. * * @param \Processwire\Pageimage $img The base image. * @param int|null $standard_width The standard width for this image. Use 0 or NULL to use the inherent size of the passed image. * @param array|null $attributes Optional array of html attributes. * @param array|null $sizes_queries The full queries and sizes for the sizes attribute. * @param array|null $variant_factors The multiplication factors for the alternate resolutions. * @return string */ function buildResponsiveImage( \Processwire\Pageimage $img, ?int $standard_width = 0, ?array $attributes = [], ?array $sizes_queries = [], ?array $variant_factors = [] ): string { // if $attributes is null, default to an empty array $attributes = $attributes ?? []; // if the standard width is empty, use the inherent width of the image if (empty($standard_width)) { $standard_width = $img->width(); } // get the original image in full size $original_img = $img->getOriginal() ?? $img; // the default image for the src attribute, it wont be // upscaled if the desired width is larger than the original $default_image = $original_img->width($standard_width, ['upscaling' => false]); // we won't create images larger than the original $full_image_width = $original_img->width(); // fill the variant factors with defaults if (empty($variant_factors)) { $variant_factors = [0.25, 0.5, 0.75, 1, 1.5, 2]; } // build the srcset attribute string, and generate the corresponding widths $srcset = []; foreach ($variant_factors as $factor) { // round up, srcset doesn't allow fractions $width = ceil($standard_width * $factor); // we won't upscale images if ($width <= $full_image_width) { $srcset[] = $original_img->width($width)->url() . " {$width}w"; } } $attributes['srcset'] = implode(', ', $srcset); // build the sizes attribute string if ($sizes_queries) { $attributes['sizes'] = implode(', ', $sizes_queries); } // add src fallback and alt attribute $attributes['src'] = $default_image->url(); if ($img->description()) { $attriutes['alt'] = $img->description(); } // implode the attributes array to html markup $attr_string = implode(' ', array_map(function($attr, $value) { return $attr . '="' . $value . '"'; }, array_keys($attributes), $attributes)); return "<img ${attr_string}>"; } Example usage with all arguments: echo buildResponsiveImage( $page->testimage, 1200, ['class' => 'img-fluid', 'id' => 'photo'], [ '(min-width: 1140px) 350px', '(min-width: 992px) 480px', '(min-width: 576px) 540px', '100vw' ], [0.4, 0.5, 0.6, 0.8, 1, 1.25, 1.5, 2] ); Result: <img class="img-fluid" id="photo" srcset="/site/assets/files/1/sean-pierce-1053024-unsplash.480x0.jpg 480w, /site/assets/files/1/sean-pierce-1053024-unsplash.600x0.jpg 600w, /site/assets/files/1/sean-pierce-1053024-unsplash.720x0.jpg 720w, /site/assets/files/1/sean-pierce-1053024-unsplash.960x0.jpg 960w, /site/assets/files/1/sean-pierce-1053024-unsplash.1200x0.jpg 1200w, /site/assets/files/1/sean-pierce-1053024-unsplash.1500x0.jpg 1500w, /site/assets/files/1/sean-pierce-1053024-unsplash.1800x0.jpg 1800w, /site/assets/files/1/sean-pierce-1053024-unsplash.2400x0.jpg 2400w" sizes="(min-width: 1140px) 350px, (min-width: 992px) 480px, (min-width: 576px) 540px, 100vw" src="/site/assets/files/1/sean-pierce-1053024-unsplash.1200x0.jpg" alt="by Sean Pierce"> Now this is actually too much functionality for one function; also, some of the code will be exactly the same for other, similar helper functions. If some of you are interested, I'll write a second part on how to split this into multiple smaller helper functions with some ideas on how to build upon it. But this has gotten long enough, so yeah, I hope this will be helpful or interesting to some of you :) Also, if you recognized any problems with this approach, or can point out some possible improvements, let me know. Thanks for reading!
    7 points
  3. I created a demo-installation of RockGrid/RockFinder that I want to share soon that shows several examples of RockFinder/RockGrid Here's one example that @jmartsch requested support for - a grid listing the sum of all pages that reference this page: the residents can assign a house with a single pagefield: The php file for the grid (returning the final finder's sql, that's why I post it here) looks like this: <?php namespace ProcessWire; // the base table contains all houses // https://i.imgur.com/e5bC4sA.png $houses = new RockFinder('template=house', ['title']); // then we create another table containing all residents that have a living assigned // https://i.imgur.com/zYXEVIL.png $residents = new RockFinder('template=person|cat|dog,livesin.count>0', ['title', 'livesin']); // we join both tables and get a combined table // https://i.imgur.com/TE0vEPd.png $houses->join($residents, 'resident', ['livesin' => 'id']); // then we can modify the resulting SQL to our needs // https://i.imgur.com/UgzNqDD.png $sql = $houses->getSQL(); $sql = "SELECT id, title, count(resident_id) as numresidents FROM ($sql) as tmp GROUP BY resident_livesin"; // set the data // to check everything i created a test-grid where we can filter for the house title // https://i.imgur.com/9pdlYVz.png $this->setData($sql); The screenshots of the comments are here: -- -- -- -- -- The grid in the last example called "residents" is as simple as that: <?php namespace ProcessWire; $residents = new RockFinder('template=person|cat|dog,livesin.count>0', ['title']); $residents->addField('livesin', ['title']); $this->setData($residents); As you can see this somewhat complex example can be done in only 6 lines of codes (same example as above, just without comments): $houses = new RockFinder('template=house', ['title']); $residents = new RockFinder('template=person|cat|dog,livesin.count>0', ['title', 'livesin']); $houses->join($residents, 'resident', ['livesin' => 'id']); $sql = $houses->getSQL(); $sql = "SELECT id, title, count(resident_id) as numresidents FROM ($sql) as tmp GROUP BY resident_livesin"; $this->setData($sql);
    3 points
  4. Thanks for that... Before CMS systems became a "thing" I was pretty active in designing and working with modern web standards static sites. But my day job was photography. I tried a bunch of systems before setting on the first branch of MODx, namely Evo. The thing I liked about MODx was that it was easier to design custom sites that fit into the structure. What was confusing to me (and many others) was the reliance on system syntax specific "chunks" and a hard to to grapple navigation system. Wayfinder was powerful but a pain. Kongondo was one of THE best MODx contributors back then. Especially with helping to build the community knowledge and comfort level with creating flexible and complicated connections between pages. But I sort of felt that the creation of the new branch of MODx, namely Revo, made the whole thing sort of awkward? The two different branches happening at the same time, etc. It changed the focus, and key guys went in new directions. Processwire wire is a vastly superior product. I can still design things on paper and use the very flexible template and field combination without fighting the whole structure. My issue has been a long standing limitation: I just could never learn to code PHP and Javascript, etc. I tried but just never gave it the commitment required. For many these skills come easily. Not for me. Looking back one of my frustrations with my early MODx days was getting elegant looking dynamic image galleries to work. I guess some things never change? MaxiGallery had promise but it was a pain to work with. The cool thing with Concrete5 is that it comes with a nice paginated and functioning gallery system, plus a blog system, etc, all without having to use a front end plus a back end editing routine. But the issue is how easy is it to customize a theme or deploy a custom design? There is always a road block with any system it seems. The other thing I like about Processwire is the size of the whole project and the community. Wordpress and Drupal have massive numbers but that can add confusion, too many choices and doubts as to how long the widget you are deploying will be actively maintained. Some systems have too little community evolvement and support. Processwire just has a nice balance.
    3 points
  5. Also just as a heads up, I'm in the process of converting this site profile into a module, since I'm struggeling to keep it up to date on my sites and thus should be much easier to update in the future
    3 points
  6. 3 points
  7. (Assuming the suggestion is for a normalized way of handling versioning in changelogs for all modules moving forward.) As much as I like the idea of using some dynamic method to keep a version number in check, I'm not sure that a changelog (or markdown file) is the best way to handle that - at least not by simply pulling the first line and expecting that it will contain the updated version number. There are many suggested ways of creating changelogs. (There's even a discussion about best practices mentioning some of those links.) Since there are so many ways to handle changelogs (sometimes organization-specific standards) I'm not sure this could work for everyone in practice (esp. those that are using info.json files for this module data). I definitely think it looks like a terrific idea for your own use case though, and until I thought about it further I got all excited by the prospect! ? I do think it's OK to have a fieldtype/inputtype combo that share the same name also share the same version number.
    2 points
  8. It can be handled by the new stuff I set up recently. Have a read here: It allows you to set Tracy settings in config.php or config-dev.php (so it's local only). I think this is probably the best solution. Let me know how you find it and if you have any suggestions for improvements. PS - there is some further discussion about the instigation of this feature starting around here: https://processwire.com/talk/topic/5693-new-module-type-wiremail/?do=findComment&amp;comment=172371
    2 points
  9. @devsmo I'm not sure that you can use this type of construction for sorting. Take a look at Ryan's comment https://github.com/processwire/processwire-issues/issues/263#issuecomment-304285290
    2 points
  10. Thanks @pwired Well spotted! I was planning to delay the opening of the overlay slider until the images were loaded, but then decided to not go that way. I removed the script already ?
    2 points
  11. Hi PhotoWebMax, this could be just a cache issue, I presume. BTW, there are quite a few former MODX users in this community (like me and you - I remember your contributions in their forums years ago - , and of course kongondo and others. What I'd like to say: Don't let you get discouraged in using PW just because of some fiddling issues with a gallery script which will be solved and have nothing to do with PW. Having found PW several years ago I quit using MODX from one day to the other and never looked back. Good luck!
    2 points
  12. I definitely understand the line one has to draw when making assumptions for the user, but it seems that in some instances you do make those assumptions already -- which is why those properties of the object feel really inconsistent and confusing. I think that issue is driving some of the posts in this thread that ask about those properties and why they don't seem to output what we expect. Depending on whether it's a one time event, an all day event, or a recurring event, they behave a bit differently or in unexpected ways. It's almost that I would prefer you to make a consistent assumption, but provide the tools to make an alternative output for myself. Right now it seems that the implementation relies much more heavily on simply understanding what I need to do to get the simple output that I expected to get. It's not an easy question to answer, but I hope you have an understanding of where I (and others?) see the confusion. The admin field, screens, and some of the tools you provide are very slick... but the object for custom output is harder to figure out, or simply not that useful depending on the nature of recurrence (or not). Thanks!
    2 points
  13. In fact, these modules are very similar. That's why I did not publish my module in the Processwire module directory. small differences: I use the builtin InputfieldMarkup I don't use eval() No need to create a new field if used in another template. Simply overwrite the output template based. The basic usecase is to set the markup field and template/field based. Via string tags all pagefield values and other page properties are accessible. Any textformatter can be applied. Full Language support. For more complex calculations the output is hookable and the full PW API can be used to create the output, not only $page or $pages. Example: A page (A) has been assigned to another page (B) via a page field. I want to show some informations about (B) inside (A)
    2 points
  14. Not too sure what doGeocoding function is doing but have you tried hooking before Pages::save? Also check out this https://modules.processwire.com/modules/fieldtype-map-marker/ which does what you are trying to accomplish.
    2 points
  15. Hi folks SCAYT (Spell Check As You Type) is a great CKEditor plugin, but does anyone know if it's possible to get it working with multi-language fields? As in configure it to check for English in the English version of a CKE field and German in another for example?
    1 point
  16. DEPRECATED - USE ROCKMIGRATIONS INSTEAD I'm very happy to share my newest module called "ProcessWire Kickstart" that I developed during the holidays Maybe some of you already saw the preview thread about this... What it does: This module makes it possible to install ProcessWire in a fully automated process. You can define all necessary settings in one single php file and you can even define "recipes" that get executed after installation. This means you can install modules, adopt settings and do whatever you want with your new site using the PW API (like creating pages and so on). You could also place a kind of frontend boilerplate on your git account and grab that after installation and place it in your templates folder. I ran out of time so maybe someone could try that out and show how he did it Additional to that there is a ProcessModule to install in your ProcessWire admin which makes creating and testing recipes super easy. Note: Alpha realese until this module gets some more testing. Please be careful with this tool since it does some heavy file system manipulations (unzipping, moving and DELETING whole directories...). Use at your own risk. Usage: Just grab a copy of the kickstarter, place it on your server, visit yournewsite.com/kickstart.php, adjust settings (like username+password) as needed and hit "install". If your mysql user does not have the rights to create a new database then you have to create a database before running the installer! Download: via SSH: cd /var/www/yournewsitedirectory wget baumrock.com/kickstart.php // or using curl curl baumrock.com/kickstart.php -L --output kickstart.php Manually: Klick baumrock.com/kickstart.php and upload the file to your server Note: baumrock.com/kickstart.php returns the current master file from the gitlab repo and changes the namespace of the script so that it can install itself via recipe. If you don't need to install the kickstart processmodule via recipe you could also download the kickstart.php file from gitlab. Screenshots/Walkthrough: The initial Screen: You can either upload a file via the left panel or take my example file from the gitlab repo: This way you can create your own kickstartfiles and host it on your own accounts. When the file is loaded you can easily edit all necessary informations, like username, password and the url where to grab ProcessWire from. I just tried it with an old version as well... 2.7 worked just fine (having the old installer that recently was updated) but an ancient 2.2.4 version failed. I don't think anybody will ever need to install lots of old versions of pw with this tool but I wanted to mention it here. Hit "install" and lean back - on my VPS it takes 15 seconds to install my very own custom version of processwire with all modules that i need After logging into your admin you'll see that all modules from your recipe are installed: Recipe Editor: As recipes are executed after processwire was installed you have all your API magic available there. Running this scripts is only possible inside of a working processwire installation, so I created a module to help you with that task. See the comments of the sample recipe for more information! I hope this tool helps you to save lots of time and create lots of awesome ProcessWire websites I would be happy to see how you use this and please share useful recipes here in the thread so that everybody can profit. Maybe you just want to throw in an idea what could be done (for example I can imagine a recipe that checks file permissions on the system after installation)... Some parts of the code and maybe also part of the idea are taken from @Soma 's old and still great online installer, thx for that!
    1 point
  17. Is there any way of presetting a checkbox field? So that I could have a setting default to true and the user could uncheck it if he/she so wished? I don't really want to resort to double negatives!
    1 point
  18. I guess... we all love and use 3rd party scripts, tools, services and modules for our ProcessWire projects. From image galleries to contact forms and newsletter subscription services lot's of things are already there and ready for use. So I am looking for your most common used and trusted scripts, tools, services and modules. You may ask yourself why I want to know this and before hiding everything behind curtains here is the answer: I plan to create a collection of ready to use ProcessWire snippets for common and often used scripts, tools, services and modules. Therefore I'd like to know what you use for your projects so I can create those ready-to-use snippets. I already have a broad collection of snippets I use everytime but I think there could be much much more. For example: I like to use Owl Carousel 2 and Slick slider for image galleries and/or sliders and Mailchimp as a newsletter subscription service. The main goal is that I want to provide working solutions and answers for ProcessWire starters. More and more questions in the forums are 3rd party related (How do I use this gallery script in PW? or How does this service could be used in PW?) and for those I want to create a copy&paste / ready-to-use collection of snippets. So... I ask you to tell me your most used scripts, tools, services and modules. Feel free to share your trusted 3rd party options with me. P.S.: I don't ask you for your snippets and solutions as they are your business secret and someone already paid you for it. But... if you want to share your scripts with me and the public you are more than welcome. P.S. 2: Modules will be part of this collection Things, thoughts and details about my project so far: Idea: born Domain: registered Hosting: paid / sponsored Scripts: in progress Tools: in progress Services: in progress Modules: in progress Free, premium, freemium: free (no ads, no tracking, no affiliate links) Authors: you & me (full credits given to you) Ideas, thoughts, questions, answers? Let me know!
    1 point
  19. Thanks @Robin S - new version looks great!
    1 point
  20. Yes, it was an oversight. As more states need to be indicated in the dropdown items it gets harder to come up with distinguishable and tasteful styles for all of them. I think the hidden and unpublished pages need to use the same styling as in Page List, so that means I've had to change the styling for uneditable pages - these are now indicated by italics and reduced opacity (and the "not-allowed" cursor for devices that support hover). Other changes introduced in v0.1.7: The dropdowns now take $page->listable into account, so non-listable pages do not appear in the dropdowns. There is now a hookable BreadcrumbDropdowns::getSiblings method in case anyone wants to override the listed siblings for a page. This won't be needed in most cases though.
    1 point
  21. @bernhard Du bist der Beste ? I will try to optimize my queries tomorrow based on your post. Also some more questions are coming up as I dive in further.
    1 point
  22. Thanks, that is excactly what I need. Great ideas from Ivan. I had the same, but he was quicker ?
    1 point
  23. Can you try this simple example in your template file: <script src="//code.jquery.com/jquery-2.1.1.min.js"></script> <script> $( document ).ready(function() { $("#ajaxButton").click(function(e) { e.preventDefault(); $.ajax({ type: "POST", url: "/data/testajax.php?test=1", data: { id: $(this).val() }, success: function(result) { console.log('ok'); }, error: function(result) { console.log('error'); } }); }); }); </script> <input id="ajaxButton" type="submit" name="testAjax" value="Test Ajax" /> This is how it looks for me:
    1 point
  24. @thomasaull Great that you are converting this into a module. It would be a muc better fit. That way we can add api funtionality to any site easily. Actually, I was thinking about converting your site profile to a module, too ?
    1 point
  25. Are you using a JS framework? You need to make sure the X-Requested-With header is sent so that PHP (and therefore Tracy) can recognize it as an AJAX call. jQuery does this by default, but other frameworks may not, eg Angular. In pure/vanilla JS, you can do: xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest"); In Angular you can do: $http.defaults.headers.common["X-Requested-With"] = "XMLHttpRequest";
    1 point
  26. Looks nice. What is the purpose of the imagesloaded js ?
    1 point
  27. Maybe try using two foreach loops: <?php foreach ($pages->get('/portal/movies/')->children as $movieCategory) { echo "<h3><a href='$movieCategory->url'>$movieCategory->title</a></h3>"; echo '<ul>'; // Get movie Children foreach ($movieCategory->children as $movie ) { echo "<li><a href='$movie->url'> $movie->title </a></li>"; } echo '<ul>'; } ?> Or using $pages->find() ... Show children from the template, which is assigned to a single movie: <ul><?php // https://processwire.com/api/ref/pages/find/ $items = $pages->find("template=single-movie, limit=12"); // Loop foreach ($items as $item) { echo "<li><a href='$item->url'>$item->title</a></li>"; } ?></ul> <?php // Pagination https://processwire.com/api/modules/markup-pager-nav/ $pagination = $items->renderPager(); echo $pagination;?>
    1 point
  28. See the link above: https://processwire.com/talk/topic/18655-solved-no-input-post-data-when-using-ajaxaxiospost/ I was not able to POST json to ProcessWire directly, had to stringify it first.
    1 point
  29. @gebeer you can also try to replace apache_request_headers() with $_SERVER which should also work. This way you don't need the any additional functions
    1 point
  30. Your hook doesn't tell anything about how you manipulate the data. This works just fine for me in ready.php : $this->addHookBefore("ProcessPageEdit::processInput", function (HookEvent $event) { $form = $event->arguments("form"); if($form->get("lat")) { $this->input->post->lat = 12; } });
    1 point
  31. Hi, Thanks for the answer! I'll try this later this week, once I continue working on the site. I do have ProFields and I understand what you mean. It might very well be worth doing it like you suggested.
    1 point
  32. Hey @Robin S - any reason why the find siblings method doesn't use "include=all" ? I am assuming it was just an oversight, but it would be nice to have please. Thanks!
    1 point
  33. Interesting that in this case InnoDB faster and yet there have been other issues where it's much slower: https://github.com/processwire/processwire-issues/issues/692 I am sure there's a good reason for it, but it does make the decision on which to use more difficult. Maybe MyISAM for most tables and InnoDB for the sessions table if you are using SessionHandlerDB?
    1 point
  34. Hi @cosmicsafari, your example is a string translation, which you can use for static texts. Those static texts are ussualy short texts inside your templates which don‘t change that often. What you are looking for are multi-language fields, which are editable on the pages in the back-end. Just convert a existing field to a language field or add a new language field. If such a language field is translated, you will see the translation in the front-end. ? Regards, Andreas
    1 point
  35. You're talking about short echo tags (<?= ... ?>) right? In that regard I agree: that's a good solution in template use. Short open tags (<? ... ?>) are a different thing entirely, and although earlier decision to remove them was apparently cancelled, they're still discouraged and disabled by default.
    1 point
  36. Hello @Hurme, if your string tranlastion is in a template file, it should work like this. If your string is in a included or prepended file (f. e. _main.php), this doesn't work in my experience. For this you could use text domains inside your string translations. I used to have a single included file (translations.php) in which I collected all string translations and used a text domain to point all string translations to this included file: Anywhere: echo __("This will be translated", "/site/templates/includes/translations.php"); In translations.php __("This will be translated"); You could save the text domain into a variable so you don't have to write the whole path every time. Nowadays I'm thinking about using the ProModule Functional Fields for string translations only, because it gives you more freedom. For example if the original string translation needs to be changed, you have to edit it in your template and enter the translations again in the back-end, because they have lost the connection. With Functional Fields a editor can edit the translations and the original string without losing the connection. If you have the ProFields, it is worth checking out Functional Fields. ? You have to add those files with string translations manually via the "Translate files" button. You should see there every file with string translations, either in the "site" or "wire" folder. Regards, Andreas
    1 point
  37. I just committed a new version with several tweaks and fixes for the old, unloved Template Resources panel. It now better detects variables, constants, and functions that are only used once and therefore redundant code. The panel icon is now also colored to warn you that there are redundant things that you could remove.
    1 point
  38. This fieldtype will generate any runtime markup: https://github.com/kixe/FieldtypeMarkup
    1 point
  39. For selectors you can't use '->' as that is reserved for things like $page->title (Array). Instead you use 'upload.description'.
    1 point
  40. More enhancements to help support @Ivan Gretsky's needs. These settings (via config.php/config-dev.php or the module config settings): $config->tracy = array( 'enabled' => true, 'guestForceDevelopmentLocal' => true, 'frontendPanels' => array('mailInterceptor','processwireInfo','requestInfo','processwireLogs','tracyLogs','debugMode','console','panelSelector'), 'backendPanels' => array('mailInterceptor','processwireInfo','requestInfo','processwireLogs','tracyLogs','debugMode','console','panelSelector'), 'nonToggleablePanels' => array('mailInterceptor', 'tracyToggler'), 'panelSelectorTracyTogglerButton' => false ); results in the following: 1) Tracy is enabled 2) Tracy is in development mode (ie debug bar on) even when logged out on localhost / dev machine 3) Mail Interceptor is enabled and can't be toggled off (notice that the checkbox is greyed out) 4) Tracy Toggler panel is disabled and can't be toggled off (notice that the checkbox is greyed out) 5) Tracy Disable/Enable (toggler) button in the Panel Selector is removed
    1 point
  41. Wow! Amazing educational answer, thanks a lot, this kind of conversation really helps anyone move forward, thanks for your dedication!
    1 point
  42. Thanks for pointing me to this. I was using the wrong keyword(modal, popup) to search for this feature. This is the thing I am looking for. Let me back-link your tutorial here for people like me.
    1 point
  43. PW already has VEX onboard. You can easily use it like I did in RockGrid. See this example: You'd just need to target the right save-button and save only when the user confirms.
    1 point
  44. I'm missing this feature - in my case I have an "Active" checkbox on some items, and want new items to be active by default. "Inactive" in my case wouldn't make much sense, and I'm also not fond of the double negation... "not inactive" - that's poor semantics.
    1 point
×
×
  • Create New...