Leaderboard
Popular Content
Showing content with the highest reputation on 05/11/2013 in all areas
-
If the parent page is hidden you'd have to include "include=hidden" in the selector when doing a find(), but not if you get() the page explicitly. Also wanted to note that doing $pages->get("title=previous caption winners")->children; isn't a very reliable method to find a page by it's title, since the title isn't unique. In most cases it makes more sense to use id or page name, page path. $pages->get(1005)->children; Or maybe $pages->get("/some/path/")->children; To find if a parent has children there's also a method in PW numChildren(). if($pages->get(1004)->numChildren) { // has children } In PW 2.3 there's a new version of numChildren() to make it access aware if you pass true as the argmument if($pages->get(1004)->numChildren(true)) { // has children that are really visible to the user }3 points
-
Web apps in PW? Hell yeah, Processwire is great for that. I love how I can map out my app before I get started into a tree. I actually built a lot of web apps on PW. One being http://collabmango.com PW saves a lot of time in building web apps. The selectors and not needing to deal with DB crap is a huge +3 points
-
Awesome news, congrats ryan! I nearly wet myself Must be a combination of ___smoothTalker() and ___giggity()2 points
-
The find() method returns an array of pages, and you can on only check for children in a individual page. If your goal with this selector is to get only one page, use get() instead. $info = $pages->get("title=previous caption winners")->children; But, if all you want is to check if there are children, the shortest method would be: if ($pages->get("title=previous caption winners")->child->id) It gets the first child and checks for it's id edit: nik was faster2 points
-
I agree, there is tons of duplication, but just temporarily. You'll see plenty of duplication when I commit the PDO updates to dev. But I think it's okay since it's only for a few months until the 2.4 transition is complete. There's also the factor that PW doesn't have a lot of SQL queries in the first place–most of the application logic is behind the PW API. Converting all the queries in the core took me less than a day. Once 2.4 is released, I'm going to go back and remove all of the redundant mysqli statements, since they won't be relevant anymore. The syntax is a lot different between the two. I'd not ever used PDO before, but after playing around with it a lot, I thought it had a lot of benefits over mysqli. Most significant to me are the benefits with prepared queries and ability to use named parameters. I'd always thought mysqli prepared statements were awkward and annoying in almost every sense, so tended to avoid them. But in PDO, they are very clean and easy to use, and help to make not just safer queries, but more readable queries. Btw, if you don't need to check the return value, a wire('db')->query('sql statement'); will work the same between mysqli and PDO. So there are some instances that may not need to be accounted for. Backwards compatibility isn't a major factor here just because our API isn't based on DB queries. So usually when DB queries are used, they are doing something out of the ordinary. There aren't a lot of modules using SQL queries. I'm guessing less than a dozen. I figured better to get this change in place sooner rather than later, as it's a lot easier to do now than it will be a year or two from now. Good and interesting idea. Is it possible to have two database drivers (PDO and mysqli) connected to the same DB at the same time? Maybe it is, in which case, I'd be open to going this route. In that case, I'd probably just leave $db the mysqli one and make it deprecated but functional till 2.5, and call the new PDO one $pdo. No plans to cut ties with MySQL and no plans to adopt other databases just yet. Going with PDO is motivated purely by making sure we're giving our users the best tools out there. PDO is looked upon much more positively in the PHP community, and that perception has just been increasing over the last couple of years. But I think it's beyond perception and there's a lot of good reasons to use PDO over mysqli. Given this, I think that combined with our switch to supporting namespaces and Composer (2.4), it will help ProcessWire to grow in the PHP community in addition to the web developer community. It's also a good time to do it because 2.3 modules aren't going to be compatible with 2.4 already, purely because of namespaces. Though this one will be very simple for module developers to correct, simply by adding "namespace ProcessWire" at the top of the file (I think).2 points
-
+1 sublime text edit: I'm also trying Textadept lately and I'm liking it for now (beware sublime!), It's free open source and cross-platform http://foicica.com/textadept/2 points
-
One simple approach could be to code up some Shortcodes for them to use inside a textarea. This way the developer can control the functionality and the client can insert and position stuff with relative ease. The developer should write some clear instructions to go along. Of course, this has it's limitations but if done correctly this can be pretty powerful. <fieldbodytext> <p>some text> [myGallery] // it could use pics attached to a page image field <p>some more text</p> // embed a video using mods.pw/D <p>some more text</p> [myLatestNewsListing] <p>etc.</p> </fieldbodytext>2 points
-
MarkupCache is a simple module that enables you to cache any individual parts in a template. I'm working on a site now that has 500+ cities in a select pulldown generated from ProcessWire pages. Loading 500+ pages and creating the select options on every pageview isn't terribly efficient, but I didn't want to cache the whole template because it needed to support dynamic parameters in the URL. The solution was to cache just the code that generated the select options. Here's an example: $cache = $modules->get("MarkupCache"); if(!$data = $cache->get("something")) { // ... generate your markup in $data ... $cache->save($data); } echo $data; I left the markup generation code (the part that gets cached) out of the example above to keep it simple. Below is the same example as above, but filled out with code that finds the pages and generates the markup (the part that gets cached): $cache = $modules->get("MarkupCache"); if(!$data = $cache->get("city_options")) { foreach($pages->find("template=city, sort=name") as $city) { $data .= "<option value='{$city->id}'>{$city->title}</option>"; } $cache->save($data); } echo $data; That was an example of a place where this module might be useful, but of course this module can used to cache any snippets of code. By default, it caches the markup for an hour. If you wanted to cache it for a longer or shorter amount of time, you would just specify the number of seconds as a second parameter in the get() call. For example, this would keep a 60-second cache of the data: $cache->get("city_options", 60) I hope to have it posted to GitHub soon and it will be included in the ProcessWire distribution. If anyone wants it now, just let me know and I'll post it here or email it to you.1 point
-
So, I've been seeing some email-related topics around here and actually had quite a few struggles of my own with this very subject myself lately. Thing is that sending email should be easy, but it's not always that; especially for those who have to work on multiple, low-price (and regrettably often low-quality) platforms that may or may not provide proper mail servers.. or prefer to host their services themselves and still want to avoid setting up and maintaining a mail server. Hosting a mail server can be real pain in the ass when things don't work like they should, not to mention that most people have very little knowledge about DNS entries etc. this requires. Anyway, long story short: yesterday I started thinking that wouldn't it be sweet to have a layer of abstraction within ProcessWire for sending email? Of course one could still use PHP mail() -- there's no way and no sense in even trying to stop that -- but using a common gateway would definitely bring in some extra value. This layer I'm talking about could by default use built-in PHP mail() but also make it possible to override it, thus allowing multitude of options that PHP mail(), being bound to Sendmail / it's alternatives, can't offer without additional server-side software (such as Nullmailer.) By making sending emails hookable it could also enable all kinds of interesting tricks to be done when mail is sent -- such as writing a custom log file, sending another email to someone else, updating local content (I'd imagine that this could be useful for building newsletter platform, for an example) and so on. Since words tend to fail me at times like these, I put together a quick proof of concept of what I'm talking about here, accompanied by one example of what could be achieved by doing this: A very simple yet functional Mailer class Two commits on top here list all the changes I've made in my PW fork to make this work -- including the fact that I've altered some default modules to use $mailer->send() instead of mail() SwiftMailer module, again very simple but fully functional (though only tested with Gmail SMTP) drop-in replacement for PHP mail() So, what do you folks think of this? Please keep in mind that this is just a suggestion and I'm not saying that this is the right path to take especially considering that it would add another API variable -- it just felt like best option here and I couldn't think of cleaner way to achieve it.1 point
-
One of the changes coming in ProcessWire 2.4 (and the 2.3 dev branch) is that we're switching the database driver from mysqli to PDO. Over the next few days, you'll see the ProcessWire dev branch begin to be compatible with both mysqli and PDO. By the time we hit version 2.4, it will only be compatible with PDO. If you develop modules or templates that perform SQL queries, and you want to have a head start, you can begin make your module(s) compatible now by checking what the DB driver is. Though I'm thinking most modules out there don't do any kind of SQL queries, so it won't matter. But for those that do, I wanted to go ahead and mention it since it'll be showing up on the dev branch shortly (I already have it switched locally). Here is an example that issues the same exact query with the two different DB drivers. $db = wire('db'); $name = "example"; if($db instanceof PDO) { // driver is PDO $query = $db->prepare("SELECT COUNT(*) FROM my_fake_table WHERE name=:name"); $query->execute(array(":name" => $name)); $count = $query->fetchColumn(); } else { // driver is mysqli $result = $db->query("SELECT COUNT(*) FROM my_fake_table WHERE name='" . $db->escape_string($name) . "'"); $row = $result->fetch_row(); $count = $row[0]; } If you have any queries that you aren't sure how to convert from mysqli to PDO, just post them here and I'll code it for you.The PDO queries tend to be a little more verbose most of the time (even if not above). But the use of named parameters is something that we need, and mysqli just doesn't have them (unless you like using question marks). There are other benefits to using PDO, but the named parameters are the main benefit in the short term.1 point
-
ok!! calendar start to live thank's to you Sakkoulas.. needs some experimental to make it look so nice like yours (time and title dont fit in calendar, image so big) i ques something with css. i like a lot the (Τελευταία Νέα) you build in your site .. was ease to do? my friend Sakkoulas people like you make this forum so wonderful and helpful, thank you for all your help!1 point
-
And you can even ditch $news in this bit $news = $pages->find("template=news-item, section={$section}, sort=-news_date, limit=5"); ..... foreach($news as $newsitem) like this... (assuming you've ditched $section as well) foreach($pages->find("template=news-item, section={$page}, sort=-news_date, limit=5") as $newsitem) { //do your stuff } Power of nesting! Recently discovered this. It works a treat. For my testing, I have been leaving both styles in my code, commenting out the first of course, with notes about the second shorter version...for my learning purposes... //Aside: Btw, dear gurus, does the 2nd style affect performance? Other issues? If too long maybe can cause readability issues...1 point
-
You can also ditch the ?>. You don't want any (invisible) characters after the >. I.e. trailing whitespace can lead to "headers already sent" errors. Those are notoriously hard to debug. Another thing you might consider is using a function. This way you can re-use the function in other templates. This might seem trivial or even more work, but in the long run you benefit when you want to change someting. function newsList($newsItems) { if (!count($newsItems)) return "There are no news-items found."; $out = ""; $out .= "<ul class='list'>"; foreach($news as $newsitem) { $out .= "<li class='list-item'>"; $out .= "<section>"; $out .= "<h5><a href='{$newsitem->url}'>{$newsitem->title}</a></h5>"; $out .= "<em>{$newsitem->news_date}</em>"; $out .= "</section>"; $out .= "</li>"; } return $out; } echo newsList($pages->find("template=news-item, section={$page}, sort=-news_date, limit=5")); Written in the browser, so not tested but I think you will get the idea.1 point
-
and aren't you missing the closing </li>; also not sure why you need the section tag within the <li> item, unless you are outputting the full news article text?1 point
-
it doesnt do enything, I'm glad I could help, if it helps i can give you the password for my test page to see by your self the structure but is all in greek in there so... - events <-this is the parent event template, has page url 'events' it doesn't matter what fields you have in there . in this page i have put the code <div class="tab-pane" id="calendary"> <div id='loading' style='display:none'>loading...</div> <div id='calendar' class='calendar-page'></div> </div> all the children pages,of 'events' page are actually the pages that been shown in calendar it doesn't matter what template you use but it must have the fields title body date_start date_end summary headline images1 point
-
I imagine what you want could be archieved nicely by some kind of offline-capable Javascript MVC app built with something like Angular.js, Ember.js, Backbone.js or similiar frameworks. This way you can make it feel very quick and at least do some meaningfull stuff, when the server is offline. You could still use Processwire for managing the data and quickly build a JSON API to communicate with.1 point
-
People might think that $db is just a short for $database. Would it make sense if the new variable would be $pdo instead?1 point
-
Looks good to me. The only feedback I have is that you could ditch the first line and replace $section in the second line with $page.1 point
-
...but here it actually is an array, thus the name . When PHP sees we're dealing with strings the string representation of a variable is used. In this case the trigger is an unescaped dollar sign between double quotation marks, but it could be the concatenation operator '.' as well. To get such a representation, the __toString() method of the class (PageArray in this case) is automagically called. See http://www.php.net/manual/en/language.oop5.magic.php#object.tostring. The __toString() method has been implemented to return a single page id (Page or PageArray with one item) or a list of page id's with a '|' (pipe) as a separator. I was trying to clarify the situation but I'm not sure if that's what happened after all .1 point
-
I defined Textadept as my default editor in the system. I wouldn't really try it if I would always have to choose it from the context menu... I like what I see very much. One thing that put me away in the beginning were the themes, but I found out that although there aren't many themes around, it's very easy to create one. So, that's what I did https://github.com/ocorreiododiogo/diogo-dark-theme1 point
-
Ok, here are the list: AlbumCover-Import is done new field for BPM in Songs is done ImporterScript now asks the user for every Task to enter a yes or no: (done) optionally delete all Pages (reset DB) import Files- and Metadata import AlbumCovers recreate the complete CacheData ImporterScript also ends with a question for 'Enter' to avoid closing the shellwindow (done) ToDo: As of the different CharEncodings with ID3v2.3 and ID3v2.4 (I think these are the two most common today) I have to rewrite the core ID3Tag-Reading. Until now I've used 3.party-code for that, but to play save on a per-file or per-field basis with mixed ID3Tag-Versions it's better to rewrite this. Some minor things here and their After that I can upload a useful SiteProfile.1 point
-
What you've got as a result is a PageArray so you'd need to check the count like this (edit: ..and change find to get as diogo says below): if(count($info) >= 1) { // do stuff } If there are potentially lots of children, it would be better to do it for example like this:$childCount = $pages->count("parent.title=previous caption winners"); if($childCount >= 1) { // do stuff } This way you wont end up fetching all the children just to count them.1 point
-
One thing you could do would be to use PhpMyAdmin (or mysqldump) to export the whole database (or just the relevant field_[name] text field tables) to an SQL/text file. Load it in a quality editor that won't mess it up (like BBEdit/TextWrangler), and let it run a spellcheck. It should red underline everything it thinks is misspelled. It will be simpler to make manual corrections in this one file, and then re-import the whole thing, than to go through it online. As for space fixing, I wouldn't worry about it. Assuming they aren't non-breaking space characters, they will get collapsed down to 1 space in HTML either way. So it doesn't really matter how many spaces one uses after a sentence, because it'll always be displayed as one.1 point
-
Since you are pulling them right out of $_GET (or $input->get), you should filter and sanitize them before doing your http_build_query. $types = array( 'limit' => 0, 'my_string_var' => '', 'my_int_var' => 0, ); $params = array(); foreach($types as $name => $type) { $value = $input->get->$name; if($value === null) continue; // not specified, skip over if(is_string($type)) $params[$name] = $sanitizer->text($value); // sanitize as string else $params[$name] = (int) $value; // sanitizer as int } if(empty($params['limit'])) $params['limit'] = 10; // set a default $new_query_string = http_build_query($params);1 point
-
One way you could do it would be to make the FieldtypeComments::sendNotificationEmail method hookable. If you want to add 3 underscores before that function name (in /wire/modules/Fieldtype/FieldtypeComments.module), I'll make the same change here. From there, it should be hookable. In this case, you'd probably want to override/replace the method completely. To do this, your hook function would populate the $event->replace=true; Using PW 2.3 dev syntax: wire()->addHookBefore('FieldtypeComments::sendNotificationEmail', function(HookEvent $event) { $event->replace = true; $page = $event->arguments(1); $field = $event->arguments(2); $comment = $event->arguments(3); $subject = "New Comment Posted!"; $body = "A new comment was posted to $page->httpUrl by $comment->cite: $comment->text"; mail($field->notificationEmail, $subject, $body); });1 point
-
If($page == $page->parent->last()) $page->parent ->next->child->url Written on mobile. But you get an idea1 point
-
1 point
-
$pages->find("parent.template=news-month-archive"); $page->rootParent->find("parent.template=news-month-archive");1 point
-
Whenever you get that error message, go and enable debug mode in /site/config.php, just so that you can get some more details as to what is happening. Double check that your homepage template has the guest role enabled. No need to sanitize the password btw.1 point
-
Ok, I think I figured out what causes the issue. Seems that the old PHP 5.2.6 on my production server messes up the encryption/hash functions, so the Password::matches() method does not work as expected (on my local machine I have 5.3.5 ...which is rather old, too, as I just realized ). I'll try to udpate the PHP version and check again.1 point
-
Anyway, if you would decide to do that check, you could do it like this: if ($pages->get("parent.name=$input->post->date, name=$input->post->name")->id) // set error to 1 edit: Ryan has some important additions to this on a post bellow1 point
-
I think first one is cleaner, but both of those will fail, if you change your page's parent. You could try this also: $pages->get(1234)->url where 1234 is page id.1 point
-
The result of the find is an array, so you can't get the children of it. If there's only one page with that template you can do: $results = $pages->get("template=news-month-archive")->children("sort=-news_date, limit=10");1 point
-
You could achieve pretty interesting results by taking this idea a bit further: Define areas on front-end where new elements (widgets, nodes, blocks, whatever) can be dropped and create new page fields for each of them, set up a collection of pre-defined blocks (templates, including proper template files for this purpose) you want users to be able to drop in, create a clean way to add new pages / edit existing ones via front-end (edit/add button, something like Fredi), store newly created pages somewhere and attach them to page field on current page automatically. Preferably you would also let the client re-arrange these blocks by dragging on the front-end side, to make it all function properly. Perhaps even drag blocks from one area / column (page field) to another? That's all very much doable, though I would imagine that it could take quite some time to work all the details out (such as where to store those pages to keep things smooth and stuff like that.) I'm definitely not advocating anything like this, based on similar reasons others have stated above (such as the fact that pages created this way usually end up unbelievably messy in the long run and no longer serve any real purpose, other than perhaps making some content editor very proud of herself) -- just saying that ProcessWire can be used for it if it's what makes you happy. If you're into it, why don't you give it a try yourself? See where it takes you and ask if you need any advice Been there, seen both of those happen more than I'd like to remember. For a very long time I believed this to be "the best way" (partly because it worked for us and made our clients very happy), but after listening and seeing all those problems it caused for our clients at the same time, I've come to one conclusion: this model is in reality one of the worst enemies of properly structured, usable and logical web content. It requires serious mental fortitude to keep things in order when you've got all the tools you could ever ask for right within your grasp. This is true especially in the long run.. and especially when there are multitude of editors to deal with. Ever been asked to re-organize a ten year old site for a client, one that's seen hordes of editors, various shifts in content strategy etc.? Not a trivial task and each and every page having a very different structure doesn't really help. It's rare for there to be someone who could keep it all under control either -- that kind of thing is too often limited to huge organizations only and even then resources tend to be scarce. From my point of view the most obvious (even if still only partial) solution for this is a clearly defined structure that editors must stick with, even if it doesn't please them at all times -- which is exactly what ProcessWire provides tools for. Clients may not "get it" at first, but that's why we as designers, developers and professionals should explain and teach them why this is a good thing. I rest my case.1 point
-
Why do "the clients/editors would like to combine them as they wish"? In my experience this is mostly a type of "I need to control" things. There are some exceptions but usually this doesn't benefit the reality (or goal) of a page. Offcourse, regular content like bodytext or images need to be controlled, but in my opinion every type of page has a goal. A designer (UI, UX or visual) determines (offcourse in cooperation with the client) what that goal is. Most of those goals I can be held accountable for since I'm designing or proposing a design to a client. When you give an editor options to create pages as they wish I've seen two scenarios happen: 1. They hardly ever use it (The client is not to blame since they are focussed on other things like running their business) 2. They overuse it (The client is not to blame since they want it "all" and we need to decide what is really important - the goal) It's both a maintance (from client perspective) and a user (the visitor of the site) issue. I always try to make this as clear as I can. That said I realize some content blocks can come in handy but I hardly ever see a proper use of using content blocks/widgets (like WordPress). As always you should test this in reallife scenarios/use cases, but from my experience I've learned that this is hardly ever really needed. I think you should talk about using content dynamically — where ProcessWire is really awesome.1 point
-
I've run into a similar issue on one of my sites that has a lot of accounts to manage. I'm hoping to improve the core modules (ProcessPageType and/or ProcessUser) in this regard whenever there is bandwidth to pursue it.1 point
-
Although I know and sort of understand the wish of clients to be able to do so, from a designer's/developer's point of view, these “free form” content types are not necessarily a good choice. (Disclaimer: This might be a very subjective point of view, and yes, I admit to being kind of a control freak.) I don't know what kinds of clients you guys have, but a lot of my projects are websites for people who don't really know much about building web sites. Those clients can actually benefit from a “rigid” approach because it does not only limit their possibilities, it also limits their margin for error, bad layout choices and basically anything which makes designers pull out their hair, as arrogant as that may sound. Then again, as long as this is implemented as a module or an option, keeping the flexibility we all love about PW, this probably is a “why not?” feature. (Just my 2 cents.)1 point
-
You can use the built in search in the admin. Just make sure to use "name" instead of "title body" in "Search in field(s):"1 point
-
I've got this feeling that hooks debug section is going to be my new best friend. That information could have prevented couple of very nasty situations already. Glad to have it here now, awesome stuff Ryan!1 point
-
1 point
-
A little bit of new fun stuff on the 2.3 dev branch: Anonymous functions and hooks You can now use PHP 5.3+ anonymous functions when attaching hooks. All the syntax below will work either from your template files, modules, or any Wire derived class. If using outside of template files or Wire-derived classes, then replace $this with wire(). Though anywhere that you can use $this you can also use wire(), so syntax is also a matter of preference. Example: Add a "hello()" function to all pages that returns "Hello World!": $this->addHook('Page::hello', function($event) { $event->return = "Hello World!"; }); Result: echo $anyPage->hello(); // outputs: Hello World! Example: Add a 'hi' property to all Users that contains the value "Hi [their name]!". $this->addHookProperty('User::hi', function($event) { $user = $event->object; $event->return = "Hi $user->name!"; }); Result: echo $user->hi; // outputs: Hi Ryan! Example: Add a grandparent() function to all pages. $this->addHook('Page::grandparent', function($event) { $page = $event->object; $event->return = $page->parent->parent; }); Result: $myPage = $pages->get('/about/news/categories/sports/'); echo $myPage->grandparent()->url; // outputs: /about/news/ Example: Save a message to a log file for each new page that is added. $pages->addHookAfter('added', function($event) { $page = $event->arguments(0); $this->message("Added new page: $page->path", true); }); Result: The message is added to log file /site/assets/logs/messages.txt when a new page is added. Example: Add a 'createdString' property to all Page objects that is the same as $page->created except that it outputs in a human readable format rather than a unix timestamp: $this->addHookProperty('Page::createdString', function($event) { $page = $event->object; $event->return = date('Y-m-d H:i:s', $page->created); }); Result: echo $page->createdString; // outputs 2013-04-30 03:05:00 This just touches on the possibilities with some overly simple examples. But you can use these anywhere you'd use any other hooks: from within modules, templates, or anywhere in ProcessWire. I think that the anonymous function syntax is particularly convenient within templates, when you can define your own helper functions in your head.inc or init.php or whatever file you have starting your templates. Don't forget you can add stuff in /site/templates/admin.php too in order to hook into things that happen during administration. Error and message logs ProcessWire has always maintained logs, but I'm guessing that most don't know how to write to them. So I setup a simpler syntax for you to save things to PW's system log files: $this->message("This text will be saved to /site/assets/logs/messages.txt", true); $this->error("This text will be saved to /site/assets/logs/errors.txt", true); This is the same as these functions worked before, except for the second "true" argument, which tells it to write to the log file. From the admin side, it'll still display these messages interactively. If you only want it to log and not display the messages in the admin, then replace the "true" with "Notice::logOnly". Though if you are doing this from templates, then you don't need to consider that since templates (other than the admin template) don't typically output ProcessWire's notices. --- Edit: I changed the wire() syntax in the examples to $this. Though either works from template files and modules, but I think $this syntax is more familiar to most.1 point
-
I don' think it's a good idea to make your site depend of something like this. If something changes with an upgraade, it will break everything.1 point
-
add this in header $(document).ready(function() { $('#calendar').fullCalendar({ header: { left: 'prev,next today', center: 'title', right: 'month,agendaWeek,agendaDay' }, editable: false, events: "json-code.php", eventRender: function(event, element, view ) { if (view.name === "agendaDay") { element.find('.fc-event-title').append("<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(); this in json-code.php 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:s",$event->date_start), 'end' => date("Y-m-d H:i:s",$event->date_end), 'url' => "$event->url", // event ID is the url segment 'description' => "$event->summary", 'allDay' => false, ); return $data; } // end else $calendarPosts=$wire->pages->get('/events/')->children(); echo pagesToJSON($calendarPosts); end in page where you want the calendar, <div class="tab-pane" id="calendary"> <div id='loading' style='display:none'>loading...</div> <div id='calendar' class='calendar-page'></div> </div>1 point
-
Yes, I think that a lot of modules currently in the core should be removed from the core. But we can't just remove modules from the core because that could break someone's site during an upgrade. So it has to be part of a longer plan that involves a custom-download packager (enabling one to download PW with user-chosen modules included), and tied to a major version where users would be expecting something more to an upgrade process. I actually think CKEditor's download packager is a pretty good example of what would work well for us. You can browse their plugin directory and click "add to cart" (or something like that) to add any given plugin to your CKEditor download. Then when you "checkout", you are downloading a CKEditor ZIP with all the plugins you wanted, ready-to-go.1 point
-
OK, it's been a while since I looked at this, and much of it was inspired or guided by Ryan. I had to boil it down a little to make it generic enough to make sense, so this exact code hasn't been tested, but it should get you started. Here's a proof of concept that works. Template for your calendar page <?php 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:s",$event->start_date), 'end' => date("Y-m-d H:i:s",$event->end_date), 'url' => "./$event->id", // event ID is the url segment ); return $data; } if($input->urlSegment1) { // event ID provided as a URL segment to this page $event = $pages->get("id=$input->urlSegment1"); include("./includes/head.inc"); echo $event->title; echo $event->body; include("./includes/footer.inc"); } else if($config->ajax && $input->get->start && $input->get->end) { // fullCalendar making an ajax request of events $start = (int) $input->get->start; $end = (int) $input->get->end; $events = $pages->get("/calendar/")->children("sort=start_date"); $events = pagesToJSON($events); echo $events; } else { //display the calendar $config->scripts->add('/site/templates/assets/js/fullcalendar.min.js'); $config->styles->add('/site/templates/assets/css/fullcalendar.css'); $config->styles->add('/site/templates/assets/css/calendar.css'); $config->scripts->add('/site/templates/assets/js/cal.js'); include("./includes/head.inc");?> <div id="calendar"></div> <? include("./includes/footer.inc"); } // end else ?> head.inc <!DOCTYPE HTML> <html> <head> <title><?=$page->title?></title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- CSS includes defined via $config->styles->add --> <?php foreach($config->styles as $url) echo "<link rel='stylesheet' type='text/css' href='$url' />";?> <!-- include jQuery --> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.3/jquery.min.js" type="text/javascript"></script> <script>!window.jQuery && document.write(unescape('%3Cscript src="/site/templates/assets/js/jquery-1.6.3.min.js"%3E%3C/script%3E'))</script> <!--js includes defined via $config->scripts->add --> <?php foreach($config->scripts as $url) echo "<script type='text/javascript' src='$url'></script>";?> </head> <body> footer.inc </body> </html>1 point
-
That is prettiest and probably most easy to use/browse calendar in long time. Reno is my designer hero for sure!1 point
-
You should also be able to retrieve them via just $field->tags or $template->tags1 point
-
I don't see an easy option to do that, but with a little module you could on each save of a child page update a date field on the parent. Then sort it by that field. Let us know so we can help you get started.1 point
-
It's definitely possible to build some great calendars and calendar functions in ProcessWire, and do so without using any other service. But I also want to mention that something like Google Calendar was built with millions of dollars and years of time, so it would be difficult to match the level of capability there. But if your needs are relatively simple, you can probably make a calendar in PW more easily than anywhere. There is no single way to make a recurring event, so I think your approach would just depend on how you've built the rest of the calendar. But I'm imagining that you would do it with a checkbox field called 'recurring', or 'recurring_weekly' or something like that.1 point
-
I'm working with a events calendar myself, though I elected to take a more service oriented approach using google calendar and outlook generated *.ics feeds. If your calendar is going to be as simple as you describe, you might be able to get away with the following approach. Set up three datetime fields - event_start, event_end, and recurrence_end. Set up a text field, recurrence_rule (rrule). Add the PHP When library to your project. For recurring events, set your rrule based on byweekday, bymonthday, etc. You can generate rrules with a google calendar (add a recurring event and look at the ical feed) if you're new to them. For the range to be displayed (e.g. today + 3 months) you can use the api to get all events that have start/end OR start/end-recurrence overlap with the displayed range. Set up an array and loop the events, using PHP When to generate a list of occurences if an rrule exists, push rule occurences and non-rrule events in as as siblings, sort by event_start/occurence_start. Render the list of occurences. That's the basic formula anyways.. If you are avoiding google only because of the look of thier embeded calendars, you might consider rendering your own calendar of events with PHP When and the raw icalendar (*.ics) feed they provide. Edit: grammar.1 point