Jump to content

hellomoto

Members
  • Posts

    364
  • Joined

Everything posted by hellomoto

  1. I have a page field on my home template with output set to multiple pages (PageArray). I can echo its value, 1111|2222, or foreach $nav as $p echo $p, 11112222. But when I do this that I need to, it doesn't work: foreach ($mainnav as $p) { if($page->rootParent->id == $p->id) $current = 'style="background: #fff;"'; else $current = ''; echo "<a href='{$pages->get($p)->url}' $current class='{$pages->get($p)->name}'>" . strToUpper($pages->get($p)->name) . "</a>"; } I get: I've tried the conditional in the code with one and three = signs.
  2. According to Pingdom on shared hosting this costs 7 seconds on an initial page load...
  3. I'll just call you Sir Fan. The MR acronym has too many options to choose from. I hear only great things about Costa Rica though, for sure. Anyway I had added magnific popup to edit them from the calendar already; but my calendar view isn't supposed to replace the page list view or whatever you have, just supplement it, with more than one type of event and varying start/end date assignments (like a listing template could be included in two group instances: one with the start date = created and no end date, to mark its creation, and another with the date_sold instead; and the event template only need be instantiated once and can use date_start and date_end for a range). I got the basic functionality going, now trying to make it into its own module and take it a bit further... keyword "trying"...
  4. I made a calendar view page in the admin using AdminCustomPages module, but since I want to add more functionality to it I am trying to make it (the calendar) its own module... So I have a module ProcessKalendar that extends Process and implements Module, ConfigurableModule. It creates the Kalendar page on installation and currently just outputs the input of the one config field for the module on that page on execution. I need to add scripts and stylesheets... How do I do this within the module?
  5. Okay now what if I want to access this info? Like display on a page, the most "viewed" pages, in a certain datetime range? (or "edited", let's say; viewed in my case.) Also how often are these flushed out? I see the cleanup function in ProcessChangelogHooks, says at an interval of $this->data_max_age. Where does that come from/is it set?
  6. This is great; I was building a viewtracker made up of PW pages but needed a better solution, so I was able to just add it in to this, thanks to adrian who brought it to my attention. Anyone know how I can add page segments to the URL though for the views? Here's my altered logPageEvent() in ProcessChangelogHooks.module (just search 'viewed' or 'render' in the code to find my additions): Never mind $page->input->urlSegment(1) had to be $event->input->urlSegment(1). public function logPageEvent(HookEvent $event) { // render has no arguments if ($event->method == "render") $page = $event->object; else $page = $event->arguments[0]; // don't log operations for repeaters or admin pages if ($page instanceof RepeaterPage || $page->template == "admin") return; // grab operation from event $operation = $event->method; if ($operation == "saveReady") $operation = "edited"; if ($operation == "render") { if ($page->template->name !== "vessel") return; $operation = "viewed"; } // only continue if this operation is set to be logged if (!in_array($operation, $this->operations)) return; $fields_edited = array(); if ($operation == "edited") { // skip new pages or pages being restored/trashed if (!$page->id || $page->parentPrevious) return; if ($page->isChanged()) { foreach ($page->template->fields as $field) { if ($page->isChanged($field->name)) { $fields_edited[] = $field->name; } } // only continue if at least one field has been changed (or // if status has changed trigger new event for that) if (!count($fields_edited)) { if ($page->isChanged("status")) { $event->method = $page->is(Page::statusUnpublished) ? "unpublished" : "published"; $this->logPageEvent($event); } return; } } else return; } else if ($operation == "renamed") { // if previous parent is trash, page is being restored if ($page->parentPrevious->id == $this->config->trashPageID) return; // if current parent is trash, page is being trashed else if ($page->parent->id == $this->config->trashPageID) return; } else if ($operation == "moved") { if ($page->parent->id == $this->config->trashPageID) { // page is being trashed $operation = "trashed"; } else if ($page->parentPrevious->id == $this->config->trashPageID) { // page is being restored $operation = "restored"; } } // details about page being edited, trashed, moved etc. $details = array(); if ($page->title) $details['Page title'] = $page->title; $details['Page name'] = $page->name; if ($page->namePrevious) { $details[($operation == "moved" ? 'Page name' : 'Previous page name')] = $page->namePrevious; } $details['Template name'] = $page->template->name; if ($page->templatePrevious) { $details['Previous template name'] = $page->templatePrevious->name; } $details['Page URL'] = $page->url; if ($page->parentPrevious && $operation != "edited") { // for pages being edited current or previous parent is irrelevant // data since changing parent will also trigger "moved" operation. $details['Previous page URL'] = $page->parentPrevious->url; if ($page->namePrevious) $details['Previous page URL'] .= $page->namePrevious."/"; else $details['Previous page URL'] .= $page->name."/"; } if ($operation = "viewed" && $page->template->name == "vessel") { //$details['Page URL'] .= $page->input->urlSegment(1); //echo $pages->get($page)->input->urlSegment(1);//->input->urlSegment(1); //print_r($page); } // note: currently only "edited" operation keeps track of edited fields if (count($fields_edited)) $details['Fields edited'] = implode(", ", $fields_edited); // find out which script / URL triggered this particular action if ($this->log_caller && $caller = $this->getCaller()) $details['Caller'] = $caller; $this->insert($operation, $page->id, $page->template->id, $details); if ($page->isChanged('status') && !in_array($operation, array("unpublished", "published"))) { // if status has changed, log extra unpublished/published event $event->method = $page->is(Page::statusUnpublished) ? "unpublished" : "published"; $this->logPageEvent($event); } Much thanks to Teppo et al in advance
  7. I just added it into Changelog Can't wait for the next release so I can try out the multiple versions of modules... I don't want to try and fail the dev branch again.
  8. Hi. I made a little module a while ago to track pageviews. It stores each pageview record as a PW page (hidden, under a hidden parent page "ViewTracker"), with the user & page IDs and timestamp. <?php /** * Processwire ProcessViewtracker Module * * ProcessWire 2.5.3 * Copyright (C) 2014 by Ryan Cramer * Licensed under GNU/GPL v2, see LICENSE.TXT * http://processwire.com * */ /* TO-DO: - add settings: templates select, clear/archive option..? - add auto-creation of templates/fields on install */ class ProcessViewtracker extends WireData implements Module { /** * getModuleInfo is a module required by all modules to tell ProcessWire about them * * @return array * */ public static function getModuleInfo() { return array( 'title' => 'ViewTracker', 'version' => 1, 'summary' => 'Records pageviews.', 'href' => '', 'singular' => true, 'autoload' => true, 'icon' => 'eye', ); } public function init() { // add a hook after each page is rendered $this->addHookAfter('Page::render', $this, 'viewTracker'); } /** * ViewTracker hooks into every page after it's rendered and records the views for specified template(s) * (and adds "Hello World" text at the bottom) * */ public function viewTracker($event) { $page = $event->object; // don't add this to the admin pages if($page->template == 'admin') return; // add to selected templates if($page->template == 'vessel') { // create record $r = new Page(); $r->template = 'pageview'; $r->parent = wire('pages')->get('/viewtracker/'); $r->user = $this->user; $r->vessel_id = $page; $r->name = $this->user . $page . date('YmdHisu'); $r->status = $r->status | Page::statusHidden; $r->save(); // record if segment if($this->input->urlSegment(1) !== '') { //$segment = "$this->input->urlSegment(1)"; $this->sanitizer->text($this->input->urlSegment(1)); $r->page_segment = "{$this->input->urlSegment(1)}"; $r->save(); } $event->return = str_replace("</body>", "<p>Hello {$this->input->urlSegment(1)} World!</p></body>", $event->return); } } } I want to add a configuration option for choosing the template(s) this module should activate for, maybe an admin view, but for right now this is all I got, so that the view data can be pulled easily. I know PW can handle a great many pages, but like I've kept this module uninstalled when not developing it... though maybe if I'd just left it enabled I'd have an answer to my own question here. Because tracking page views compiles much more quickly than any other sort of page, really... Should I just be storing this data in its own table?
  9. I want to use this to add events to a calendar using FullCalendar.js... and eventually other items of different templates... The initialization goes like so: jq111("#calendar").fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month,agendaWeek,agendaDay' }, //defaultDate: '2010-01-01', editable: true, eventLimit: true, // allow "more" link when too many events events: '<?php echo $pages->get(1373)->url ?>?template=events' }); Obviously that doesn't work though since the JSON needs to be outputted in this format: [{"id":830,"start":1262279460000,"end":1262281260000,"title":"this is a long event isnt that right?","body":"","multi":0,"allDay":false,"extension_id":2},{"id":831,"start":1262282052000,"end":1262283852000,"title":"830","body":"","multi":0,"allDay":false,"extension_id":2},{"id":832,"start":1262284644000,"end":1262286444000,"title":"831","body":"","multi":0,"allDay":false,"extension_id":2}] Is there any way to change the format of the output..?
  10. Hey I got FC working! Woohoooo With AdminCustomPages module, in my admin page scripts and styles in its settings: calendar.js: var jq111 = jQuery.noConflict(true); jq111(function() { jq111("#calendar").fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month,agendaWeek,agendaDay' }, //defaultDate: '2014-11-12', editable: true, eventLimit: true, // allow "more" link when too many events events: [ { title: 'All Day Event', start: '2014-11-01' }, { title: 'Long Event', start: '2014-11-07', end: '2014-11-10' }, { id: 999, title: 'Repeating Event', start: '2014-11-09T16:00:00' }, { id: 999, title: 'Repeating Event', start: '2014-11-16T16:00:00' }, { title: 'Conference', start: '2014-11-11', end: '2014-11-13' }, { title: 'Meeting', start: '2014-11-12T10:30:00', end: '2014-11-12T12:30:00' }, { title: 'Lunch', start: '2014-11-12T12:00:00' }, { title: 'Meeting', start: '2014-11-12T14:30:00' }, { title: 'Happy Hour', start: '2014-11-12T17:30:00' }, { title: 'Dinner', start: '2014-11-12T20:00:00' }, { title: 'Birthday Party', start: '2014-11-13T07:00:00' }, { title: 'Click for Google', url: 'http://google.com/', start: '2014-11-28' } ] }); }); It's a beautiful start, there are minor CSS fixes to be made but that's the least of my concerns.
  11. I haven't even used PageTables yet but aren't those both (PT & Repeater) just different ways of managing pages? Everything's a page. I don't know if you mean to have one or multiple programs... so... you probably can just achieve what you want with PageTables or Repeater, just test out both. I just don't know what you want. But I would really like to get a calendar viewer of some sort up... where you can select templates to include or exclude and corresponding start & end datetime fields, if other than the default created. I really wanted to get FullCalendar to work, I've been trying to include the jQuery 1.11.1 to try to noconflict it in but I don't know what I'm doing but sadly it's not working. I'll check out the UI datepicker, thanks Mr. Fan.
  12. Unfortunately something about Full Calendar seems to conflict with the admin UI (debug info in footer is all open). I got this Kalendar to embed easily enough, now I just have to play with it... but I am disappointed about missing out on FC, at least for now.
  13. You just want an intuitive admin UI for these or something else? Just make a custom admin page, calendar, and I'm sure you can use like DataTables or even FullCalendar.io. Arrange the showings pages in the calendar view and have the page editors open in a modal. I might try this because calendar views tend to come in handy and could be mixed with actual calendar feeds potentially to see everything you need in one place.
  14. At least you get to travel rather than being stuck somewhere under somebody else's nose all day! Anyway, when you get a chance, definitely do buff up your site's SEO; that way you won't have to work as hard to promote your services to individual local agents, as they'll be coming to you. Also on your Services page, the sample website link http://maxwellbalmain.com/housesample/index.html is giving a server error. Maybe fix that first. Nice photography! Congrats on getting your site live, I hope it serves you well.
  15. hellomoto

    Lister

    I've used this before http://ngiriraj.com/pages/htmltable_export/demo.php which was super easy to implement and worked like a charm, and that was when only CSV was supported, apparently now many formats are; also I haven't tried it with large amounts of data. But it might be pretty breezy to implement export functionality with that script.
  16. Actually I don't think repeaters really can be set in importPageValue, because the column header isn't passed to it. So it would be better to set them as options in build form 2 (and more direct).
  17. I installed ServiceCurrencyConversion and it's great. I was wondering if any of you by chance had any experience with using this as I would expect it would often be used, to search by price... in your currency. Right now I have products that each have fields price_currency and price_amount. So each has a native currency. I am able to show the price in each currency we currently support on our listings index by way of this function: function currencyConvert($page) { //echo $page->id . '<br/>'; $cc = wire('modules')->get('ServiceCurrencyConversion'); $current = $page->price_currency->name; $amt = $page->price_amount; $currencies = wire("pages")->find('parent=1135,include=all'); //echo count($currencies) . '<br/>'; $converted = []; foreach($currencies as $currency) { //echo $currency->name; //if($currency = $cc) continue; //$converted["$currency->name"] = $cc->convert($current, $currency->name, $page->price_amount); //if($current != $currency->name) { //echo " Set: $current Now: $currency->name Amt: $page->price_amount "; $converted[$currency->name] = $cc->convert(strToUpper($current), strToUpper($currency->name), $page->price_amount); $amount = $currency->name == 'eur' ? number_format($converted[$currency->name], 0, ',', ' ') : number_format($converted[$currency->name]); $converted[$currency->name] = wire("pages")->find("parent=1135, name=$currency->name, include=all")->first()->title . $amount; //} } //print_r($converted); return $converted; //echo '<br/><br/>'; } So in my listings index I have: foreach(wire("pages")->find('parent=1135, include=all') as $currency) { if($currency->name != $item->price_currency->name) $price .= ' / ' . currencyConvert($item)[$currency->name]; } That outputs the price in every currency that isn't the default for the listing (which is already output). So I already have a search in place for listings that searches by the price_amount. I want to incorporate the different currencies in my search, while not excluding results based on their set currency. The way I have this set up currently works, but incorrectly, as it doesn't restrict listings based on their currency conversion. Now that I can convert them I want to fix the search feature to accommodate this. So how can I do this? I would think to maybe store a separate price_amount per currency, with a default set (to base other values from), but this does seem a bit tricky... Right now only 3 currencies are supported but if it grows to be a large amount it might become unwieldy. If that's the right way to do it though, so I will. Or, just leave the fields as-is, and go by the chosen currency in the search, returning all results that match the amount in that currency. This is what I would like to do because it seems simpler. But then I worry about performance... This means every search would have to convert the price for potentially almost every listing, and that's before even returning a set of results!(?) Like, you would have to search, with a currency and max. and/or min. amount set for price... then that search would have to first process the converted price for every listing that fits all the other search criteria, right (potentially all), and then return the values that match the price range in the chosen currency. That sounds like too much to me. Also obviously outputting the price in every currency we have would get too lengthy so I want to be able to target a single one efficiently. You see my dilemma? Anyone more knowledgeable have any advice, please? Much appreciated.
  18. Well this seems to work ok: protected function setPriceHistory($event) { $page = $event->arguments('page'); if($page->template != 'vessel') return; if($page->price_amount) { if(!$page->price_amount_hold) { $page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save(); $this->message("Updated hold price to current price."); } elseif($page->price_amount_hold && $page->price_amount != $page->price_amount_hold && !$page->is('unpublished')) { if($page->price_amount < $page->price_amount_hold) { $page->set("price_amount_was", $page->price_amount_hold)->set("price_cut_date", wireDate('Y-m-d')); $this->message("Price Cut set on " . wireDate('Y-m-d', $page->price_cut_date) . "."); } $page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n"); $pos = strpos($page->price_history, "\n", 1600); // Search for linebreaks after 1600 chars if($pos) $page->price_history = substr($page->price_history, 0, $pos); // Limit the string $page->save(); $this->message("Updated price history."); } } if($page->price_cut_clear) { $page->set("price_cut_date", "")->set("price_cut_clear", false)->save(); $this->message("Price cut cleared."); } }
  19. Okay so this was working, but now it seems to time out since I added changed the second condition to != and put the < within that: protected function setPriceHistory($event) { $page = $event->arguments('page'); if($page->template != 'vessel') return; if($page->price_amount) { //$this->message("Price exists"); if(!$page->price_amount_hold) { $page->set("price_amount_hold", $page->price_amount)->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save(); // append price_amount, date(), newline to price_history $this->message("Updated hold price to current price."); } if($page->price_amount != $page->price_amount_hold && !$page->is('unpublished')) { if($page->price_amount < $page->price_amount_hold) { $page->set("price_amount_was", $page->price_amount_hold)->save(); $this->message("Price Cut set on {$page->price_cut_date}."); } $page->set("price_history", $page->price_history . $page->price_amount . ", " . wireDate('Y-m-d') . "\n")->save(); $this->message("Updated price history."); } //$page->save(); } } See it was working up until I tried adding price history for any change in price, as opposed to only when it's cut. I thought it might be too many page->saves at once, so I removed the last save() from each of the changes, and just put it at the bottom... Still doesn't work, I get no data received, or a timeout: Oh. and it added about a million of the same line from the same save, that's why it timed out... Why might that be..?
  20. Yeah I just realized I should just make it what it is plus the new one as I was reloading this page just now... Leave it to me to think after I ask... Thanks for the delimiter tip too.
  21. Teppo got me to realize that I can simply do $page->$field->address = $value. So now map marker address can be imported which means it's time to tackle the repeaters... oy.
  22. Ah yes it works! Thank you I didn't even know you could string variables like that!
  23. I know repeaters are pages... For my main template that I am trying to get this to work for primarily, I have a repeater field engines with the default ready set to 2. So I would assume that these are created nonetheless when creating a page of that template via the API... This is tricky. I think perhaps the individual repeater fields should be included in the fields list when matching them prior to actually importing and then separate the values into repeaters on import? Anyway I think I'll try to get the mapmarker working first. The $value in importPageValue isn't what's returned by MapMarker, it's the value you're setting for the field, from the CSV.
×
×
  • Create New...