-
Posts
1,336 -
Joined
-
Last visited
-
Days Won
62
Everything posted by BitPoet
-
Module Configuration not working for Inputfield modules?
BitPoet replied to gebeer's topic in Module/Plugin Development
Happy New Year too! getConfigInputfields is not the same as module configuration, it's a mechanism of the Inputfield class.- 2 replies
-
- module
- configuration
-
(and 1 more)
Tagged with:
-
The waves div is fine for me. The images themselves do work as links, but my first instinct was to click the buttons below.
-
Hi Sanne, nicely done. At first glance, I spotted two small issues: the carousel arrows unfortunately don't work, and the "LEES MEER" buttons on the portfolio page aren't functional (I'm using Firefox here). That said, I like the soft slide-into-place effect on navigating between pages, and the styling is pleasing and harmonic.
-
I can only concur that this has been a great year. It was nearly impossible not to get infected by the momentum of PW's development. Love (that's an understatement) the JS $pages API plan, and the pages export/import function could even be a solid base for native staging support, just by hooking into the proper PW actions and filling a staging actions table. You're absolutely right, @apeisa, PW is much more than just a brilliant website platform. Our intranet site really does some "heavy lifting", consolidating information from the ERP system, the DMS, personnel and operational time keeping, financial accounting and a few proprietary databases. That way, it also serves as the middleware for a big, distributed test run database. Like Sense, it drives a few chained workflows, e.g. for bridging the feedback gap between dunning proposals and our sales managers. All our intra-company course scheduling/booking runs on PW too, including supervisor approval, and it was surprisingly easy to implement. HR was over the moon with PW's ease of use. For 2017, we're planning a site that provides our customers with all the publicly available documentation for the machines and plant parts we sold them, requiring just a QR code scan on their side. Setting up a working (UIKit styled, multilingual) prototype only took me a few hours and really impressed our sales guys If 2017 is going to be anything like this year, it's going to be a blast. Thank you @ryan! A happy, healthy and inventive new year to everyone!
- 12 replies
-
- 15
-
-
Actually, it's quite obvious once you know where to look. When you have entries where both mother and father are empty, you try to set two entries with identical titles of "No Parent Defined" in $data, and since this is a plain array, PHP will only use the last assignment for that array key. So you'll have to make sure in some way that your titles differ for the "SIRE" and "DAM" fields (e.g. "No Sire Defined" vs. "No Dam defined").
-
You need to pass the page id of the event in question (probably as a GET parameter or URL segment) when you open the ICS page, then in your ICS template retrieve the corresponding page (remember to use sanitizer or (int) casting to make sure you're really getting a valid page id) and fill in the page's field values.
-
While this is a reasonable way of structuring things, it's not a case I'll cover with the module. But that's why I made getPageMediaLibraries hookable. You don't need to modify the original module code, just add a hook in site/ready.php and change the return value there. wire()->addHookAfter("MediaLibrary::getPageMediaLibraries", null, "myCustomGetLibraries"); function myCustomGetLibraries(HookEvent $event) { $event->return = wire('pages')->find("template=MediaLibrary"); }
-
How to not allow user to add child from the parent page?
BitPoet replied to adrianmak's topic in General Support
Yes. A simple way would be hooking into ProcessPageListActions::getActions in your site/ready.php: wire()->addHookAfter("ProcessPageListActions::getActions", null, "removeNewAction"); function removeNewAction(HookEvent $event) { $page = $event->arguments(0); if($page->template == "blog") { $actions = $event->return; unset($actions['new']); $event->return = $actions; } } -
Warning: array_values() expects parameter 1 to be array, object given
BitPoet replied to Fran's topic in API & Templates
What $page->get returns depends on the field type, but you'll hardly ever get back a plain array. Btw., $page->get("planos") is the same as $page->planos. For image and file fields, the return value (unless null/empty or set to "Single item") is a PageImages object, which, while it inherits from WireArray and thus implements an iterator so you can run a foreach loop over it, isn't the same as a plain array. If you do need a plain array for some reason (in most cases you won't), you can call getArray() or getValues() on classes inheriting from WireArray.- 1 reply
-
- 5
-
-
- array
- array_values
-
(and 2 more)
Tagged with:
-
I see, that's of course different, and - since there's no direct relationship between two image fields - doable but dangerous in case one of the images is missing, and keeping then in sync isn't easy once the list gets long. $precioschico = $page->get("planos"); $preciosgrande = $page->get("mapas"); for($i = 0; $i < $precioschico->count(); $i++) { $chicoimg = $precioschico->eq($i); $grandeimg = $preciosgrande->eq($i); echo " <div class='col-md-6 col-lg-4'> <a href='{$grandeimg->url}' class='thumbnail' rel='prettyPhoto[galeriaplanos2]'> <img class='img-responsive' src='{$chicoimg->url}' /> </a> </div> "; } To make the code a little simpler and avoid errors by images not matching up, you might consider creating a repeater field with two image fields (one named "grande" and one "chico", each set to "Single item"). Then you could run a simple loop over your repeater field. foreach($page->repeaterimages as $img) { echo " <div class='col-md-6 col-lg-4'> <a href='{$img->grande->url}' class='thumbnail' rel='prettyPhoto[galeriaplanos2]'> <img class='img-responsive' src='{$img->chico->url}' /> </a> </div> "; } If you set the column width for both image fields to 50%, you can show and edit them side by side in the repeater list on the page. The page editor would look like this:
-
Another approach using WireArray::and() which implicitly creates a copy of the Wire(or Page)Array: $precioschico = $page->get("planos"); $preciosgrande = $page->get("mapas"); $precios = $precioschico->and($preciosgrande); // Or all in one step: $precios = $page->get("planos")->and($page->get("mapas")); foreach( $precios as $precio ) { echo $precio . '<br/>'; }
-
Merry Christmas from me to you and your family too Ryan, and to everybody else in the fabulous PW community. The updates over this year were really brilliant and I find myself using a lot of them already. The ProDrafts workflow feature is just the thing I was looking for and it's coming at the perfect time.
-
I've seen that too, hand in hand with a near doubling of new sessions in GA with arbitrary pages/view rate for last month, so this really messes up the stats. I've found some reports saying that these entries all come from Accept-Language headers (not Measurement Protocol) so it should be possible to block these requests at server level with a regex on Accept-Language that throws away anything that doesn't match the required format given in rfc7231. I'm going to take a look after Christmas hols if Akamai lets me add that such a filter in DSA. It should be relatively easy to do in Apache and NGINX, something like RewriteCond %{HTTP:Accept-Language} !^$|\*$|([a-z]{2,3}(-[a-z]{2,3})?)(\s*,\s*[a-z]{2,3}(-[a-z]{2,3})?)*($|;) [NC] RewriteRule ^.*$ "-" [F] The regex isn't a complete validity check and untested yet, but it should get the job done. Might even work for a GA filter too.
-
Depending on whether the last row needs to have a complete set of elements (not sure if bootstrap's css requires that), you could also use PHP's builtin array_chunk function to make the logic clearer. $out = ""; foreach(array_chunk($page->children->getArray(), 3) as $row) { $out .= "<div class='col-xs-4'>"; foreach($row as $p) { $out .= "<img src='{$p->images->first->url}' class='img-responsive'>"; $out .= $p->title; } $out .= "</div>"; }
-
change custom admin page topnav button on/active state
BitPoet replied to Marc's topic in API & Templates
The only way I could see this working would be by adding a custom piece of javascript (using AdminCustomFiles) that adds the CSS class "on" for your entry, as PW's built-in logic tries to match the id of /admin/appearance/ in the link against the id of the current page (that of /settings-appearance/). You'd have to check the URL for your settings page in that custom code, something like (untested): $(document).ready(function() { // Page id of /admin/settings/ var pageid = 28; var regex = new RegExp("^http://[^/]+/admin/appearance/"); if(regex.text(window.location.href)) { $("#topnav-page-" + pageid).addClass("on"); } }); If you have PW in a subdirectory, you'll have to insert the path in the RegExp pattern and adapt it if you move your installation. In the long run, using AdminCustomPages might be a better approach. Create your settings-appearance page just as before, and create a /admin/appearance/ page with a custom admin template that displays the current settings and outputs an edit link for settings-appearance with the CSS class pw-modal. Also output a short JS snippet that listens for the pw-modal-closed event on that link and calls window.location.reload when triggered, to make sure you're not displaying stale settings. This way, the navbar highlighting will work without hassles. -
urls Access to the website with Processwire in a subfolder
BitPoet replied to Elías Gómez's topic in General Support
There are possibilities to prevent that, e.g. by excluding all physically existing files and directories using a rewrite condition: RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /pw/$1 You could also add specific subdirectories from being redirected, for example if you want to have another PW installation in a sub directory named "pw3", you'd add a condition before the rule: RewriteCond %{REQUEST_URI} !^/pw3/ -
This discussion might be worth a look:
-
You could use my FieldtypeDropdownDynamic in conjunction with a snippet of code that iterates the gcb directory for php files like the following (untested): return array_map( function($file) { return array("label" => $file, "name" => $file); }, array_filter( scandir($config->paths->templates . "gcb"), function($found) { return substr($found, -4) == ".php"; } ) );
-
WireArray's unique method is not what you're looking for, it removes duplicate entries from a WireArray like your images field, and the image list is already unique. But you could shorten the filling of your tags array (the internal steps are basically the same as what your code does): $tagsarray = array_unique($page->images->explode("tag"));
-
Wishlist: Add a "Siblings" tab to edit mode
BitPoet replied to creativejay's topic in Wishlist & Roadmap
<?php /** * Add "Siblings" tab to page editor. * */ class PageEditSiblings extends WireData implements Module { public static function getModuleInfo() { return array( "title" => "Page Edit Siblings", "summary" => _("Add siblings tab to page edtior"), "version" => "0.0.1", "autoload" => true ); } public function init() { $this->addHookAfter("ProcessPageEdit::buildForm", $this, "addSiblingsTab"); } public function addSiblingsTab(HookEvent $event) { $edit = $event->object; $form = $event->return; $master = $edit->getMasterPage(); $page = $master ? $master : $edit->getPage(); $wrap = $this->buildFormSiblings($edit, $form, $master, $page); $form->insertAfter($wrap, $form->get("ProcessPageEditChildren")); } public function ___buildFormSiblings($edit, $form, $master, $page) { $wrapper = $this->wire(new InputfieldWrapper()); $id = $this->className(); $wrapper->attr('id+name', $id); if(!empty($settings['ajaxChildren'])) $wrapper->collapsed = Inputfield::collapsedYesAjax; $defaultTitle = $this->_('Siblings'); // Tab Label: Siblings $title = $this->page->template->getTabLabel('siblings'); if(!$title) $title = $defaultTitle; if($page->parent->numChildren > 1) $wrapper->attr('title', "<em>$title</em>"); else $wrapper->attr('title', $title); $this->addTab($edit, $id, $title); if(!$edit->isPost) { $pageListParent = $page->parent; /** @var InputfieldMarkup $field */ $field = $this->modules->get("InputfieldMarkup"); $field->label = $title == $defaultTitle ? $this->_("Sibling Pages") : $title; // Siblings field label if($pageListParent->numChildren > 1) { $field->value = $this->renderPages($pageListParent->children(), $page); } else { $field->description = $this->_("There are currently no siblings of this page."); } if($page->addable()) { /** @var InputfieldButton $button */ $button = $this->modules->get("InputfieldButton"); $button->attr('id+name', 'AddPageBtn'); $button->attr('value', $this->_('Add New Page Under Parent')); // Button: add new child page $button->icon = 'plus-circle'; $button->attr('href', "../add/?parent_id={$page->parent->id}" . ($this->input->get('modal') ? "&modal=1" : '')); $field->append($button); } $wrapper->append($field); } return $wrapper; } public function ___renderPages($list, $cur) { $out = '<div class="PageList" style="display: block;">' . "\n"; foreach($list as $p) { $out .= ($p == $cur) ? "<div class='PageListItem'>{$p->title}</div>\n" : "<div class='PageListItem'><a href='{$this->page->url}?id={$p->id}' title='{$p->name}' class='PageListPage label'>{$p->title}</a></div>\n" ; } $out .= "</div>"; return $out; } protected function addTab($edit, $siblingid, $siblingtitle) { $tabs = $edit->getTabs(); $removed = array(); foreach(array_reverse($tabs) as $id => $title) { if($id == "ProcessPageEditChildren") { break; } $removed[$id] = $title; $edit->removeTab($id); } $edit->addTab($siblingid, $siblingtitle); foreach(array_reverse($removed) as $id => $title) { $edit->addTab($id, $title); } } } Only tested on PW 3.0.34 but should (I hope) work on any 2.7.x / 2.8.x / 3.0.x install. Large parts stolen from ProcessPageEdit::___buildFormChildren. -
Change Language Inherit for empty multi-lang fields
BitPoet replied to Orkun's topic in Multi-Language Support
Definitely an issue with the loop (a typo, to be precise). This: foreach(array($usrpache, $sprache, $dsprache) as $lang) { should contain $usprache instead of $usrpache. -
It might be that MySQL and PHP differ in the opinion what localhost should resolve to. If MySQL treats localhost as ::1 (ipv6) and PHP thinks of localhost as 127.0.0.1, that would explain this behavior. Though it's also possible that the user is defined as user@% instead of user@localhost and ipv6 loopback access is treated like a remote access. It's hard to say without taking a peek into the system.
-
@LostKobrakai's question is a good one. You shouldn't run any logic inside getModuleInfo() since it is executed by the module cache update routine long before the system is ready and things like permissions, roles, users and session have been wire()d. I guess one cou could say it used to work accidentally. I don't think there's a way around moving your logic into __construct(), init() or ready() in recent PW versions.
-
Shouldn't that read 'piece' instead of 'child', since you're using $piece in piece.php?
-
Here's an announcement for the magazine in their news ticker.
- 1 reply
-
- 2
-