Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/08/2019 in all areas

  1. From time to time, when I'm on a website, I'm checking the source, because I'm curious. But may be since two years, I got the feeling, that the more and more websites are stuffed with interesting crap. Today I found these body styles. It's from Squarespace. There were times, when a webpage was stuffed with table constructions and local styles. Now this madness appears again.
    4 points
  2. @Tom., I tried resizing your original image and could see the banding issue when using GD for image resizing with the default gamma correction. The banding issue doesn't occur when using the ImageMagick resize engine, or when using the GD resize engine if gamma correction is disabled. Disable gamma correction for individual image resize: $page->image->size(1920, 1080, ['defaultGamma' => -1])->url Or disable gamma correction globally in /site/config.php $config->imageSizerOptions('defaultGamma', -1);
    4 points
  3. This is how I solved this question: I've assigned page-publish permission to the agent role so they can publish pages based on the property template. I've created a module that with a hook on ProcessPageEdit::buildForm like this $this->addHookAfter('ProcessPageEdit::buildForm', $this, 'removePublishButton'); The function that handles this just looks at the page being edited and if it has a status of Unpublished, it removes the Publish button: foreach($form->children() as $f){ if($f->name == "submit_publish" && $page->isUnpublished()) $form->children()->remove($f); // Removes the Publish Button from Properties not yet published. } This allows the users with agent role to edit already published pages (if they belong to them, something that the module also checks) but keeps them from publish new pages directly.
    2 points
  4. Wow... that's way more text than you see on most Squarespace pages. ?
    2 points
  5. Snippet to easily add Inputfields with intellisense support ? "Get PW Inputfield": { "prefix": "field", "body": [ "/** @var Inputfield$1 \\$${2:f} */", "\\$${2:f} = \\$this->modules->get('Inputfield$1');" ], "description": "Get PW Inputfiel" }, PS: Turns out that the chaining syntax as shown in the demo does not properly work with intellisense, so I'll use single line method calls in the future ?
    2 points
  6. Thanks Robin, it seems to be the Gamma correction causing the issue here. Thank you ?
    2 points
  7. Here you go, pwired's super language switcher: <ul> <?php $i = 1; foreach($languages as $language) { $var[$i] = $page->localUrl($language); $i++; } echo "<li>" . "<a href=" . '"' . $var[3] . '"' . ">" . "Deutsch" . "</a>" . "</li>"; echo "<li>" . "<a href=" . '"' . $var[2] . '"' . ">" . "English" . "</a>" . "</li>"; echo "<li>" . "<a href=" . '"' . $var[1] . '"' . ">" . "Español" . "</a>" . "</li>"; ?> </ul> Feel free to modify for your own needs, and beautify <ul>, <li> and <a> with your own custom css Here is a recommended read not to fall into unexpected not working language urls: https://processwire.com/talk/topic/19356-language-switcher-do-i-need-to-update-all-urls-in-the-api/
    2 points
  8. Here a short tutorial of how to use file fields in ProcessModules because I needed that today. File fields are somewhat special as they are usually connected to an existing page with an existing ID and folder in /site/assets/files. But it is also possible to use the Inputfield alone to provide a GUI for uploading files (just like it is done in ProcessDatabaseBackups or the Modules GUI): /** * Import CSV file * * @return string */ public function executeImportcsv() { $form = $this->modules->get('InputfieldForm'); /** @var InputfieldForm $form */ $tmpDir = $this->files->tempDir('upload_csv'); // get path of temp directory $f = $this->modules->get('InputfieldFile'); $f->extensions = 'csv'; $f->maxFiles = 1; $f->descriptionRows = 0; $f->attr('id+name', 'upload_csv'); $f->label = 'Upload CSV'; $f->icon = 'download'; $f->destinationPath = $tmpDir; // here we set a custom destination path $form->add($f); $form->add([ 'type' => 'submit', 'name' => 'submit', 'icon' => 'download', 'value' => 'Import', ]); if($this->input->post->submit) { $form->processInput($this->input->post); // if there where any errors we exit early and render the form // we also exit here if no files where uploaded if($form->getErrors() OR !count($f->value)) return $form->render(); // loop all uploaded files // here we have only one file maximum, but still it is an array foreach($f->value as $pagefile) { // the regular pagefile's filename is incorrect because it links to // /site/assets/files and not the tempDir, so we get the correct path $file = $tmpDir . $pagefile->basename; // ####################################### // now do whatever you want with that file // ####################################### } // redirect to somewhere $this->session->redirect("/admin/somewhere/"); } // form was not submitted, so render it return $form->render(); } The result: When you upload an invalid file it will show a warning:
    2 points
  9. FieldtypeMatrix and InputfieldMatrix Modules Directory: http://modules.processwire.com/modules/fieldtype-matrix/ GitHub: https://github.com/kongondo/FieldtypeMatrix The module Matrix enables you to save data from a 2D-Matrix table. The rows and columns of the matrix table are made up of pages retrieved via a ProcessWire selector or via a page field selection of parent pages. The matrix values are made up of the data input in the matrix cells, i.e. the 'intersection of rows and columns'. Example Usage You have Products whose prices vary depending on colour, size, material, etc. Using the Fieldtype, you can create a table with rows made up of colours and columns made up of sizes the combination of each making up their respective values (in this case price). So rather than creating multiple text fields to do the following: Colour Size Price Red Small £10 Red Medium £20 Red Large £30 Red X-large £35 Green Small £9 Green Medium £15 Etc... You can instead have the following in one field: Small Medium Large X-Large Red £10 £20 £30 £35 Green £9 £15 Blue Etc... Yellow Purple If you set a selector in the Field's settings, to retrieve pages to build your matrix's rows and columns, it follows that all pages using the template the Fieldtype is attached to will have identical rows and columns. In some cases, this could be the intention. For instance, you might have 'Car' pages, e.g. Audi, Volvo, Ford, Citroen, Mazda, BWM, etc., each of which uses a 'Cars' template that has a single FiedltypeMatrix called 'car_attributes'. If you set a selector to build the Fieldtype's rows and columns, your users can easily compare the cars based on a combination of different values. The following matrix table best illustrates this: Type Engine Size Fuel Efficiency Carbon Emissions Warranty Road Tax Price 1994 Audi brand 1 values, etc. 2000 Audi brand 2 2006 Audi brand 3 2012 Audi brand 4 Each of your car pages would have similar matrices. This allows you to make easy but powerful queries. Such a setup allows you to compare within and across car brands. Say you wanted to find out which car(s) offered the best value for money given certain parameters such as warranty, emissions etc. You can easily make such comparisons (see code below). You can also compare within one car type, e.g. which brand of BMWs does best in what area...The possibilities are endless. In the database, Rows and column pages data are stored as their respective page->id. Matrix-values store any data (varchar(255)). If instead you wanted a template's pages to each have a matrix built of different rows and columns, you would have to name a Multiple Page Field (attached to the same template as the as your matrix field) in the matrix field's settings. When editing those pages, your matrix table's rows and columns will be built using the published children pages of the 2 pages you select in the Multiple page field.. The module allows the creation of matrix tables of any sizes (rows x columns). The rows and columns dynamically grow/shrink depending on the addition of row/column pages that match what you set in the matrix field's settings (see its 'Details Tab'). Please note that, if such pages are deleted/trashed/hidden/unpublished, their data (and presence) in the matrix are also deleted. Entering values in the matrix You have three choices: Manually entry Uploading a comma delimited (CSV) file. This can be delimited by other characters (tab, pipe, etc); not just commas Copy-pasting CSV values. (Tip: you can copy paste directly from an Excel spreadsheet. Such values will be 'tab-delimited'). In addition, if your server supports it, in the field's settings, you can enable the use of MySQL's fast LOAD DATA INFILE to read and save your submitted CSV values. Note that for large tables, you may have to increase your PHP's max_input_vars from the default 1000 otherwise PHP will timeout/return an error and your values will not be saved. I have successfully tested the module with up to ~3000+ values (10x350 table), the Fieldtype is not really optimised (nor was it intended) to handle mega large matrix tables. For such, you might want to consider other strategies. Install Install as any other module. API + Output A typical output case for this module would work like this: The matrix's rows, columns and values are subfields of your matrix's field. So, if you created a field called 'products' of the type FieldtypeMatrix, you can access as: product.row, product.column and product.value respectively foreach($page->matrix as $m) { echo " <p> Colour: $m->row<br /> Size: $m->column<br /> Price: $m->value </p> "; } Of if you want to output a matrix table in the frontend: //create array to build matrix $products = array(); foreach($page->matrix as $m) $products[$m->row][$m->column] = $m->value; $tbody ='';//matrix rows $thcols = '';//matrix table column headers $i = 0;//set counter not to output extraneous column label headers $c = true;//set odd/even rows class foreach ($products as $row => $cols) { //matrix table row headers (first column) $rowHeader = $pages->get($row)->title; $tbody .= "<tr" . (($c = !$c) ? " class='even' " : '') . "><td class='MatrixRowHeader'>" . $rowHeader . "</td>"; $count = count($cols);//help to stop output of extra/duplicate column headers foreach ($cols as $col => $value) { //matrix table column headers $columnHeader = $pages->get($col)->title; //avoid outputting extra duplicate columns if ($i < $count) $thcols .= "<th class='MatrixColumnHeader'>" . $columnHeader . "</th>"; //output matrix values $currency = $value > 0 ? '£' : ''; $tbody .= "<td>" . $currency . $value . "</td>"; $i++; } $tbody .= "</tr>"; } //final matrix table for output $tableOut = "<table class='Matrix'> <thead> <tr class=''> <th></th> $thcols </tr> </thead> <tbody> $tbody </tbody> </table>"; echo $tableOut; The module provides a default rendering capability as well, so that you can also do this (below) and get a similar result as the first example above (without the captions). echo $page->matrix; Or this foreach($page->matrix as $m) { echo $m; } Finding matrix items The fieldtype includes indexed row, column and value fields. This enables you to find matrix items by either row types (e.g. colours) or columns (e.g. sizes) or their values (e.g. price) or a combination of some/all of these. For instance: //find all pages that have a matrix value of less than 1000 $results = $pages->find("products.value<1000"); //find some results in the matrix (called products) of this page $results = $page->products->find("column=$country, value=Singapore");//or $page->products->find("column=$age, value>=25"); //$country and $age would be IDs of two of your column pages Other more complex queries are possible, e.g. find all products that are either red or purple in colour, come in x-large size and are priced less than $50. Credits @Ryan on whose Fieldtype/InptufieldEvents this is largely based @charger and @sakkoulas for their matrix ideas Screens Field Details Tab Inputfield Larger matrix table Example output
    1 point
  10. Hello All, I've been working on a new Fieldtype + Inputfield combination that handles street addresses. I've been using it now for about 3 months on my latest administration system for a charity and, so far, it seems to be working really well for them. It's based on the meta-data from Google's LibAddressInput project and uses the data feeds from that to build a cache of address formats used by various countries. My initial testing was aided by @Macrura and @adrian - and they were later joined by @mel47 and @BFD Calendar - so a big thank-you to them all. You can access the repository on GitHub and the Module Repository. Here's a few images from the project. First up: config screen. Here's an early version... ...and a more recent update... Here's a UK-based address. The module can integrate with my tag parser, if installed. Note that the output is formatted according to the output meta-data from the feed - which should match the preferred postal preferences of the destination country. Which subfields are required, and their regex expressions (if any) are also pulled from the feed and used as validation rules on the input side. Here's an address in the Netherlands - inputfield layout is currently adjusted on save - if you've configured it to adjust based on the destination country. Hopefully this will eventually be ajax driven. Use of the address preview is configurable and the HTML output can include micro-format data. Address sub-fields can also be used in selectors... Back with inputs, if you prefer a table-based input - you can have it... Format hints (unfortunately, I've found that many users need these)... Let me know if you find any issues or if you have any feature requests. So far, I have this from the previous testers... Allow multi-lingual address input for countries that support a multi-lingual postal system (like Canada.)
    1 point
  11. I challenged myself for something similar in the past but ended that due to my lack of knowledge in JS/AJAX handling. The thing I mentioned before was done with Angular JS - and a third-party developer involved to do that magic - and I re-created the JSON he needed in PW-page/queries. If it's ok I will dig through to my archives the following weekend and look for the templates/JSON I created for that project. It will not be perfect for your things but maybe it gives you an idea somehow.
    1 point
  12. Ok... I get it. Well... sessions are sometimes a thing on its own. In some settings my sessions live forever and sometimes they expire right away.
    1 point
  13. Yep, but this is only with the GD lib. Unfortunatly the gamma correction brings some advantages for most the images, but is worse for images with very dark parts. Maybe I should check out if we can detect such candidates on upload and flag them for automatic disabling gamma correction (whit GD). But currently I have no clue if this can be done with reasonable accuracy.
    1 point
  14. Cool! Thank you guys! I will go through this all.
    1 point
  15. Hi @kongondo, we've tested your new MM 012, great work! In grid view, there is a small bug in rendering thumbnails: If the calculated width is not a whole number, the style of the elements div.mm_page_thumb is written as "width: 263,5px" for example. Because browsers expect decimal numbers in CSS with a dot, they fail in case of the comma, so the width is undefined and the thumbnail is not shown (see screenshot). This error probably only occurs in german environments, where the decimal point is the comma by default. I've changed line 524 in MediaManagerRenderer.php, what fixed the problem: $wrapperWidth = str_replace(',', '.', $media->thumbWidth) . 'px'; Alternatively, rounding the thumb width will have the same effect, because the decimal part isn't really important on rendering. Greetings, Thomas.
    1 point
  16. I'm not sure if it is but possibly yes. Try passing it inside the "overrides" array: https://github.com/rolandtoth/FrontEndEditLightbox#individual-overrides-overrides $mycalc->feel(array( "text" => "edit", "overrides" => array( "selectorsToHideSuperUser" => "#_ProcessPageEditDelete, #ProcessPageEditDelete" ) ) );
    1 point
  17. 1 point
  18. @Gadgetto There is nothing special in using preloadFor method. All you have to do is to call it before any calls of get method $cache->preloadFor($this->className()); As you can see I have a lot of chunks of cache namespaced with TestsDashboard. Instead of multiple select queries 67 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2725, null) 68 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2726, null) 69 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2727, null) 70 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2728, null) 71 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2729, null) 72 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2730, null) 73 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2731, null) 74 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2732, null) 75 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2733, null) 76 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2734, null) 77 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2735, null) 78 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2736, null) 79 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2737, null) 80 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2738, null) 81 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2739, null) 82 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2740, null) 83 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2741, null) 84 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2742, null) 85 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2743, null) 86 SELECT name, data FROM caches WHERE (name=:name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__test-intro-2744, null) using preloadFor I will load them to memory from DB only with one query and then all next calls of get will load them not from DB, but from memery SELECT name, data FROM caches WHERE (name LIKE :name1) AND (expires>=:now OR expires<=:never) -- cache.get(TestsDashboard__*, null)
    1 point
  19. Hi @gregory, What is the field type of "type"?? Please provide more info about your template and field settings. Gideon
    1 point
  20. As long as the language switcher is concerned: if you only have two languages, then you can do this in your template file: <a href="<?= $page->localUrl($languages->findOther()->first()) ?>"><?= $user->language->name == "default" ? "EN" : "HU" ?></a> Regarding translatable strings, I recommend this method (but in the forum you can certainly find other methods too in order to get inspiration from) :
    1 point
  21. I meant the browser based Visual Studio Online, mentioned at the end of the article, that will be coming in the future. Although it might be not be for you, that was the real news. ?
    1 point
  22. Microsoft announced Visual Studio Online: https://devblogs.microsoft.com/visualstudio/intelligent-productivity-and-collaboration-from-anywhere/ @bernhard Could be what you are looking for. ?
    1 point
  23. @MrSnoozles and everyone! This project is certainly halted at the moment and we are discussing what to do with it. We have not publish because one of our original intentions was to make it a Pro module. We still need to clear our heads from work and decide what to do.
    1 point
  24. Just want to thank @horst for all his work on the WebP integration and the effort for explaining many things (of which I am aware, because I also have a background in image retouching and stuff, but most people do not).
    1 point
  25. I think it is independent from the source. The compression is set for the output format, that is webp, regardless what was the source format. It can be JPEG, PNG, GIF, TIFF, BMP or any other image file format that can be opened by the proceeding rendering engine. (For IMagick most often one out of 230+) In this context, we can use lossless for sources from JPEGs too. But because in my tests it seems to be exact or nearly the same like quality 100, I had not seen a valid reason to bloat our imageSizerOptions with another setting, what then would need to be checked for its existence and compared against webpQuality. Also: HINT: if one passes wrong values for webpQuality, out of range (1-100), the webp rendering method automatically falls back to lossless. So if you use 100 or anything above 100 for webpQuality, you get lossless. ?
    1 point
  26. Because it is not a "normal" image format by its intended purpose! As far as I understood, you upload already compressed images that you don't want to proceed further? Note: 1) Already (not lossless) compressed images should not be used for any transformation, because the images are lacking lots of information due to the compression. (like the webp format!) 2) If you do not want to use the resize functionality, you have to provide the final webp by yourself too. PW only provides webp support for PW created variations for final output. This is due to the file formats nature or its intended purpose. Maybe you don't want or need a webp variation for admin thumbs. Maybe other users don't care. Maybe some users really like it when opening a editor page with 300 images displayed as admin thumbs. I cannot answer this other then: It may depend on a lot of different things? I really would like to discuss the general webp support first, and the less common use cases like this later on, in a following fine tuning phase. ----------- AFAIK the most common case is to use the pageimage system with uploaded uncompressed images that serves as master images. Those master images are never get served to the outside "as is". They every time get transformed into a variation file that is optimized and finalized for a specific purpose! At least this is the only correct way for an error-free workflow with maximum possible quality combined with smallest possible file size! Whether people understand this or not, my almost 30 years of expertise in the photographic industry has never shown me anything else. And all my work within the PW images system is (and only can be) based on this. ----------- I know that there also is a minor usage of the pageimage fields for simply displaying the original files to the frontend, but my best bet is that this is much lower then 10%. In my opinion this is not the intended use case for pageimages. The use of a file field would suffice, if it also could display an admin thumbnail in the backend. But because this functionality is missing in a file field, pageimage fields are used as "compromise solution" for this purpose.
    1 point
  27. Hi, I've added an addInlineImage() method to https://github.com/chriswthomson/WireMailMailgun <?php $img = $pages->get(1)->images->getRandom(); // An example $customFilename = "test.$img->ext"; // Don't want to use the basename for this example $mg = $mail->new(); $mg->to("your@email.com") ->subject("Test Inline Image") ->bodyHTML("<p>Testing, 123, is there an image for you to see?</p><img src='cid:$customFilename'>") ->addInlineImage($img->filename, $customFilename) // Second argument is optional ->send(); If the image isn't referenced in the HTML it just appears as a standard attachment from what I can see. Cheers, Chris
    1 point
  28. I use WireMailSmtp successfully with the following services/webhosting providers: Gmail (@gmail.com) Google for Domains (Google Apps) Yandex for Domains Outlook.com (Freemail) Strato (Webhosting, DE) 1&1 (Webhosting, DE) Checkdomain (Webhosting, DE) webgo (Webhosting, DE) Dreamhost (Webhosting, US) A2hosting (Webhosting, US)
    1 point
  29. @mrkhan please refer to https://support.office.com/en-us/article/POP-IMAP-and-SMTP-settings-for-Outlook-com-d088b986-291d-42b8-9564-9c414e2aa040 Specifically: SMTP server name smtp-mail.outlook.com SMTP port 587 SMTP encryption method STARTTLS
    1 point
  30. As @Macrura said in most cases ProCache and WireCache is the way to go for me. Also what I have found super useful is namespaces for WireCache, as for the example you can load all cache for a page with namespaced cache and preloadFor method just with one query. There is CacheNesting module, I haven't used it but it should help to handle such scenarios https://modules.processwire.com/modules/cache-nesting/.
    1 point
  31. Set $event->cancelHooks and $event->replace to true in your first hook. Edit: First one should be enough.
    1 point
  32. Hi all! I have created this new module that improve the current search engine on PW: https://github.com/USSliberty/Processwire-site-indexer (Beta version) The main idea is to create an hidden field that store keywords (separated by space). The keywords are generated automatically from all text fields in the page, plus PDFs and DOCs files. So if you create new text fields you can forget to add they on Search Page Module. The only thing to do after install, is to change the list of fields in Search Page (see attachment). In fact you need to search only in "indexer" field. NOTE 1: At this time the module index only when you save the page. In the next week maybe i will add the complete-site re-index. NOTE 2: The files are indexed with 2 Unix packages (poppler-utils & wv). I have tried without success with pure PHP classes, but if know a class that works fine i can add it into module. ADB
    1 point
  33. $num = 10; // u.tell it how.manys file ob_start(); $path = rtrim(wire('config')->paths->files, '/'); passthru("find $path -type f -exec stat -f '%m %N %m' {} \; | sort -n | tail -$num | cut -f2- -d' '"); $data = explode("\n", trim(ob_get_contents())); ob_end_clean(); foreach($data as $line) { list($file, $ts) = explode(' ', $line); echo date('Y-m-d H:i:s', $ts) . " - $file<br />"; }
    1 point
×
×
  • Create New...