Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 05/24/2017 in all areas

  1. Hey all, yesterday evening I started playing with the new uikit admin theme and I have to say I really like the way @ryan has developed it, it's relatively easy to modifiy it further. It took me around 10 minutes to prepare the development pipeline (from installation, setup the build processes and grasp the directory structures), so I highly encourage every designer in here to get their hand dirty and start without any fear I'm going to post in this thread my progresses, since my will is to dedicate every evening 1 hour or so with the purpose to release a visually pleasing and stable admin theme. If you want to post your progresses in this thread too, you're welcome!
    12 points
  2. Working with PNG and GIF now too. Looks really interesting! I'm impressed with how far you've taken this already. Is this a fairly common need? (chunked uploads). I'm not sure I've come across a case where I would have used this on a site before, but I imagine there are cases this could be a real life saver. Really cool libraries! Probably too much for our needs in the admin, but seems like a lot of great potential for modules here.
    6 points
  3. Basically every time you need to handle files bigger than say 100-200MB, but you don't want to / can't give php more memory. Also timeouts Given more free time I would've created a bit more fleshed out PR to the core, but it's currently not possible. The biggest thing to improve here would be some kind of cleanup, so chunks of unsuccessful uploads do not sit there forever. Keeping them for a short timeframe is nice, because it'll speed up second tries.
    4 points
  4. A page does not have an icon, its template does, so if you are creating the template programmatically, use: $template->setIcon($icon); And about the sort order, do you wish to set the sort of the children or just append the page at the beginning of the list of its siblings?
    4 points
  5. @ryan This might be a handy addition to the topic as well: https://gist.github.com/LostKobrakai/ddb11c64dcb0f1bf1c8eed4dd534a868 (prove-of-concept level) Chunked uploads would allow for file uploads beyond any php set limits even for files, which we obviously cannot shrink client side.
    4 points
  6. I agree! I was playing around with the styles the other day for about 20 minutes to create a "calm" version, not yet finished, but see the screenshots.
    3 points
  7. Just a little progress I made, there is (of course) a lot of work to do and several tweaks, but it's a starting point
    3 points
  8. client side image resizing is definitly a common need - if you work with non proffesional endusers that wanna trow images from their digcams online...;)
    3 points
  9. Conceptually such a module will never be part of the ProcessWire core, however, thanks to developers there are lots of useful modules out there solving various needs such as: Think of ProcessWire as a Content Management Framework and not as a CMS. The phrase CMS is used because the ProcessWire backend is powerful enough to be called so. ProcessWire is somewhere between a CMS like Joomla and a framework like CodeIgniter. And this is done all conceptually. Those who rely on it appreciate this, that is why we are here in the first place. You might need something else, it is up to you to decide. BTW, there are similar systems out there (such as SilverStripe that comes to my mind), meaning ProcessWire is not a one-of-its-kind system at all in this regard. However it is a one-of-its-kind in its OWN category Hope this helps.
    3 points
  10. I started experimenting this morning. It's not all that difficult to get going. Proof-of-concept up and running already, so should have this functional on the core dev branch this week hopefully. (note: works for JPGs only)
    3 points
  11. Introducing our newest [commercial] module: Recurme Processwire Recurring Dates Field & Custom Calendar Module. http://www.99lime.com/modules/recurme/ One Field to Recur them ALL… A Recurring Dates InputField for your Processwire templates. The InputField you’ve been waiting for. Complex RRule date repeating in a simple and fast user interface. Use the super simple, & powerful API to output them into your templates. example: <? // easy to get recurring events $events = $recurme->find(); // events for this day $events = $recurme->day(); // events for this week $events = $recurme->week(); // events for this month $events = $recurme->month(); ?> <? // Loop through your events foreach($events as $event){ echo $event->title; echo $event->start_date; echo $event->rrule; echo $event->original->url; ... } ?> Unlimited Custom Calendars. Imagine you could create any calendar you wanted on your website. Use recurring events with the Recurme field, or use your own Processwire pages and date fields to render calendars… it’s up to you. Fully customizable. Make as many calendars as you like. Get events from anywhere. Recurme does all the hard date work for you. Unlimited Custom Admin Calendars too. Hope you like it , Joshua & Eduardo from 99Lime. ## [1.0.1] - 2017-05-29 ### changed - Fixed $options[weekStartDay] offset in Calendar - Fixed ->renderCalendar() Blank Days - Fixed missing ->renderList() [renderMonth][xAfter] - Removed ->renderCalendar() <table> attributes border, border-spacing - Fixed ->renderCalendar() excluded dates - Fixed rrule-giu.js exclude dates - Fixed ->renderList missing space in attr ID (shout out to @Juergen for multiple suggestions & feedback).
    2 points
  12. This is a minimalistic website for the german architecture office Weissenrieder Architekten BDA. The front-end uses UIkit 2 and Isotope for the projects overview. Every project category can be accessed in the overview with an URL segment. ProFields Table was used for the project detail view. www.architekt-weissenrieder.de Modules used: AdminThemeUIkit Table ProCache Markup Sitemap XML Email Obfuscation (EMO) Jumplinks Tracy Debugger Regards, Andreas
    2 points
  13. Thank you, adrian this... $user_image->first()->url ..fixed my issue of rendering a user image. As you mentioned, even though field is set to 1, I needed to add "first()" I just started using ProcessWire today and I have to say this is the most fun I've had coding a CMS. It's the CMS I'd have written if life didn't keep getting in the way and eat up so much of my time....haha Outstanding job, Ryan!
    2 points
  14. body {filter: saturate(0)} img {filter: saturate(1)} calm version the quick way
    2 points
  15. Check these methods: $p->prepend($page) Prepend the given page to the beginning of the PageArray. $p->append($page) Append the given page to the end of the PageArray. More: https://processwire.com/api/arrays/page/
    2 points
  16. Hi @Marc Not tested $siteB = new ProcessWire($path, $url); $siteB->pages->add('skyscraper', '/skyscrapers/atlanta/', [ 'title' => 'Symphony Tower', 'summary' => 'A 41-story skyscraper located at 1180 Peachtree Street', 'height' => 657, 'floors' => 41 ]); https://processwire.com/api/ref/pages/add/
    2 points
  17. awesome Looks really interesting! I'm impressed with how far you've taken this already. Is this a fairly common need? (chunked uploads). I'm not sure I've come across a case where I would have used this on a site before, but I imagine there are cases this could be a real life saver. i think this would be a great addition as well and would like to support lostkobrakai here. i already stumbled over this problem here: and it came up some other times as well: i ended up needing my client to upload everything via FTP or dropbox and pasting the links into a textfield. i wanted to develop a module that scans the directory and adds the files automatically to a file field but all of this is a really bad solution regarding UX. i almost had to build a video-platform once where this would also have been a very welcome feature. otherwise i would have had to use some 3rd party uploader with all the problems (different design, maybe opening security holes, ...). especially regarding security i would feel much more comfortable when having a built in solution rather than adding any 3rd party hack... ps: it may not be a very common need, but it can be a fundamental one
    2 points
  18. Just a suggestion but it'd be really useful if there was a Description field available when creating a HannaCode. I like to keep my HC names short and choppy and a description would greatly help users later on establishing what the HC is for or does a Description column on the HannaCode overview page too pulling in above Description It would also be great to be able to see a list of pages where HCs are used within RTEs or templates but that (for me) isn't such a biggie.
    2 points
  19. @jploch, looks like good case to use my proposed $wirearray->chunk() for. See this post for the hook you would need to add in order to use chunk()... I'm not a fan of echoing markup within functions (nothing wrong with it, just a personal preference) so I would do this: In a new include/partial named album_list.php... <?php $images_per_slide = 4; // exclude pages with no thumbnail in the selector $albums = $pages->find("parent=/work/, template=project, thumbnail!='', sort=sort"); // chunk albums into groups $albums_chunked = $albums->chunk($images_per_slide); // ditch the last group if it has less than the number of images per slide (assuming that's what you want) if( count(end($albums_chunked)) < $images_per_slide ) array_pop($albums_chunked); ?> <?php foreach($albums_chunked as $key => $slide): ?> <div class="slide" id="slide<?= $key + 1 ?>"> <div class="grid"> <?php foreach($slide as $album): ?> <a href="<?= $album->url ?>" <?= $album->thumbnail->bgset('half', 'lazyload item size1of2', array('quality' => 70)) ?>> <img src="/site/templates/img/plus-icon.svg" class="info-button"> <div class="item-info"> <div class="info-container-center"> <h3><?= $album->thumbnail->tags ?></h3> <h2>Für <?= $album->title ?></h2> <p><?= $album->thumbnail->description ?></p> </div> </div> </a> <?php endforeach; ?> </div> </div> <?php endforeach; ?> Then wherever you want to output the slides... include $_SERVER['DOCUMENT_ROOT'] . '/site/templates/partials/album_list.php'; Or if you prefer... echo $files->render('partials/album_list');
    2 points
  20. Yes, you can set the name for children of a page, editing the parent template "Family" settings. See: http://processwire.com/api/modules/process-template/
    2 points
  21. If the role doesn't have page-edit permission and doesn't have profile-edit permission then they cannot see the page list or edit their profile. They just see this: But to prevent them from seeing the admin interface at all you can add this at the top of /site/templates/admin.php... if($user->isLoggedin() && !$user->hasPermission('page-edit')) { // Uncomment whichever you prefer // $session->redirect('/'); // throw new Wire404Exception(); }
    2 points
  22. This week we’ve got ProcessWire 2.8.62 (corresponding to 3.0.62 master), a look at some current work-in-progress, and some nice momentum in ProcessWire usage and market share. https://processwire.com/blog/posts/new-2.8-version-current-projects-and-pw-usage/
    1 point
  23. I like it! I've used Shuffle.js (non-jQuery, non-commercial) recently to replace Isotope and it did the job nicely.
    1 point
  24. I tested out the new version and it works really well. Thanks @Robin S.
    1 point
  25. Another option would be: $page = $siteB->wire(new Page());
    1 point
  26. Is modifying the recurring tabular list below the RRule definition currently the only way to exclude dates in the exclusion? We pay for a (rather poorly implemented) calendar that has a GUI mini-calendar selection to create a list of dates to exclude. Love this calendar, but I'd be fearful of removing/changing something that our staff (not highly computer literate) is used to - so just curious. Thanks for providing this! RRule is a confusing thing to implement in a database!
    1 point
  27. Hello @Robin S the problem is still there in version 0.0.3. Argument 2 passed to ProcessWire\InputfieldWrapper::insertAfter() must be an instance of ProcessWire\Inputfield, null given, called in /home/.sites/24/site1275/web/site/assets/cache/FileCompiler/site/modules/CustomInputfieldDependencies/CustomInputfieldDependencies.module on line 156 and defined Best regards
    1 point
  28. This would certainly come in handy for me on a few projects. I do work for charities and set them up with hosting that is free, but there are a lot of restrictions put in place naturally. +1 from me.
    1 point
  29. The only thing affecting the order of the images is the sort within the selector. You can check the order right after you get the albums: $albums = $pages->find("parent=/work/, template=project, thumbnail!='', sort=sort"); echo $albums->each("<p>{title}</p>"); This should list the pages in the same order as they appear in the page tree. Unless you have specified automatic sort settings on the parent page or template, but I doubt you would have done that as it would prevent manually sorting the pages. If the album pages are listed in the right order but the images within each slide are not in the position you want then that is a CSS issue. Not sure what is going on there. There's nothing in the chunk() hook that should affect logging in. But you don't really need to add chunk() as a new WireArray method if it's causing you difficulties and you only need to use it for this one application - you can just do the equivalent within your template/include/function instead: $images_per_slide = 4; $albums = $pages->find("parent=/work/, template=project, thumbnail!='', sort=sort"); $albums_chunked = array(); for($n = 0; $n + $images_per_slide <= $albums->count(); $n += $images_per_slide) { $albums_chunked[] = $albums->slice($n, $images_per_slide); } // now iterate...
    1 point
  30. I just wanted to say THANK YOU @adrian Great work!
    1 point
  31. Are you talking about inputfield dependencies? From the docs...
    1 point
  32. Installing via "Add module from URL" is nearly as easy: https://github.com/somatonic/ClearCacheAdmin/archive/master.zip But I agree it would be great to have this module in the directory.
    1 point
  33. To my way of thinking, numeric IDs are the worst case in terms of being editor friendly. I see HannaCodeDialog as being a kind of progressive enhancement of Hanna Code, such that in the future you could uninstall HannaCodeDialog and still have tags that an editor can understand and use. But with numeric IDs you'll have tags along the lines of... [[my_tag file="34784" options="4745|9748|8985"]] And that seems contrary to the whole idea of Hanna Code, which is about giving editors easy to understand options while you the developer do the heavy lifting (be it matching editor-friendly names to IDs or whatever) behind the scenes in the tag code. Having said that, I'd like the module to be flexible and let devs decide for themselves how they want to use it. So happy to announce... HannaCodeDialog v0.1.2 Inserting a tag from the dropdown no longer opens the dialog if the tag has no editable options. A new method prepareOptions() can be hooked in order to define or manipulate the options that can be selected for a tag attribute. See the module readme for more. @LMD, you can hook this new method to set separate value and label as per your proposal: $wire->addHookAfter('HannaCodeDialog::prepareOptions', function($event) { $options = $event->return; $new_options = array(); foreach($options as $option) { if(strpos($option, '@@') !== false) { list($value, $label) = explode('@@', $option); $new_options[$value] = $label; } else { $new_options[$option] = $option; } } $event->return = $new_options; });
    1 point
  34. Most of our image/file features have been developed by the community rather than me, and I'm guessing this will follow a similar path. It doesn't seem to come up very often, but since you've mentioned it here maybe we'll have to bring more focus to it. I'll try to get a closer look this week to get a better idea of when we might be able to get more momentum going here. I do agree it would be a nice thing to have sooner rather than later. Also, since you quoted both 2016 and 2017 roadmap, it's important to note that this is a roadmap. It is a list of goals, it is not a contract of promises. We never expect to be able to accomplish all the goals, but feel it's important to have them nevertheless. Always good to aim for more rather than less. What doesn't get completed in one year still stays on the roadmap for the next year, unless it's determined it shouldn't be for some reason.
    1 point
  35. Speaking for my modules only, I'm marketing these as turn-key modules, not as API tools. With the exception of the ProfilerPro module and Likes modules, the Pro modules that I develop were never intended as primarily API programming modules. They are modules that, outside of output generation, are meant to be largely turn-key, without little or no coding needed. It is true that you can use them at the coding level to do lots of things, they have an API and hooks available, and we could write an encyclopedia worth of content to cover it all. And it's also true that there are a few people, perhaps 5% of the users, that pursue this kind of stuff with these modules (especially Robin S., Adrian, LostKobrakai). I think that's great, and I'm happy to support that for those that are interested in using them that way, and have been for a long time via the support boards. This is a welcome and valuable audience for these modules, but not the primary or intended audience. The intention with most of the Pro modules is to provide things you can install and start using, and not have to code around. The documentation is consistent with the audience and intention of the modules. For those that want to get into the code side, I welcome it, but prefer to support them via the support board and focus in specifically on their needs. Though in the ProFields modules we do cover a lot of API side stuff too. The code of the modules is also well documented with phpdoc as well, making it handy in an IDE environment. If I develop a module intended primarily for API usage in the future, then of course the approach would be different. But because that doesn't describe my current Pro modules, I prefer to support people individually when they want to pursue unique needs that might require additional code, as everyone's needs are slightly different. That's beautifully put together– joshuag is an amazing designer and front-end framework developer, and there's no way I could ever compete with his skills in those areas. Sorry about that, but that's just reality. I can make great modules, but I'm far more developer than designer and marketer. I gave up trying to be a designer long ago. Also should mention though that what he's marketing clearly has a larger API-side than what's intended for any of my modules. And I agree he's outlined everything really nicely. I feel that I covered everything about the product pretty exhaustively. What do you think is lacking? https://processwire.com/api/modules/lister-pro/ Actions are just one small part of ListerPro, but it comes with seven actions, including an action that's a template for creating your own. Also why the surprise (?), the ListerPro page outlines all of the seven actions here. Have you seen this? https://processwire.com/api/modules/profields/ I don't use this one very often, and may delete it. It started back before we had an on-site store, so isn't really needed anymore, as it's been replaced by our store. They are not outdated. As far as the information goes about the modules, they are fully relevant and up-to-date. Though I should mention I always try to provide more than I market, and feel this is a good thing. I like for people to feel that they got something more and better than what they expected, with everything I do.
    1 point
  36. How about a Buy-a-Coffee too? We need options!
    1 point
  37. I edited my post above. Sure you can have multiple super users but it also happened to me that I forgot the name of the initial admin and I had to find out in the database... User id 41 can be very handy to know in those cases
    1 point
  38. I've been using PW for quite a while, now, so I would like to give back to the community that helped me so many times. I had this customer that wanted to use the Google Translate API to automatically translate the site, so I built this function that takes advantage of it without the need to use the API on every page cycle. I put it on a file that gets called on the _init.php, so that I can use it on every template. Here it is: <?php function googleAutoTranslate($page, $field) { // Turn off outputFormatting $page->of(false); // Get current language and field content for this language $current_language = wire('user')->language->name; $field_content = $page->getLanguageValue($current_language, $field); // Is there any content for this language? if($field_content != '') { // Do nothing! } else { // No content, lets translate... // Get default language text $text = $page->getLanguageValue('default', $field); // Translate only if there's content in the default language if($text != '') { // Translate it $apiKey = 'YOUR API KEY HERE'; $default_language = 'pt'; // Your default language here! $url = 'https://www.googleapis.com/language/translate/v2?key=' . $apiKey .'&q=' . rawurlencode($text) . '&source=' . $default_language . '&target=' . $current_language; $json = json_decode(file_get_contents($url)); $field_content = $json->data->translations[0]->translatedText; // Save translated text $page->$field->setLanguageValue($current_language, $field_content); $page->save(); } } // Turn on outputFormatting $page->of(true); // Return result return $field_content; } ?> Whenever you use a field on a template that should be auto translated, just call the function with a page object and the field name, like so: echo googleAutoTranslate($page, 'body'); Features: Translation occurs only once per field, so you don't need to keep paying translations (it stores the translation into the field language); You can correct the translation in the admin area and it won't be overwritten; If you need the translation to be made again, just delete the field content in the needed language. For the translation to occur, content must exist in the default language. I had to fight a little to get this working, so I hope this helps anyone, who comes across this particular need. Nice Things To Have If someone wants to give it a shot to make this into a module, please do. It would be nice to have a checkbox "Enable Google auto translate for this field", when you edit a field input features. Don't Spend Too Much Mind you that the Google translate is a payed service! and needs a Credit Card to get it going (even with $300 free credit); With a relatively small site (and the tests made to get this to work) I already spent about 80.000 translated characters = $3, Hope this helps someone!
    1 point
  39. It was far easier than I had first expected, as I started without much external input and CI restraints, so I could stick with UIKit defaults and had no usability expectations to meet. So I stuck with the "keep it simple" philosophy. I'm tentatively planning to make a release bundle out of it (time is as always the factor), but need to strip out a few specifics first and replace them with more generic code. There are also a few things which I simply stuck into site config but would merit a dedicated config page (think addresses, currency, holidays, time constraints and all that).
    1 point
  40. Between a lot of big, not-web-related projects at work, I could squeeze in having a little a fun with ProcessWire too. What was needed was a shop-like solution where employees can order lunch snacks from our local butcher. Previously, this was handled with hand-written lists in each production hall that would be forwarded over fax to the butchers, leading to all kinds of transliteration and pricing errors. Our Central Services department looked at different software packages for that, but none of them did exactly what they needed. ProcessWire to the rescue. In little more than two days, I got a fitting solution up and running: PW 3.0.52 The only two non-standard modules used are @adrian's AdminActions and my own DatetimeAdvanced Role based template access UIKit 3 with modals, flex layout, mobile-ready with hamburger menu on smaller devices Everything is a page Synchronisation of employee accounts from time management software (> 600) into PW (120 lines, runs twice a day) Mixed authentication (Windows Active Directory if user is available there, local password if not) Account balance system with manual deposits and automated checking / detuction / refunding for orders, complete transaction history visible for the user Article categories (page reference), product images (not used yet), simple product variants (1 level, text + price) Ordering contents of a shopping cart for a single day or multiple days ahead of time within (admin configurable) time constraints (order window for following day ends X hours before, holidays excluded, etc.) Delivery locations (buildings) changeable by users themselves Integrated favorites system Management area in frontend for balance bookings, managing articles, previewing orders Daily collected orders for the butchery are printed into PDF through fpdf with a tiny wrapper Product images option with thumbnails (currently not used) Small additions like price validity dates or saving and re-using shopping carts will be added over the next months The shop landing page with all relevant information: Articles are grouped by category and have dropdowns for variations (with optional price addition/discount): Editable shopping cart with option to order same selection for multiple days: Minimallistic product item editor:
    1 point
  41. I think there is still an outstanding bug (https://github.com/ryancramerdesign/ProcessWire/issues/1803) with images on user pages - it seems like outputformatting is always off which results in the need for first(), even when maxFiles is set to 1. Try this: $user_image->first()->url
    1 point
  42. Hi pitbull Download the fullcalendar from the link below http://arshaw.com/fullcalendar/download/ Upload the fullcalendar.css , fullcalendar.print.css and fullcalendar.js to your server end embedded in your page header like this <link rel="stylesheet" type="text/css" href="<?php echo $config->urls->templates ?>assets/css/styleaahaeota.css"> <link href='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.css' rel='stylesheet' /> <link href='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.print.css' rel='stylesheet' media='print' /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="<?php echo $config->urls->templates ?>assets/js/bootstrap.js"></script> <script src='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.js'></script> add the code below in your header after the <script src='<?php echo $config->urls->templates ?>assets/calendar/fullcalendar.js'></script> <script> $(document).ready(function() { $('#calendar').fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month,agendaWeek,agendaDay' }, editable: false, events: "http://weborange.gr/aahaeota/json-events.php", eventRender: function(event, element, view ) { var image = '<img src="'+event.img+'" />'; if (view.name === "agendaDay") { element.find('.fc-event-title').append("<br/>" + event.description); } // on event hover pop up a small discription of the event and an image, // i use bootsrap framework so popoever is curently works only for // bootsrap details in http://twitter.github.io/bootstrap/javascript.html#popovers //if you dont want this, delete it or take the code from my last post element.popover({ html: true, trigger: 'hover', title: event.title, placement: 'top', content: image + '<span class="calendar-detail-time"> ' + event.ddate + ' until ' + event.dend + '</span>' + '<br/>' + event.description , }); }, eventDrop: function(event, delta) { alert(event.title + ' was moved ' + delta + ' days\n' + '(should probably update your database)'); }, loading: function(bool) { if (bool) $('#loading').show(); else $('#loading').hide(); } }); $oldTable.remove(); }); </script> create a new php file called json-events.php and upload it in your root folder. Inside json-events.php add the below code <?php include("index.php"); // bootstrap ProcessWire function pagesToJSON(PageArray $events) { $json = array(); foreach($events as $event) { $json[] = pageToArray($event); } return json_encode($json); } function pageToArray(Page $event) { $data = array( 'id' => $event->id, 'title' => $event->title, 'start' => date("Y-m-d H:i",$event->date_start), 'end' => date("Y-m-d H:i",$event->date_end), 'url' => "$event->url", // event ID is the url segment 'description' => "$event->summary", //event summary for bootsrap popover 'allDay' => false, 'img' => $event->images->first()->url, //event image for bootsrap popover 'ddate' => date("d-m-Y H:i",$event->date_start), //event date start for bootsrap popover 'dend' => date("d-m-Y H:i",$event->date_end), //event date for bootsrap popover ); return $data; } // end else $eventPage = $wire->pages->get('/events/')->children(); echo pagesToJSON($eventPage); ?> and final in the template that you want to render the calendar add <div class="tab-pane" id="calendary"> <div id='loading' style='display:none'>loading...</div> <div id='calendar' class='calendar-page'></div> </div> that's it, you can see example here just go one month before from the upper left arrows sorry for my bad english , i hope that this is going to help you
    1 point
  43. Here was Ryan's example code for calendar, until I (apeisa) modified it instead of quoting... I got the original back from my editor, I post it here as reference. Ryan - sorry I lost your message here. You wrote something about that it is fun to code calendars -apeisa <?php $year = (int) $input->urlSegment1; $month = (int) $input->urlSegment2; if(!$month) $month = date('n'); // if no month, use this month if(!$year) $year = date('Y'); // if no year, use this year $startTime = strtotime("$year-$month-01 00:00:00"); $endTime = strtotime("+1 month", $startTime); // find all events that fall in the given month and year $events = $page->children("date>=$startTime, date<$endTime"); // get all the info you need to draw a grid calendar $weekDayNames = array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'); $firstDayName = date('D', $startTime); // i.e. Tue $daysInMonth = date('t', $startTime); // 28 through 31 // make the calendar headline $out = "<h1>" . date('F Y') . "</h1>"; // i.e. October 2011 // create the calendar header with weekday names $out .= "<table><thead><tr>"; foreach($weekDayNames as $name) $out .= "<th>$name</th>"; $out .= "</tr></thead><tbody><tr>"; // fill in blank days from last month till we get to first day in this month foreach($weekDayNames as $name) { if($name == $firstDayName) break; $out .= "<td> </td>"; } // draw the calendar for($day = 1; $day <= $daysInMonth; $day++) { // get the time info that we need for this day $startTime = strtotime("$year-$month-$day 00:00:00"); $endTime = strtotime("+1 day", $startTime); $dayName = date('D', $startTime); // if we're at the beginning of a week, start a new row if($day > 1 && $dayName == 'Sun') $out .= "<tr>"; // create the list of events for this day (if any) $list = ''; foreach($events->find("date>=$startTime, date<$endTime") as $event) { $list .= "<li><a href='{$event->url}'>{$event->title}</a></li>"; } // if any events were found for this day, wrap it in <ul> tag if($list) $list = "<ul>$list</ul>"; // make the day column with day number as header and event list as body $out .= "<td><h2>$day</h2>$list</td>"; // if last day in week, then close out the row if($dayName == 'Sun') $out .= "</tr>"; } // finish out the week with blank days for next month $key = array_search($dayName, $weekDayNames); while(isset($weekDayNames[++$key])) { $out .= "<td> </td>"; } // close the last row and table $out .= "</tr></tbody></table>"; // output the calendar echo $out;
    1 point
×
×
  • Create New...