Jump to content

Search the Community

Showing results for 'render('.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Welcome to ProcessWire
    • News & Announcements
    • Showcase
    • Wishlist & Roadmap
  • Community Support
    • Getting Started
    • Tutorials
    • FAQs
    • General Support
    • API & Templates
    • Modules/Plugins
    • Themes and Profiles
    • Multi-Language Support
    • Security
    • Jobs
  • Off Topic
    • Pub
    • Dev Talk

Product Groups

  • Form Builder
  • ProFields
  • ProCache
  • ProMailer
  • Login Register Pro
  • ProDrafts
  • ListerPro
  • ProDevTools
  • Likes
  • Custom Development

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

  1. Hi @Morphosis - glad you found a solution! Based on the module documentation on Github, you can also define this in your site/config.php using an array-based syntax. Choose whichever method you would prefer! Example: /** * Module: SearchEngine * * Override any module settings or other config values here. Anything set here * cannot be overridden. * */ $config->SearchEngine = [ // Render arguments affect the rendered output from the SearchEngine module. 'render_args' => [ // Various attributes used by the search form and results list when rendered. 'form_action' => '/search/', ] ];
  2. Hello all, @BFD Calendar - this did actually the trick. If no user is logged in the textblocks render once as expected. Thanks for the hint! I also figured out, that this behaviour depends on frontend editing, which is enabled for this particular field in my case. Once this is disabled, it also works fine even when logged on to processwire's backend. For my scenario I m fine, however, I think it is a small glitch and could be enhanced... any opinions if I should file a bug report for this and how and where? Many thanks!
  3. Hi @Jan S.! Welcome to the forum, and congratulations on your first post! We're glad to have you. 😊 Based on what you're showing, your code looks good from what I can see of the TextBlocks documentation, so I am not entirely sure what to suggest, other than maybe seeing if removing the "echo" from your template call to the field will still render the field. I don't think it should, but since it's being duplicated, it can't hurt to try. Beyond that, TextBlocks is a paid ProDevTools module, so support for that module is in its own forum, locked down for paid/active module owners. Assuming your module support status is up-to-date, that can be found in the ProFields Support subforum here.
  4. I think experimenting with a block-style editor would be great. In the very large discussion over WYSIWYG editors (I don't recall of this was a 2025 wishlist, or a discussion of the future of TinyMCE/CKEditor, but it had a LOT of paginated responses), a few people even experimented in creating a proof-of-concept with editor.js, showing their results. I gave it a shot but determined the end result (interface) was too cumbersome for most of my users (and I usually try to aim for a very low bar as a standard; less complaints / support needed). Even in the demo (tried today) I was able to cause a rendering bug in both of the editors mentioned (TipTap, Editor.js) above. That said, if a true module is attempted to be released, since they render and use JSON as the underlying structure, I would recommend using a similar database structure to TinyMCE and/or CKEditor, and save the HTML-rendered output in a field just in case someone wished to switch back to a standard text editor for a particular field. (Unfortunately that means only one-way compatibility, however - and increased storage costs/size...so maybe an option for that in the module.)
  5. enum TournamentType:string { case MYSTERY = "Mystery"; case PKO = "PKO"; case VANILLA = "Vanilla"; } class FilterSolvesForm extends AbstractFrontendForm { protected function buildForm(): void { $tournamentTypeSelect = new Select("tournamentType"); $tournamentTypeSelect->setLabel(__("Type de tournoi")); foreach (TournamentType::cases() as $tournamentType) { $tournamentTypeSelect->addOption($tournamentType->value, $tournamentType->value); } $this->add($tournamentTypeSelect); } } abstract class AbstractFrontendForm extends Form { public function __construct(string $id) { parent::__construct($id); $this->buildForm(); $this->addSubmit(); } private function addSubmit():void { $button = new Button('submit'); $button->setAttribute('value', __("Valider")); $this->add($button); } abstract protected function buildForm(): void; } // TEMPLATE PHP FILE $command = new SelectSolvesDatabaseCommand(1, 10); $filtersForm = new FilterSolvesForm("solvesFilterForm"); if ($filtersForm->isValid()) { // DevUtils::prettyPrintObject($filtersForm->getValue('tournamentType')); // $command->addFilter('tournamentType', $filtersForm->getValue('tournamentType')); } $filtersForm->showForm(true); $command->execute(); $solves = $command->getPaginatedSolves(); Twig::render('browse-solves', [ 'paginatedSolves' => $solves, 'filtersForm' => $filtersForm, ] );
  6. @Stefanowitsch asked about using the File Mover module with a "media library" page that is accessed via a modal. I thought I would share some hook code publicly in case it's useful for others too. // Add a button to file and image fields to open a media library page in a modal // Hook InputfieldFile::render to affect file and image fields, // or InputfieldImage::render to affect only image fields $wire->addHookAfter('InputfieldFile::render', function(HookEvent $event) { $inputfield = $event->object; // The field associated with the inputfield (if any) $field = $inputfield->hasField; // The page containing the inputfield (if any) $page = $inputfield->hasPage; // Don't add the button to fields on the media library page // as we don't want the possibility of nested modals if($page && $page->template == 'media_library') return; // You can also check the field name if the button should only be added to a specific field, e.g. // if($field && $field->name !== 'article_images') return; // Get the media library page $media_library = $event->wire()->pages->get("template=media_library"); // Construct the URL to edit the media library page $url = $media_library->editUrl; // Add &modal=1 so the admin header isn't shown $url .= '&modal=1'; // We don't need other tabs or fields besides the image/file field(s), // so specify the field name(s) in the URL // Unfortunately there is this layout bug: https://github.com/processwire/processwire-issues/issues/1972 $url .= '&field=images,files'; /** @var InputfieldButton $f */ $f = $event->wire()->modules->get('InputfieldButton'); $f->href = $url; $f->value = 'Open media library'; $f->icon = 'picture-o'; // Add pw-modal class so the button link opens in a modal $f->addClass('pw-modal'); // Make it a large modal $f->addClass('pw-modal-large'); // Add a bit of space above the button $f->attr('style', 'margin-top: 10px;'); // Append the rendered button to the inputfield $event->return .= $f->render(); });
  7. I'm experiencing a similar issue. The default language is English. The other language is French. Even when I set the guest user language to French in the user profile, it defaults to English on render. How do I get PW to recognise the guest user language?
  8. Hi, I'm in the process of relaunching a site of mine and wanted to build and test it side by side with the current site. I tried to set the template folder in ready.php for some users with $config→setLocation() to a different folder (as described here): $userNamesWithDevAccess = ['testuser']; if(in_array($user->name, $userNamesWithDevAccess)) { $config->setLocation('templates', 'site/templates-dev/'); echo '<pre>'; var_dump($config->urls->templates); var_dump($config->paths->templates); echo '</pre>'; } This seems to work as intended: string(21) "/site/templates-dev/" string(54) "/Users/myaccount/mysite/site/templates-dev/" But when I go to my frontend, there's only a blank page besides my var_dump. (Same blank page when I remove the var_dump test.) If I go to the backend I get the following error message: Hey now… Error: Exception: Missing or non-readable template file: site/templates-dev/site/templates/admin.php (in wire/modules/PageRender.module line 584) #0 wire/core/Wire.php (416): PageRender->___renderPage(Object(HookEvent)) #1 wire/core/WireHooks.php (968): Wire->_callMethod('___renderPage', Array) #2 wire/core/Wire.php (484): WireHooks->runHooks(Object(PageRender), 'renderPage', Array) #3 wire/core/WireHooks.php (1094): Wire->__call('renderPage', Array) #4 wire/core/Wire.php (484): WireHooks->runHooks(Object(DefaultPage), 'render', Array) #5 wire/modules/Process/ProcessPageView.module (193): Wire->__call('render', Array) #6 wire/modules/Process/ProcessPageView.module (114): ProcessPageView->renderPage(Object(DefaultPage), Object(PagesRequest)) #7 wire/core/Wire.php (416): ProcessPageView->___execute(true) #8 wire/core/WireHooks.php (968): Wire->_callMethod('___execute', Array) #9 wire/core/Wire.php (484): WireHooks->runHooks(Object(ProcessPageView), 'execute', Array) #10 index.php (55): Wire->__call('execute', Array) #11 {main} (I modified the line 584 in PageRender.module to output the whole path.) So looking at the path (site/templates-dev/site/templates/admin.php), it seems the system prepends the new path to the old path. Which is probably also the reason for the blank pages at the frontend. Is this a bug, or am I doing something wrong? Thanks! ProcessWire 3.0.246
  9. The Api docs have changed and I reference the Api docs a lot. It is possible to revert to the 3 column layout with the major Api vars/functions on the left and then when clicking on one, list its functions on the right? The new layout is 2-column. You search for the module/var you want, then it lists its functions underneath in the left column. Too bad if its not the right one. Finding another module/var is then a problem as the Search function isn't obvious. Yes it lists the possibilities, but then you have to hit return to get to the page. The other option is to click the parent in the breadcrumb list. I can live with it but it slows things down and not as user-friendly as the previous layout. @ryan A bit more on the API docs... They throw an Error 500 on a number of pages, eg https://processwire.com/api/ref/inputfield-form/render-or-process-ready/
  10. OK - code examples first, just because they caught my eye immediately: It's missing the closing ")" and I also think it would look cleaner on one line: <!-- Render simple breadcrumb nav --> <ul class="breadcrumbs"> <?= $page->parents->each( '<li><a href="{url}">{title}</a>' ?> </ul> ie: <!-- Render simple breadcrumb nav --> <ul class="breadcrumbs"> <?= $page->parents->each('<li><a href="{url}">{title}</a>') ?> </ul> This won't work because of $p->url in double quotes like that without extra single quotes for href. // Render primary navigation foreach($pages->get("/")->children as $p) { echo "<a href="$p->url">$p->title</a> "; } Missing the semi-colon at the end of the second line: // Find and list tall buildings $buildings = $pages->get("/buildings/"); $skyscrapers = $buildings->find("height>1000") echo $skyscrapers->each("<li>{height}: {title}");
  11. Hey @adrian, I came across a minor problem which prevents the Tracy console showing in the debug bar when bootstrapping PW in a standalone PHP script. The error shown is: ErrorException: foreach() argument must be of type array|object, null given in D:\laragon\www\[sitename]\site\assets\cache\FileCompiler\site\modules\TracyDebugger\panels\ConsolePanel.php:172 Stack trace: #0 D:\laragon\www\[sitename]\site\assets\cache\FileCompiler\site\modules\TracyDebugger\panels\ConsolePanel.php(172): Tracy\Bar->Tracy\{closure}(2, 'foreach() argum...', 'D:\\laragon\\www\\...', 172) #1 D:\laragon\www\[sitename]\site\assets\cache\FileCompiler\site\modules\TracyDebugger\tracy-2.10.x\src\Tracy\Bar\Bar.php(143): ConsolePanel->getPanel() #2 D:\laragon\www\[sitename]\site\assets\cache\FileCompiler\site\modules\TracyDebugger\tracy-2.10.x\src\Tracy\Bar\Bar.php(115): Tracy\Bar->renderPanels('') #3 D:\laragon\www\[sitename]\site\assets\cache\FileCompiler\site\modules\TracyDebugger\tracy-2.10.x\src\Tracy\Bar\Bar.php(89): Tracy\Bar->renderPartial('main') #4 D:\laragon\www\[sitename]\site\modules\TracyDebugger\tracy-2.10.x\src\Tracy\Debugger\DevelopmentStrategy.php(123): Tracy\Bar->render(Object(Tracy\DeferredContent)) #5 D:\laragon\www\[sitename]\site\assets\cache\FileCompiler\site\modules\TracyDebugger\tracy-2.10.x\src\Tracy\Debugger\Debugger.php(314): Tracy\DevelopmentStrategy->renderBar() #6 [internal function]: Tracy\Debugger::shutdownHandler() #7 {main} And this is what the debug bar looks like: I think it should be a simple fix - it looks like the line 172 is traversing $p->fields, but $p is a NullPage at this point. Kind regards, Ian.
  12. Here is what I'm currently doing: <?php class MyBlock extends Block { // ...rest of block /** * Determines if this block should render on the page * @return bool */ public function shouldRender(): bool { // For a field that displays featured activities. This is actually much more complex in real life // and keeping this in a shouldRender() method makes the template much cleaner return $this->featured_activities->where('date>=now&is_sold_out=false')->count(); // Sometimes blocks are saved in an incomplete state // Because ProcessWire doesn't have live field dependencies, an event has to be selected, page saved, // then activies in that event can be selected. This block shouldn't render until all of the information is complete. return !!$this->title && !!$this->event?->id && $this->featured_activities->count(); } // ...rest of block } View file: <?php namespace ProcessWire; /** @var Page $page */ /** @var MyBlock $block */ // This could be eliminated by making shouldRender() a method in Block.php if (!$block->shouldRender()) { return; } ?> <section class="rpb-myblock <?=$block->classes()?>" <?=alfred($block)?>> <!-- Block markup --> </section> If shouldRender() is defined in Block.php then it would be available everywhere. Otherwise to maintain consistency I have to do this in every block: <?php class AnotherBlock extends Block { // ...rest of block /** * This could be eliminated by making shouldRender() a method in Block.php */ public function shouldRender(): bool { return true; } // ...rest of block }
  13. @bernhard Forgot to mention that the first block of code is added to Block.php and is a method provided just for child blocks to override if they need. This way RPB will not render a block if that method returns false independently of the Inputfield UI for hide/unpublished state, which I think is what your for loop checks for. If I'm misunderstanding your for loop example then that could be my problem. A block can be published and unhidden, but the block can determine if it will render with its own logic.
  14. @bernhard My approach was very basic. <?php /** * Whether this block should be rendered. May be optionally implemented by blocks to control front-end visibility * @return bool */ public function shouldRender() { return true; } /** * Render this block * @return string */ public function renderBlock() { if (!$this->shouldRender()) { return ''; } // rest of method... } It works in practice as a function that does not modify RPB's existing behavior and the Inputfield UI takes precedence. Since this visibility is controlled by the blocks and not the user, the developer can work with this state. These may serve some edge cases, but it illustrates the philosophy of separating what is declared in the UI vs. in the block. <?php namespace ProcessWire; /** @var Page $page */ /** @var FeaturedActivities $block */ ?> <section class="rpb-foo <?=$block->classes()?>" <?=alfred($block)?>> <!-- You can create "grouped" behavior --> <?php if ($block->nextBlock()->type === 'Bar' && $block->nextBlock()->shouldRender()): ?> <p>Here's a little something extra</p> <?php endif ?> <!-- ...rest of block code --> <!-- Conditional design still possible --> <?php if ($block->isLastBlock() || !$block->nextBlock()->shouldRender()): ?> <span class="rounded-bottom-corners"></span> <?php endif ?> </section> The un-rendered will exist with an ID because the UI and RPB's core behavior dictates that the block exists and is available, but blocks maintain control of rendering separately.
  15. One of the things that I have to work around in a current site is lots of dynamic content. Content in blocks may change depending on values from other pages, dates/times, or updates from external sources such as APIs. Many of these are automated via hooks. My example is events and activities. Events can become active, tickets go on sale, be cancelled, end, etc. This is a block for "Featured Activities" Activities are selected by a person editing a page. They can choose as many activities as desired but only 3 are shown on the page If the date of an activity passes, or tickets are sold out, it is removed from the featured activities (automatically via hook) When one is removed another is rotated in (automatically via hook) If there are no more featured activities (all of the dates have past, or tickets are sold out) the block should no longer be output to the page. These are featured on many pages across the site with a lot of automation and updating them manually would be a very terrible thing 🤣 I have a handful of blocks that do stuff like this. The idea is a shouldRender() method for Block classes. By default it returns true but may be overridden to control whether a block will show up on the page. <?php /** * Whether this block should be rendered. Called before a block is output to the page. * @return bool */ public function shouldRender() { return true; } I have something like this cobbled together already in my code but I have to add an if statement to all of the block views that need this. I also use it for things like image galleries that shouldn't render if the image field is empty. It would be really nice native feature 😎
  16. For bypass the admin page i have added two lines if ($wire->config->debug) { $wire->addHookAfter('Page::render', function (HookEvent $event) { $page = $event->object; if($page->template->name == 'admin') return; (...) Thank you for the snippet
  17. Here is the solution. First, on the checkbox field (let's call it terms_privacy_checkbox) settings leave empty the "Checkbox label". On the field "Label" you can either write something for example "Terms - Privacy Policy" or leave empty (it will output field name) doesn't matter cause we gonna remove it with the following hook. $wire->addHookAfter('Page::render', function(HookEvent $event) { if($this->wire('page')->template->name != 'checkout') return; $event->return = str_replace("<span class='pw-no-select'>Terms - Privacy Policy</span>","", $event->return); }); Then with the following hook where we customize our form we can change the markup for the checkbox field too and split it to 2 divs using for example UIkit. $wire->addHookBefore('InputfieldWrapper::render', function($event) { if ($this->wire('page')->template->name != "checkout") return; $wrapper = $event->object; $terms = wire('pages')->get("template=terms"); $privacy = wire('pages')->get("template=privacy"); $defaultMarkup = array( // Check wire\core\InputfieldWrapper.php for the $defaultMarkup 'list' => "<ul {attrs}>{out}</ul>", 'item' => "<li {attrs}>{out}</li>", 'item_label' => "<label class='InputfieldHeader ui-widget-header{class}' for='{for}'>{out}</label>", 'item_label_hidden' => "<label class='InputfieldHeader InputfieldHeaderHidden ui-widget-header{class}'><span>{out}</span></label>", 'item_content' => "<div class='InputfieldContent ui-widget-content{class}'>{out}</div>", 'item_error' => "<p class='InputfieldError ui-state-error'><i class='fa fa-fw fa-flash'></i><span>{out}</span></p>", 'item_description' => "<p class='description'>{out}</p>", 'item_head' => "<h2>{out}</h2>", 'item_notes' => "<p class='notes'>{out}</p>", 'item_detail' => "<p class='detail'>{out}</p>", 'item_icon' => "<i class='fa fa-fw fa-{name}'></i> ", 'item_toggle' => "<i class='toggle-icon fa fa-fw fa-angle-down' data-to='fa-angle-down fa-angle-right'></i>", // ALSO: // InputfieldAnything => array(any of the properties above to override on a per-Inputfield basis) // Here we override the default markup for checkbox field by targeting it's name 'name=terms_privacy_checkbox' => [ 'item_label' => "", 'item_label_hidden' => "", 'item_content' => " <div class='uk-grid-collapse{class}' uk-grid> <div class='uk-width-auto'> {out} </div> <div class='uk-width-expand'> <label class='uk-form-label' for='Inputfield_terms_privacy_checkbox'> <span class='uk-text-normal'>I agree with the <a href='{$terms->url}' rel='noopener' target='_blank'>{$terms->title}</a> and the <a href='{$privacy->url}' rel='noopener' target='_blank'>{$privacy->title}</a>.</span> </label> </div> {error} </div>", ], ); $defaultClasses = array( // Check wire\core\InputfieldWrapper.php for the $defaultClasses 'form' => '', // additional clases for InputfieldForm (optional) 'list' => 'Inputfields', 'list_clearfix' => 'ui-helper-clearfix', 'item' => 'Inputfield {class} Inputfield_{name} ui-widget', 'item_label' => '', // additional classes for InputfieldHeader (optional) 'item_content' => '', // additional classes for InputfieldContent (optional) 'item_required' => 'InputfieldStateRequired', // class is for Inputfield 'item_error' => 'ui-state-error InputfieldStateError', // note: not the same as markup[item_error], class is for Inputfield 'item_collapsed' => 'InputfieldStateCollapsed', 'item_column_width' => 'InputfieldColumnWidth', 'item_column_width_first' => 'InputfieldColumnWidthFirst', 'item_show_if' => 'InputfieldStateShowIf', 'item_required_if' => 'InputfieldStateRequiredIf' // ALSO: // InputfieldAnything => array(any of the properties above to override on a per-Inputfield basis) ); $wrapper->setMarkup($defaultMarkup); $wrapper->setClasses($defaultClasses); foreach ($wrapper->children as $in) { switch ($in->name) { case 'email': $in->wrapAttr('class', 'uk-width-1-1'); $in->addClass('uk-input'); $in->attr('required', 'required'); break; case 'pad_paymentmodule': $in->wrapAttr('class', 'uk-width-1-1 uk-margin-small-top'); $in->addClass('uk-radio'); break; case 'terms_privacy_checkbox': $in->wrapAttr('class', 'uk-width-1-1'); $in->addClass('uk-checkbox'); $in->attr('required', 'required'); break; case 'customerForm': $in->wrapAttr('class', 'uk-width-1-1 uk-margin-medium-top'); $in->addClass('uk-button uk-button-primary uk-button-large'); break; default: $in->wrapAttr('class', 'uk-width-1-1'); $in->addClass('uk-width-1-1'); break; } } });
  18. Found this GooglePlaceDetails module today. Have no idea why it took so long! Installed and tested. Unfortunately when testing in the module config, I got an error saying I was using a deprecated legacy API - so Google! It's now Google Places (New). A bit of fiddling got it to work: Hide contents <?php namespace ProcessWire; /** * Gooogle Place Details Module * * This module can be used to display Google place details like reviews and other information in the frontend of a website. * * @author Stefan Thumann, 27.12.2022 * @license https://processwire.com/about/license/mit/ * * ProcessWire 2.x & 3.x, Copyright 2020 by Ryan Cramer * https://processwire.com * https://processwire.com/about/license/mit/ * **/ class GooglePlaceDetails extends WireData implements Module, ConfigurableModule { public static function getModuleInfo() { return [ 'title' => 'Google Place Details', 'summary' => 'Display Google place details like reviews and other information.', 'author' => 'Stefan Thumann', 'version' => '1.0.0', 'icon' => 'google' ]; } static protected $defaults = array( 'apiKey' => '', 'placeId' => '', 'dataFields' => 'name,reviews', 'reviewSort' => 'most_relevant', 'previewDetails' => '', 'detailsData' => '' ); public function __construct() { // populate defaults, which will get replaced with actual // configured values before the init/ready methods are called $this->setArray(self::$defaults); } public function getModuleConfigInputfields(array $data) { $inputfields = new InputfieldWrapper(); $data = array_merge(self::$defaults, $data); $f = wire('modules')->get('InputfieldMarkup'); $f->attr('name', 'infoData'); $f->label = 'Before you begin'; $f->icon = 'info'; $f->attr('value', 'Before you start using the Google Maps API you need an API key and a project with a billing account.'); $f->notes = 'Use Googles quick start widget here: [https://developers.google.com/maps/third-party-platforms/quick-start-widget-users](https://developers.google.com/maps/third-party-platforms/quick-start-widget-users)'; $inputfields->add($f); // API Key Inputfield $f = wire('modules')->get('InputfieldText'); $f->attr('name', 'apiKey'); $f->label = 'API Key'; $f->attr('value', $data['apiKey']); $f->columnWidth = 50; $f->notes = 'The API key is a unique identifier that authenticates requests associated with your project for usage and billing purposes: [https://developers.google.com/maps/documentation/javascript/get-api-key](https://developers.google.com/maps/documentation/javascript/get-api-key)'; $f->required = true; $inputfields->add($f); // Place ID Inputfield $f = wire('modules')->get('InputfieldText'); $f->attr('name', 'placeId'); $f->label = 'Place ID'; $f->attr('value', $data['placeId']); $f->columnWidth = 50; $f->notes = 'Use the place ID finder to search for a place and get its ID: [https://developers.google.com/maps/documentation/places/web-service/place-id](https://developers.google.com/maps/documentation/places/web-service/place-id)'; $f->required = true; $inputfields->add($f); // Fields Parameter Inputfield $f = wire('modules')->get('InputfieldText'); $f->attr('name', 'dataFields'); $f->label = 'Fields to include in request'; $f->attr('value', $data['dataFields']); $f->description = 'Specify a comma-separated list of place data types to return. Leave empty to load all default fields.'; $f->notes = 'For an overview of the available fields see: [https://developers.google.com/maps/documentation/places/web-service/details](https://developers.google.com/maps/documentation/places/web-service/details)'; $inputfields->add($f); // Sorting Options $f = wire('modules')->get('InputfieldSelect'); $f->attr('name', 'reviewSort'); $f->label = 'Review Sorting'; $f->icon = 'filter'; $f->options = array( 'most_relevant' => 'Most relevant', 'newest' => 'newest' ); $f->attr('value', $data['reviewSort']); $f->notes = 'Info: The amount of reviews is limited to 5 by the API.'; $inputfields->add($f); // Fetch Place Details Checkbox $f = wire('modules')->get('InputfieldCheckbox'); $f->attr('name', 'previewDetails'); $f->label = 'Preview Place Details'; $f->description = 'If checked the place details can be previewed for debugging/development purpose after submit. This preview data will not be saved and is lost after leaving this page.'; $f->attr('value', 1); $f->icon = 'heartbeat'; $inputfields->add($f); if($this->session->previewDetails) { $this->fetchData('liveData'); } // Markup Field for Preview Data Array $f = wire('modules')->get('InputfieldMarkup'); $f->attr('name', 'previewData'); $f->label = 'Preview Data'; $f->icon = 'filter'; $f->notes = 'Note that is is not allowed to store Google Maps content outside their services. [https://cloud.google.com/maps-platform/terms](https://cloud.google.com/maps-platform/terms) '; if($this->session->previewDetails) { $f->attr('value', $this->previewData()); } $inputfields->add($f); if(wire('input')->post->previewDetails) { // if checkbox was checked, set session data $session = wire('session'); $session->set('previewDetails', 1); } return $inputfields; } /** * This function previews the revieved data in a markup field on the module page */ private function previewData() { // remove session data $session = wire('session'); $session->remove('previewDetails'); $detailsData = $this->detailsData; if (!empty($detailsData)) { // When there is data, show it // hier config $outputTemplate = "<pre style=\"overflow:scroll !important; margin:15px auto; padding:10px; background-color:#ffffdd; color:#555; border:1px solid #AAA; font-family:'Hack', 'Source Code Pro', 'Lucida Console', 'Courier', monospace; font-size:12px; line-height:15px;\">".print_r(json_decode($detailsData,true), true)."</pre>"; } else { $outputTemplate = "<pre style=\"overflow:scroll !important; margin:15px auto; padding:10px; background-color:#ffffdd; color:#555; border:1px solid #AAA; font-family:'Hack', 'Source Code Pro', 'Lucida Console', 'Courier', monospace; font-size:12px; line-height:15px;\">No data received yet.</pre>"; } return $outputTemplate; } /** * This function recieves the place data over the google api via a http request and saves it for later use * @return array|string */ private function fetchData() { // Get Values $apiKey = $this->apiKey; $placeId = $this->placeId; $dataFields = $this->dataFields; $reviewSort = $this->reviewSort; // $apiUrl = "https://maps.googleapis.com/maps/api/place/details/json?fields=$dataFields&reviews_sort=$reviewSort&reviews_no_translations=true&place_id=$placeId&key=$apiKey"; $apiUrl = "https://places.googleapis.com/v1/places/$placeId?fields=$dataFields&key=$apiKey"; $http = new WireHttp(); $responseJson = $http->get($apiUrl); if($responseJson !== false) { // Description: // The Response is in JSON Format. // To return just the result data, we have to decode the JSON into a php array, select the result object and return it // Turn JSON into php array $responseArray = json_decode($responseJson, true); // For preview purpose get only the result data and encode it back to JSON $this->detailsData = $responseJson; // return response array to frontend return $responseArray; } else { echo "HTTP request failed: " . $http->getError(); } } /** * This function recieves the place data over the google api via a http request and returns it in real time * @return array */ public function getPlaceDetails() { return ($this->fetchData()); } public function getUIKitMarkupExample() { $responseArray = $this->fetchData(); // return only the result array to the frontend and include it in a sample markup $result = $this->wire('files')->render('../modules/GooglePlaceDetails/reviews-markup',['details' => $responseArray]); return $result; } } Please note that the review results are automatically sorted by "relevant" and a maximum of 5 reviews on the 'free' (low usage) plan. The available data has also changed. See https://developers.google.com/maps/documentation/places/web-service/data-fields for the available field info. The examples in the help text will no longer work. It's simply a matter of mapping the new fields to your template. Would love to see an official upgrade of this module and hope the above helps. PS: Hardest part was navigating Google to get the API key!
  19. Using ::render would probably be too late? Try ::renderReady
  20. I would like to order the display of a repeater in the backend on the basis of a field in it; my repeater is called dates_events and contains a title field and a date_event field. How can I display the values in admin by sorting by dates_events? I have tried with a hook but this does not work the date_event is a date/time field $wire->addHookAfter('InputfieldRepeater::render', function(HookEvent $event) { $inputfield = $event->object; if ($inputfield->name === 'date_events') { $inputfield->value = $inputfield->value->sort('data_event'); } }); Thank you in advance
  21. I haven't tried (and so could easily be wrong!), but I think the following would work: foreach ($pages->find("template=template_name") as $page) { ob_start(); $page->render(); ob_end_clean(); } The output buffering is to stop the pages rendering in the browser. It'd probably be easiest to put the code in a template file.
  22. Just tried to upgrade my very old Padloper installation. I get this error when the `ProcessWireCommerce` folder i in the `modules` folder and I hit Modules > Refresh. Warning: require(ProcessWire/PaymentPaypal.php): Failed to open stream: No such file or directory in /yadayada/site/modules/ProcessWireCommerce/vendor/autoload.php on line 49 Well well… Fatal Error: Uncaught Error: Failed opening required 'ProcessWire/PaymentPaypal.php' (include_path='.:/Applications/MAMP/bin/php/php8.3.14/lib/php') in site/modules/ProcessWireCommerce/vendor/autoload.php:49 #0 [internal function]: ProcessWireCommerce\autoload_paypal_stripe('\Pay...') #1 wire/core/ModulesFiles.php (271): ReflectionClass->__construct('\\\Pa...') #2 wire/core/Modules.php (2276): ModulesFiles->getModuleFile('PaymentPaypal', Array) #3 wire/core/ModulesInfo.php (1128): Modules->getModuleFile('PaymentPaypal', Array) #4 wire/core/Modules.php (1953): ModulesInfo->clearModuleInfoCache(true) #5 wire/core/Wire.php (416): Modules->___refresh(true) #6 wire/core/WireHooks.php (998): Wire->_callMethod('___refresh', Array) #7 wire/core/Wire.php (484): WireHooks->runHooks(Object(Modules), 'refresh', Array) #8 wire/modules/Process/ProcessModule/ProcessModule.module (389): Wire->__call('refresh', Array) #9 wire/core/Wire.php (413): ProcessModule->___execute() #10 wire/core/WireHooks.php (998): Wire->_callMethod('___execute', Array) #11 wire/core/Wire.php (484): WireHooks->runHooks(Object(ProcessModule), 'execute', Array) #12 wire/core/ProcessController.php (361): Wire->__call('execute', Array) #13 wire/core/Wire.php (413): ProcessController->___execute() #14 wire/core/WireHooks.php (998): Wire->_callMethod('___execute', Array) #15 wire/core/Wire.php (484): WireHooks->runHooks(Object(ProcessController), 'execute', Array) #16 wire/core/admin.php (174): Wire->__call('execute', Array) #17 wire/modules/AdminTheme/AdminThemeUikit/controller.php (15): require('/Users/claus/Gi...') #18 site/templates/admin.php (15): require('/Users/claus/Gi...') #19 wire/core/TemplateFile.php (328): require('/Users/claus/Gi...') #20 wire/core/Wire.php (413): TemplateFile->___render() #21 wire/core/WireHooks.php (998): Wire->_callMethod('___render', Array) #22 wire/core/Wire.php (484): WireHooks->runHooks(Object(TemplateFile), 'render', Array) #23 wire/modules/PageRender.module (581): Wire->__call('render', Array) #24 wire/core/Wire.php (416): PageRender->___renderPage(Object(HookEvent)) #25 wire/core/WireHooks.php (998): Wire->_callMethod('___renderPage', Array) #26 wire/core/Wire.php (484): WireHooks->runHooks(Object(PageRender), 'renderPage', Array) #27 wire/core/WireHooks.php (1099): Wire->__call('renderPage', Array) #28 wire/core/Wire.php (484): WireHooks->runHooks(Object(Page), 'render', Array) #29 wire/modules/Process/ProcessPageView.module (193): Wire->__call('render', Array) #30 wire/modules/Process/ProcessPageView.module (114): ProcessPageView->renderPage(Object(Page), Object(PagesRequest)) #31 wire/core/Wire.php (416): ProcessPageView->___execute(true) #32 wire/core/WireHooks.php (998): Wire->_callMethod('___execute', Array) #33 wire/core/Wire.php (484): WireHooks->runHooks(Object(ProcessPageView), 'execute', Array) #34 index.php (55): Wire->__call('execute', Array) #35 {main} thrown (line 49 of site/modules/ProcessWireCommerce/vendor/autoload.php) This error message was shown because: you are logged in as a Superuser. Error has been logged.
  23. Actually this looks like Markdown to HTML. I want the inverse! I.e. $markdownFile = $someTool->convertHTMLToMD($page->render()); Edit https://github.com/thephpleague/html-to-markdown
  24. Hi @bernhard, is it possible to enable livereload only for frontend, like it used to be in RockFrontend? I think there was a switch in the GUI to enable it for backend. Now we only have the $config->rockdevtools = true; setting. Do we need to hook somewhere (maybe Page::render) to set it to false if template == admin, or something like this? Where to place the hook? I see in bot RockDevTools class and LiveReload class the check for the config value is in the constructor. So we would have to hook before the RockDevTools module is loaded, right? Or is there an easy solution, that I overlooked? The docs don't mention anything. Having reload in the backend can sometimes be annoying, e.g. when working on migrations and saving a file with unfinished migration or copying an existing migration file for reuse etc. Some control here would be much appreciated.
  25. I have added a hook recorder and this is what I got when logging in with a non-existing email address: ProcessWire\ProcessLogin::execute ProcessWire\ProcessLogin::buildLoginForm ProcessWire\ProcessLogin::loginFormProcessReady ProcessWire\ProcessLogin::loginFailed ProcessWire\ProcessLogin::loginFormProcessed ProcessWire\ProcessLogin::renderLoginForm ProcessWire\ProcessLogin::headline ProcessWire\ProcessLogin::getLoginLinks ProcessWire\ProcessLogin::executed So to me it looks like loginFormProcessReady should work. This is the whole hook recorder log, which looks like InputfieldForm::processInput should also be an option? ProcessWire\Fields::load ProcessWire\Fieldgroups::load ProcessWire\Templates::load ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Session::init ProcessWire\ProcessWire::init ProcessWire\Pages::find ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\FieldgroupsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\FieldgroupsArray::changed ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\ProcessPageView::execute ProcessWire\PagesRequest::getPage ProcessWire\PagesRequest::getPageForUser ProcessWire\DefaultPage::viewable ProcessWire\PagesRequest::getLoginPageOrUrl ProcessWire\Pages::find ProcessWire\ProcessPageView::ready ProcessWire\ProcessWire::ready ProcessWire\Config::InputfieldWrapper ProcessWire\Config::callUnknown ProcessWire\JqueryUI::use ProcessWire\PageFrontEdit::getPage ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\FieldgroupsArray::changed ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\TemplatesArray::changed ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\Pages::find ProcessWire\Pages::find ProcessWire\Pages::find ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\TemplateFile::render ProcessWire\DefaultPage::render ProcessWire\PageRender::renderPage ProcessWire\TemplateFile::render ProcessWire\ProcessController::execute ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\ProcessLogin::execute ProcessWire\ProcessLogin::buildLoginForm ProcessWire\ProcessLogin::loginFormProcessReady ProcessWire\InputfieldForm::processInput ProcessWire\InputfieldText::processInput ProcessWire\InputfieldText::processInput ProcessWire\InputfieldSubmit::processInput ProcessWire\InputfieldHidden::processInput ProcessWire\InputfieldHidden::processInput ProcessWire\InputfieldHidden::processInput ProcessWire\InputfieldHidden::processInput ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\ProcessLogin::loginFailed ProcessWire\ProcessLogin::loginFormProcessed ProcessWire\ProcessLogin::renderLoginForm ProcessWire\ProcessLogin::headline ProcessWire\InputfieldForm::render ProcessWire\InputfieldForm::renderInputfield ProcessWire\InputfieldText::render ProcessWire\InputfieldForm::renderInputfield ProcessWire\InputfieldText::render ProcessWire\InputfieldForm::renderInputfield ProcessWire\InputfieldSubmit::render ProcessWire\InputfieldForm::renderInputfield ProcessWire\InputfieldHidden::render ProcessWire\InputfieldForm::renderInputfield ProcessWire\InputfieldHidden::render ProcessWire\InputfieldForm::renderInputfield ProcessWire\InputfieldHidden::render ProcessWire\InputfieldForm::renderInputfield ProcessWire\InputfieldHidden::render ProcessWire\ProcessLogin::getLoginLinks ProcessWire\Pages::find ProcessWire\ProcessLogin::executed ProcessWire\AdminThemeUikit::getExtraMarkup ProcessWire\AdminThemeUikit::getExtraMarkup ProcessWire\AdminThemeUikit::getUikitCSS ProcessWire\AdminThemeUikit::getExtraMarkup ProcessWire\AdminThemeUikit::getExtraMarkup ProcessWire\AdminThemeUikit::getExtraMarkup ProcessWire\AdminThemeUikit::renderBreadcrumbs ProcessWire\AdminThemeUikit::getExtraMarkup ProcessWire\AdminThemeUikit::getExtraMarkup ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\Pages::find ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\ProcessPageView::finished ProcessWire\ProcessWire::finished ProcessWire\DefaultPage::viewable ProcessWire\DefaultPage::rootParent ProcessWire\DefaultPage::viewable ProcessWire\DefaultPage::rootParent ProcessWire\DefaultPage::rootParent ProcessWire\DefaultPage::rootParent ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\DefaultPage::viewable ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\DefaultPage::viewable ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\FieldsArray::changed ProcessWire\DefaultPage::viewable ProcessWire\DefaultPage::editable ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\DefaultPage::addable ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::publishable ProcessWire\DefaultPage::editable ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::listable ProcessWire\DefaultPage::moveable ProcessWire\DefaultPage::editable ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::sortable ProcessWire\DefaultPage::editable ProcessWire\UserPage::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::deleteable ProcessWire\DefaultPage::trashable ProcessWire\DefaultPage::restorable ProcessWire\DefaultPage::rootParent ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\PageArray::changed ProcessWire\DefaultPage::viewable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::editable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::addable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::publishable ProcessWire\DefaultPage::editable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::listable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::moveable ProcessWire\DefaultPage::editable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::sortable ProcessWire\DefaultPage::editable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\DefaultPage::deleteable ProcessWire\DefaultPage::trashable ProcessWire\DefaultPage::restorable ProcessWire\DefaultPage::rootParent ProcessWire\PageArray::changed ProcessWire\PageArray::changed ProcessWire\DefaultPage::viewable ProcessWire\DefaultPage::editable ProcessWire\DefaultPage::addable ProcessWire\DefaultPage::publishable ProcessWire\DefaultPage::listable ProcessWire\DefaultPage::moveable ProcessWire\DefaultPage::editable ProcessWire\User::hasPagePermission ProcessWire\Pages::find ProcessWire\PageFinder::find ProcessWire\PageFinder::getQuery ProcessWire\DefaultPage::sortable ProcessWire\DefaultPage::editable ProcessWire\User::hasPagePermission ProcessWire\DefaultPage::deleteable ProcessWire\DefaultPage::trashable ProcessWire\DefaultPage::restorable ProcessWire\DefaultPage::rootParent ProcessWire\WireCache::log ProcessWire\WireCache::log ProcessWire\WireDateTime::relativeTimeStr ProcessWire\WireDateTime::relativeTimeStr ProcessWire\WireDateTime::relativeTimeStr ProcessWire\WireDateTime::relativeTimeStr ProcessWire\Session::changed ProcessWire\Session::changed ProcessWire\WireCache::log ProcessWire\WireCache::log ProcessWire\Fields::load ProcessWire\Fieldgroups::load ProcessWire\Templates::load ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Fieldgroup::setQuietly ProcessWire\Fieldgroup::callUnknown ProcessWire\Session::init
×
×
  • Create New...