Jump to content


Popular Content

Showing content with the highest reputation on 07/30/2020 in all areas

  1. 4 points
    Maybe useful for you @teppo. In one of my last projects I integrated a lightbox gallery that outputs both videos and pictures. The data source for the videos and images was a PageFile field. Here is an excerpt from the template in which the gallery was integrated via Javascript. Resizing works similarly as suggested by @Robin S // galleries $page->_galleriesJS = ''; $galleriePages = $pages->find('template=gallery'); // 16:9 inline video $markup = '<div class="mfp-video-wrapper"><div class="mfp-video-inner"><video width="854" height="480" controls autoplay preload> <source src="{src}" type="video/mp4"> Leider wird dieses Video von ihrem Browser nicht unterstützt. </video></div></div>'; if ($galleriePages->count) { $galleries = ''; foreach ($galleriePages as $gp) { if ($gp->files->count == 0) continue; $items = []; $filesDirPath = $gp->files->path; foreach ($gp->files as $gi) { if (!fileExists($gi->url)) continue; // inline video if (in_array($gi->ext, array('mp4','m4v','ogg','ogv','mpg'))) { $src = str_replace('{src}', $gi->url, $markup); $items[] = ['type' => 'inline', 'src' => $src]; } // wrong file type else if (!in_array($gi->ext, array('png','jpg','jpeg'))) throw new WireException("Unallowed Fileformat $gi->ext for magnificPopup Gallery"); // any image with youtube video source in description else if (strpos($gi->description, 'youtube')) { $oembed = getVideo($gi->description); if ($oembed) { // nocookie source used $items[] = ['type' => 'iframe', 'src' => $oembed->frameUrl]; } } // image else { $src = $gi->url; $copyFileName = strstr($gi->filename, $gi->ext, true) . '1200x0.' . $gi->ext; list($width, $height) = getimagesize($gi->filename); if ($width > 1200) { if (!file_exists($copyFileName)) { $files->copy($gi->filename, $copyFileName, ['limitPath' => true]); $imageSizer = new ImageSizer($copyFileName); $imageSizer->resize(1200, 0); } $src = str_replace($config->paths->root, '', $copyFileName); } $items[] = ['title' => $gi->description, 'src' => $src]; } } $gallery = [ 'gallery' => ['enabled' => true], 'type' => 'image', 'midClick' => true, 'mainClass' => 'mfp-lightbox-wrapper', 'items' => $items, 'tClose' => 'Schließen (esc)' ]; $gallery = json_encode($gallery); $galleries .= "$('.mfp-open-$gp->id').magnificPopup({$gallery})\n"; } $page->_galleriesJS = "<script> $galleries</script> "; }
  2. 4 points
    I'm not quite sure if you mean thumbnails within the Files inputfield in the PW admin, or if you mean you want to resize the image file for the front-end. If it's the latter you could use a function or module method along these lines: function getResizedImageUrl(Pagefile $pagefile, $width, $height) { $variation_basename = $pagefile->basename(false) . ".{$width}x{$height}." . $pagefile->ext(); $variation_filename = $pagefile->pagefiles->path . $variation_basename; if(!is_file($variation_filename)) { copy($pagefile->filename, $variation_filename); $sizer = new ImageSizer($variation_filename); $sizer->resize($width, $height); } return $pagefile->pagefiles->url . $variation_basename; } $file = $page->files->first(); $resized_url = getResizedImageUrl($file, 400, 300);
  3. 3 points
    @teppo You already got setup by Kixe and Robin. So, only thing that I can contribute is, if you are using this in an environment that allows overwriting existing files with same filename, you should bind a check of last modified timestamps into your program logic: If fileFieldItem is image and not thumbnail exists: create a thumbnail If fileFieldItem is image and not thumbnail exists OR if origTimestamp is newer than thumbnailTimestamp: create a (new) thumbnail
  4. 3 points
    Yes, this is called bootstrapping, see the documentation. Basically, you only need to include ProcessWire's index.php, then you can use the API as usual. The only difference is that you won't have access to the $page variable, since it's not a regular ProcessWire page request, so ProcessWire can't associate a particular page with it.
  5. 3 points
    Awesome, thanks @Robin S and @kixe! Manually copying the file and using ImageSizer on it seems like a really nice approach. Don't think I've ever done that myself; in some cases I've accessed Imagick or GD directly, but this is definitely cleaner 🙂
  6. 3 points
    The output of the path history on the settings-tab is only visible to superusers. However, you can access the path history of a page through the API. The module has no access restrictions. You may want to output the information somewhere else. $modules->get('PagePathHistory')->getPathHistory($page); Just in case, if you need to access a module with access restriction: $modules->getModule('ModuleWithRequiredPermission', ['noPermissionCheck' => true]);
  7. 3 points
    Well this was a great one to do. The Beyond Banglatown site is the public facing site for a report conducted by researchers at the London School of Economics and the University of Manchester, and published by the Runnymede Trust. The aim is to present the findingsof the report in a publically accessible way that can be used by teachers and students and well as the general public. It covers the changing face of the neighbourhood around Brick Lane in East London. https://beyondbanglatown.org.uk/ Technically this was the first project we used ProcessWire on - although what with one thing and another it's taken 18 months to get the site launched, so we've managed to get a few others out before this one. It was certainly jumping in at the deep end though and we learned a lot. The site involves a fair amount of ajax driven content and we had to get to grips with importing the data used for the maps and graphs as well as sorting out how best to manage templates and assets. As far as modules that we used there's nothing too exciting, but certainly we made good use of TracyDebugger as we fumbled about. A special mention also needs to go to the PW documentation, the API references and of course this forum which provided a great deal of help. Anyway - we're really pleased with the site and it's already been getting very good coverage. Hopefully the first of many PW sites. s.
  8. 2 points
    I found a post on how to check if a field type is present. Now it seems to work great: // add style fields $this->addHookAfter('Pages::added', function(HookEvent $event) { $page = $event->arguments(0); $fields = wire('fields'); // add fields only if FieldtypePageTableExtendedGrid is inside template foreach ( $page->fields as $field ) { if ( $field->type instanceof FieldtypePageTableExtendedGrid ) { if(!$fields->get('pgrid_settings_style_large')) { $field = new Field; $field->type = $this->modules->get("FieldtypeTextarea"); $field->name = "pgrid_settings_style_large"; $field->label = $this->_("Style Large"); $field->tags = 'pgrid'; $field->save(); } if(!$page->hasField('pgrid_settings_style_large')) { $field = $fields->get('pgrid_settings_style_large'); $template = $page->template; $template->fieldgroup->add($field); $template->fieldgroup->save(); } } } });
  9. 2 points
    Hello kixe, I guess it's a good idea that the pph-module is working silently in the background for non-super-users. And your examples are good to know and helpful. Thank you for your instant reply!
  10. 1 point
    I think you have to hook into Page::viewable, then detect if user has role reviewer and page is unpublished. If yes, you can change the return to true. Please search for hook examples with Page::viewable here in the forums. There will be some available. Or you look into existing modules how it is done there, like this one: https://github.com/Sebiworld/PageAccessReleasetime/blob/master/PageAccessReleasetime.module.php#L182-L201 and here https://github.com/Sebiworld/PageAccessReleasetime/blob/master/PageAccessReleasetime.module.php#L241-L254 And you don't need to build a module, you can write the hook into the site/ready.php file.
  11. 1 point
    Yes, thanks. @horst found out the same and wrote this tutorial 😄
  12. 1 point
    The gain of "nicer looking" IDs is way smaller than the possible loss of consistency or risk of side effects not being aware of...
  13. 1 point
    this looks like a good fit for my usecase! Now I hit another roadblock. I want the fields to be grouped together in a fieldset that can be collapsed. How would I do this with the inputfields approach? EDIT: Figured it out, here is my final code: $this->addHookAfter('ProcessPageEdit::buildForm', function (HookEvent $event) { $form = $event->return; $page = $event->object->getPage(); // make sure we're editing a page and not a user if ($event->process != 'ProcessPageEdit') return; if (!$page->template->hasField("pgrid")) return; $submitButton = $form->getChildByName('submit_save'); if ($submitButton) { $fieldset = $event->wire('modules')->get('InputfieldFieldset'); $fieldset->label = 'Fieldset Test'; $field1 = $event->wire('modules')->get('InputfieldText'); $field1->set('label', __('Test123')); $field1->set('name', __('test123')); $field1->addClass('test123'); $fieldset->append($field1); // append the field $form->insertBefore($fieldset, $submitButton); } $event->return = $form; }); @MoritzLost thanks again for your help, this was very helpful!
  14. 1 point
    @Zeka That's correct. V4 is split out into a bunch of different classes like this, as ProCache has grown quite a bit. It's possible I might not understand what you mean. But ProCache only clears cache files that exist. It knows ahead of time which ones exist because there's a corresponding DB table entry for every cache file. So it shouldn't attempt to find or clear files for any languages that don't have the content available in the cache. Meaning, so long as the page isn't published in the language that it lacks content in, ProCache isn't going to be attempting to write or clear cache files for that page in that language it's not available in (i.e. no extra overhead). But if what you are looking for is more logic in determining whether a page is cleared for a particular language, that clearPage() call in the earlier hook I mentioned does also accept a 'language' option which limits the clear to a particular language. You can also tell it to clear only a particular URL segment, or segments matching a wildcard pattern. Here's the options for the clearPage method: /** * Clear the cache for a specific page * * Default behavior is to clear for all languages, paginations and URL segment variations. * To clear only specific languages, paginations or URL segments, use the options. * * @param Page $page * @param array $options * - `language` (string|int|Language): Clear only this language (default='') * - `urlSegmentStr` (string): Clear only entries matching this URL segment string, wildcards OR regex OK (default='') * - `urlSegments` (array): Clear only entries having any of these URL segments (default=[]) * - `pageNum` (int|bool): Clear only pagination number (i.e. 2), true to clear all paginations, false to clear no paginations (default=0) * - `clearRoot` (bool|null): Clear root index of page path? (default=false when URL segments or paginations requested, true otherwise) * - `rmdir` (bool): Remove directories rather than index files? (default=false) * - `getFiles` (bool): Get array of files that were cleared, rather than a count? (default=false) * @return int|array Quantity or array of files and/or directories that were removed * */ I think we've got all the tools we need to support that kind of logic on the hook side, but ProCache doesn't do that automatically at present. It's a good idea though, I can explore it further.
  15. 1 point
    Ah, ok. Interesting ideas. The hanna code seems to have worked for now, but I'm going to look more into ACF (didn't know about that!). Thanks!
  16. 1 point
    Just wanted to link a solution for people that are in a hurry 😄
  17. 1 point
    Please teach Mirja the difference between ´, ` and ’, or install Super Smartypants.
  18. 1 point
    I updated my forked version of AIOM+ to 4.0.0 https://github.com/matjazpotocnik/ProcessWire-AIOM-All-In-One-Minify It adds "AIOM+ template caching" :-) My tests shows noticeable improvements in render times, dropping from like 300 ms (on localhost) to 10 ms. I guess ProCache would be even faster (don't have it, can't test). If anyone wanna try this early alpha version, please read README.md (must read).
  19. 1 point
    Just wanted to share the simplest language switcher possible if you only have two languages: <a href="<?= $page->localUrl($languages->findOther()->first()) ?>">DE/EN</a> 🙂
  20. 1 point
    I made this with Page Tables. It's not 100% perfect yet, but works for my demands _init.php: // Main Content if ($page->views) { $content = "<div id='views' data-uk-grid-margin>"; $contentview = ""; foreach ($page->views as $view) { $typ = $view->template; $id = $view->name; $colxl = $view->colxl; $gridcountxl = $colxl; $colsm = $view->colsm; $gridcountsm = $colsm; $colxs = $view->colxs; $gridcountxs = $colxs; $fw = $view->fullwidth; $nmnp = $view->removemargin; $border = $view->hasborder; switch ($typ) { case "Text": $text = $view->textfield; $ct = "<div id='{$id}' class='uk-width-small-". $colxs ."-12 uk-width-medium-". $colsm ."-12 uk-width-large-". $colxl ."-12'>$text"; $ct .= checkGrid($gridcountxs, $gridcountsm, $gridcountxl); $ct .= "</div>"; $contentview .= fullWidth($fw, $cv=$ct, $nmnp, $border); break; case "SlideGalerie": $bilder = $view->images; $sg = ""; $sg .= "<div id='{$id}' class='product-gallery views owl-carousel owl-theme'>"; foreach ($bilder as $b) { $bbig = $b->width(1920, $options); $bsmall = $b->size(485,325, $options); $bretina = $b->size(970,650, $options); $sg .= "<div class='g-item'>"; $sg .= "<a href='{$bbig->url}' data-uk-lightbox=\"{group:'{$view->name}'}\">"; $sg .= "<img data-src='{$bsmall->url}' data-src-retina='{$bretina->url}' class='owl-lazy' alt='$b->description'>"; $sg .= "</a>"; $sg .= "</div>"; } $sg .= "</div>"; $sg .= checkGrid($gridcountxs, $gridcountsm, $gridcountxl); $contentview .= fullWidth($fw, $cv=$sg, $nmnp, $border); break; // Case .. Case .. Case .. } $content .= $contentview; $content .= "</div>"; } _func.php /** * @param string $gridcountxs * @param string $gridcountsm * @param string $gridcountxl * @return string */ function checkGrid($gridcountxs = '', $gridcountsm = '', $gridcountxl = '') { $out = ''; if ($gridcountxs >= 12) { $out .= "<div class='uk-clearfix uk-visible-small'></div>"; } if ($gridcountsm >= 12) { $out .= "<div class='uk-clearfix uk-visible-medium'></div>"; } if ($gridcountxl >= 12) { $out .= "<div class='uk-clearfix uk-visible-large'></div>"; } return $out; } /** * @param string $fw * @param $cv * @param string $nmnp * @param string $border * @return string */ function fullWidth($fw = '', $cv, $nmnp = '', $border = '') { if ($nmnp) { $nomargin = 'uk-margin-top-remove'; } else { $nomargin = ''; } switch ($border) { case '1': $b = 'border-top'; break; case '2': $b = 'border-right'; break; case '3': $b = 'border-bottom'; break; case '4': $b = 'border-left'; break; case '5': $b = 'border-all'; break; default: $b = ''; break; } $fout = ''; if ($fw) { $fout = "<div class='full-width " . $nomargin . " " . $b . "'>" . $cv . "</div>"; } else { $fout = "<div class='uk-container uk-container-center uk-margin-large-top " . $nomargin . "'><div class='uk-grid " . $b . "'>" . $cv . "</div></div>"; } return $fout; }
  21. 1 point
    Two page arrays result in this: date 1 | date 2 - 1 - 2 - 3 1 2 3 4 Or the other way around. It's not merging the dates. But if all pages are fetched no matter what (no pagination) it works like that: foreach($myPages as $p){ $p->set('sortDate', $p->date1 ?: $p->date2); // Runtime field } $myPages->sort("sortDate");
  22. 1 point
    I like these posts, clear titles, quick answers.
  • Create New...