Jump to content

abdus

Members
  • Posts

    743
  • Joined

  • Last visited

  • Days Won

    42

Everything posted by abdus

  1. Use Page Reference & Repeater fields. Seriously. They're immensely powerful if you know how to utilize them. There's a blog post that explains how you might use Page Reference fields for toggling states and attributes, but you can also use them for ordering things, as it saves the order of the pages you referenced too. What you should do: Create 3 dummy templates, "home-block", "container", and "block-type". You can use tags in Advanced tab and put "-home" to hide them away. Create the following pages /processwire (your admin root page) +---tools/ (template: container) (hide this page) +-home-blocks/ (template: container) | + hero (template: home-block) | + what-we-do | + our-work | + testimonials | ... other blocks | +-block-types/ (template: container) + full-width (template: block-type) + half ... other types Create a Page reference field, set its inputfield to select, limit to single item and only pages with "home-block" template under /tools/home-blocks Create another page field, this time set its inputfield to Checkboxes and limit it to "block-types" under /home/block-types Create a repeater homeLayout and add these two page fields to it Add the repeater field to home template. Add any block you want using the repeater in any order and add any property you want to any container. Using this blog post as your guide, loop over the repeater items and find which block has been selected, render your block (you can put your block codes under templates/block and render them individually with $files->render()) with the options in the order your client/you selected
  2. Created an issue and pull request with a fix https://github.com/processwire/processwire/pull/91 https://github.com/processwire/processwire-issues/issues/385
  3. Hmm. I am having the same issue. I did some debugging. It looks like the module is working as intended, and sending response to frontend with 'data-nosize' attribute set correctly. But in pwimage plugin for CKEditor, nosize setting isn't used at all. // pwimage/plugin.js function insertImage(src) { var $i = $iframe.contents(); var $img = jQuery("#selected_image", $i); // ... var $insertHTML = jQuery("<img />").attr('src', src).attr('alt', alt); // ... if (width > 0) $insertHTML.attr('width', width); // ... editor.insertHtml(html); // ... }
  4. It applies to images added after the setting is changed.
  5. @pwFoo MarkupCache only supports strings and uses files for storage. WireCache supports arrays (of non-objects), PageArray and strings and uses DB for storage. WireCache is the way to go.
  6. Template cache is bound to the template of the current page. When rendering a page, regardless of how many files you render or include, only the markup that is output to the browser will be cached into a file (can be found in /site/assets/cache/Page/<id>), so that the render routine can be skipped if request can be responded with the cached output. If you want to cache arbitrary bits of markup you can use WireCache class with $cache API variable, or use MarkupCache module. $layout = $cache->getFor($page, 'layout'); if (!$layout) { $layout = $files->render('layout.tpl', [ 'title' => $page->title, 'content' => $page->body ]); $cache->saveFor($page, 'layout', $layout, WireCache::expireDaily); } One thing to note is that template cache, by default, is disabled when you're logged in. https://processwire.com/api/ref/wire-cache/ https://processwire.com/talk/topic/7-new-markupcache-module/
  7. You need to use $page argument. Also remember to check if field is actually the field you want. wire()->addHookAfter('InputfieldRepeater::renderRepeaterLabel', function (HookEvent $e) { /** @var Page $page */ $field = $e->object->hasField; // check the field if ($field != "events_detail_dates") return; $page = $e->arguments('page'); $e->return = date('D. j F Y', $page->events_detail_dates_start_date); });
  8. You can hook into InputfieldRepeater::renderRepeaterLabel and change $event->return. wire()->addHookAfter('InputfieldRepeater::renderRepeaterLabel', function (HookEvent $e) { $field = $e->object->hasField; // check the field if ($field != "myRepeaterField") return; /** @var Page $page */ $count = $e->arguments('cnt'); $page = $e->arguments('page'); $labelDate = date('y-m-d', $page->published); $label = substr($page->getText('title|body'), 0, 20); $e->return = "{$label} -- {$labelDate}"; }); Which renders as From the core: // InputfieldRepeater.module /** * Render the repeater label * * @param string $label Default label * @param int $cnt Item index (1-based) * @param Page $page Repeater item * @return string * */ public function ___renderRepeaterLabel($label, $cnt, Page $page) { ... }
  9. Hmm, it still works without wireInstanceOf() (which I believe is used for PW2 compatibility), but one bug I've found is that since FieldtypeFieldsetPage is a single repeater item, it doesnt return a RepeaterPageArray, instead returns the only item. Adding a check fixes it else if ($type instanceof FieldtypeRepeater) { $items = $page->{$f->name}; if (!$items) continue; if ($items instanceof PageArray) { foreach ($page->$f as $item) $tagged = array_merge($tagged, findTaggedImages($item, $tag)); } // FieldtypeFieldsetPage returns a single page instead of a PageArray elseif ($items instanceof Page) { $tagged = array_merge($tagged, findTaggedImages($items, $tag)); } } Updated the code in OP
  10. FieldtypeFieldsetPage extends FieldtypeRepeater, so you dont need to explicity specify FieldtypeFieldsetPage. class FieldtypeFieldsetPage extends FieldtypeRepeater implements ConfigurableModule { ... }
  11. To remove the breadcrumbs, and change headline and browser title: $this->addHookBefore('Process::execute', function (HookEvent $e) { /** @var Process $process */ $process = $e-object; if ($process != "ProcessModule") return; $e->wire('breadcrumbs')->removeAll(); $e->wire('processHeadline', 'asd'); $e->wire('processBrowserTitle', 'asd'); }); You can't really remove headline and browser title, because admin theme defaults to page name if it doesn't exist. // AdminThemeDefaultHelpers.php /** * Get the headline for the current admin page * * @return string * */ public function getHeadline() { $headline = $this->wire('processHeadline'); if(!$headline) $headline = $this->wire('page')->get('title|name'); // ... } /** * Render the browser <title> * * @return string * */ public function renderBrowserTitle() { $browserTitle = $this->wire('processBrowserTitle'); if(!$browserTitle) $browserTitle = $this->_(strip_tags($this->wire('page')->get('title|name'))) . ' • ProcessWire'; // ... } But you can set it to a unicode space character, like &nbsp; which works well enough. $e->wire('processHeadline', "&nbsp;"); $e->wire('processBrowserTitle', "&nbsp;");
  12. When you open the source dialog of CKE do you get just basic text? Try disabling ACF and Purifier, maybe one of them is misbehaving (don't leave it disabled though)
  13. A simple recursive function that walks over all image fields and those inside repeaters(including FieldtypeFieldsetPage) to find images tagged with a certain tag(s). It can easily be extended to file fields by changing instanceof FieldtypeImage to FieldtypeFile, or be restricted to file fields by adding a !$type instanceof FieldtypeFile, too. Adapted from ProcessPageEditLink::getFilesPage() method. /** * Find all images tagged with a certain tag in a page including repeater items. * * @param $page Page to search tagged images * @param $tag string|array Image tag(s). Can be 'foo' for single, 'foo|bar' for multiple OR tags, 'foo,bar' or ['foo', 'bar'] for multiple AND tags * @return array Tagged images in [basename => Pageimage] associated array form or empty an array */ function findTaggedImages(Page $page, $tag) { $tagged = []; foreach ($page->template->fieldgroup as $f) { $type = $f->type; if ($type instanceof FieldtypeImage) { /** @var Pageimages $images */ $images = $page->{$f->name}; if (!$images) continue; $tagged = array_merge($tagged, $images->findTag($tag)->getArray()); } else if ($type instanceof FieldtypeRepeater) { $items = $page->{$f->name}; if (!$items) continue; if ($items instanceof PageArray) { foreach ($page->$f as $item) $tagged = array_merge($tagged, findTaggedImages($item, $tag)); } // FieldtypeFieldsetPage returns a single page instead of a PageArray elseif ($items instanceof Page) { $tagged = array_merge($tagged, findTaggedImages($items, $tag)); } } } return $tagged; } And can be used as $featuredImages = findTaggedImages($page, 'featured'); // get first featured image $featured = reset($featuredImages); // or array_shift($featuredImages)
  14. It works fine for me $page->of(false); $page->body = $sanitizer->purify("<br />Some Content<br /><br />More Content"); $page->save();
  15. I find using sprintf() for formatting strings to be much cleaner http://php.net/manual/en/function.sprintf.php $count = $page->comments->count; $commentHeading = sprintf("Only %d %s commented on this recipe. Be the next one!", $count, _n('person', 'persons', $count));
  16. @MilenKo You can just use translation functions for this: echo _n('person', 'persons', $page->comments->count); From the core: // LanguageFunctions.php /** * Perform a language translation with singular and plural versions * * @param string $textSingular Singular version of text (when there is 1 item) * @param string $textPlural Plural version of text (when there are multiple items or 0 items) * @param int $count Quantity of items, should be 0 or more. * @param string $textdomain Textdomain for the text, may be class name, filename, or something made up by you. If omitted, a debug backtrace will attempt to determine automatically. * @return string Translated text or original text if translation not available. * */ function _n($textSingular, $textPlural, $count, $textdomain = null) { return $count == 1 ? __($textSingular, $textdomain) : __($textPlural, $textdomain); }
  17. From the top menu > modules > refresh Or go to setup > modules > refresh (the button on top right) http://processwire.com/blog/posts/processwire-core-updates-2.5.14/#multiple-copies-of-the-same-module
  18. You may need to replicate ids, class names, and input names in your markup from the original form, and include js files for rating system to work.
  19. $yesterdayEvening = strtotime('yesterday 21:00'); $todayEvening = strtotime('today 21:00'); $latest = $pages("<your selector>, created>=$yesterdayEvening, created<=$todayEvening"); http://php.net/manual/en/datetime.formats.relative.php
  20. Refresh the module cache, it should ask you which copy of the module to use.
  21. I'd say develop locally (use local database). To me, having a permanent ~70x2=140ms round-trip delay at every operation would be a frustrating experience. Using custom git hooks you can export & import sql databases from local <-> remote setups. Once the template & field infrastructure is complete you can utilize page import export feature to exchange pages between local & remote as well.
  22. At line 107 module iterates over $wire->languages, if it's not an iterable object, i.e. null, you'll get this error. If you can, try uninstalling all language modules, then reinstall starting from language support module.
  23. Most likely Javascript components didn't load Chrome gives this error on non-https forms Again, if scripts don't load you'll get this behavior.
  24. abdus

    DropboxAPI

    @benbyf are you using composer? Or manually downloading the packages? vendor directory and autoload.php is created when you require a package with composer.
  25. What happens when you add new options to that field? Or remove one? Or decide to create another select field before you change the old one? In the database, all select options are stored under a single table, this means ids may get intertwined with multiple option fields, they are not necessarily ordered neatly as "options of select1", "options of select 2" etc. Also, old ids aren't reused, instead new ids are assigned. All these condition are an invitation to undefined behavour. Ids aren't meant to be made arithmetic upon, they are what they are, identifiers and nothing more. If you need a field that can be incremented, use an integer field instead, you'll save much headache later. If you want to sanitize & limit the range of values, use field settings or hook into Page::saveReady and perform your sanitization there.
×
×
  • Create New...