Leaderboard
Popular Content
Showing content with the highest reputation on 05/31/2014 in all areas
-
Continuing from my previous post in this thread about some selector enhancements available on the dev branch, we've got a couple more advanced options for use in selectors in case anyone is interested: OR-groups These let you specify multiple expressions and only one of them has to match in order for the selector to match. It's a way of saying "either this has to match OR that has to match". This is useful because selectors always assumed AND – meaning everything has to match. While you have always been able to use the pipe "|" to specify ORs for fields or values or both, the scope of it was just that field=value statement only. Now we have something new called OR-groups. These let you create multiple selector groups and only one of them has to match. You can specify OR-groups by surrounding selectors in parenthesis. An example demonstrates it best. Lets say that we wanted to find all "product" pages that were in stock, and either in a featured date range, or had a highlighted checkbox checked. Previously we would do like this with two separate find operations: $items = $pages->find("template=product, stock>0, featured_from<=today, featured_to>=today"); $items->add($pages->find("template=product, stock>0, highlighted=1")); Now we can do it in one find operation: $items = $pages->find("template=product, stock>0, (featured_from<=today, featured_to>=today), (highlighted=1)"); Above are two selectors surrounded in parenthesis. Only one of them has to match. You can specify as many of them as you want. This type of OR expression is something you couldn't previously do with selectors. Think of the parenthesis as a way of saying "this is optional". But of course, at least one of your parenthesized selectors has to match in order for the full selector to match. I'm guessing the above usage probably covers 99% of the situations where you might need it. But lets say that you want to have different combinations of OR expressions. You can create named groups that OR with each-other by specifying: foo=(selector1), bar=(selector2), foo=(selector3), bar=(selector4) In the above you'd replace "foo" and "bar" with names of your choice. And you'd replace the "selector" with any selector strings. Those foo/bar names aren't referring to fields, instead they are just named groups that you can name however you want. In that selector, at least one of the "foo" named selectors would have to match, and at least one of the "bar" named selectors would have to match. If you didn't use the foo/bar named groups here (but still used the parenthesis), then only one of the 4 selectors would be required to match. Sub-selectors Some of you are already familiar with these because it was committed to the dev branch a couple weeks ago (and I think may have been outlined elsewhere in the forums). Sub-selectors let you put a selector within a selector, enabling you to perform more complex matches that used to require you to use separate API calls. These can be used on the 'id' property of any field that maps to a page. The 'id' property is assumed when referring to a page reference or a parent, so it's not necessary to specify it unless you want to, i.e. "field" and "field.id" mean the same thing in this case. Sub-selectors are specified between [square brackets]. For example, lets say we are matching products and our product template has a "company" page field. Each company also has it's own page field where all the company locations are identified. Lets say we want to find all products that are made by a company that has more than 5 locations and at least one of those locations has "Finland" in the title. Previously we would have had to do it like this: $companies = $pages->find("template=company, locations>5, locations.title%=Finland"); $items = $pages->find("template=product, company=$companies"); That's easy enough. But now it's even simpler, as you can do it in one operation: $items = $pages->find("template=product, company=[locations>5, locations.title%=Finland]"); When you've got a "field=[value]" selector, any properties you refer to in "[value]" assume the "field", so "locations" above is referring to a property of the "company" field.9 points
-
It's more efficient to do it in one find() operation, using the new options available. When using two separate find operations, all the pages from the first find() operation have to be loaded. When you do it in one find(), then those pages don't have to be loaded. So it can actually be a whole lot more efficient, especially if dealing with larger scales. There is still some room for optimization so I'll be working on that, but regardless they should be a lot more efficient than multiple find operations. Another good reason to use OR-groups (and sub-selectors, depending on the case) would be for pagination. You really can't achieve paginated results very easily if splitting into multiple finds.8 points
-
Well, I read through your code a week back but couldn't spot any obvious flaw. Now I had another look and feel like I should've seen it in the first place... Actually you did yourself in the very beginning as you had the very same problem then. You're welcome. And you should still hang on to what you had working . Here's the problem line (core of it anyway): $matches = $all->find("rental_period.date_from>=$df, rental_period.date_to<=$dt, rental_period.booked=0"); As you figured out before (and Ryan confirmed you right), this kind of selector is something to beware of. While all of the three conditions must match, they only have to match the same page (property_availability), not the same repeater item. So this would match any page that has rental_period-repeater with one item matching the condition for date_from, another item matching the condition for date_to and third item matching the condition for booked. All the conditions could have a match in the very same repeater item, but that's not required (and you'd want it to be). That's just the nature of repeaters. Nasty, I know. Take the version with working date ranges and add the capacity and region handling like you have now in the beginning. Then, instead of first finding all cottages matching region and capacity, just go for the repeater items matching the date range like before and modify the match handling like this: foreach($matches as $item) { $property = $item->getForPage(); if(!$property->viewable()) continue; // skip if property is unpublished or something // add this: skip the match if it doesn't match your region or capacity if(!$property->matches($filterSelector)) continue; // now you have the $property and the matching repeater $item $termCottages[] = $item->id; } Here $filterSelector should be empty if no region or capacity has been chosen. Or it could be something like "location=xyz, sleeps>=10" to rule out any cottages not located in xyz or having capacity of less than 10. I haven't tested it but naturally it'll work like a charm . So you were on the right track all along. Just don't go for something that's been proven faulty for this scenario before.4 points
-
So epic It just nickname we have been calling Ryan here at Avoine office. I mentioned that to Ryan and since then it has been his member title. For Finnish people Reiska is quite a traditional nickname and most famous Reiska is indeed Remontti-Reiska, who has been celebrity (also popular among ladies) here for a long time. I agree with Teppo, he represents only the finest values - not anything God like here though, but maybe our dear neighbors at Estonia sees him as a god I'm just giggling here for the idea many people googling and wondering about that strange connection3 points
-
If you want to know what "Reiska" often means here in Finland, Google Remontti-Reiska and you're getting close. Finnish TV star, media personality, self-taught handyman / construction worker, ex-hockey player, ex-bodybuilder, motorist and a huge person (in more than one way), Remontti-Reiska ("Reiska the Handyman") symbolises all that is good and fair in Finland. I'm not 100% sure about this one, but I believe that the term "remontti-reiska", which is often used to describe handymen and like in general, originated from this guys TV show. (There's also a whole series of YouTube videos of his shows, mostly slowed down to make him and the guy helping him seem drunk -- don't worry about those, that's just Finnish Internet humour at it's finest.) Of course there are other interpretations too, but this is the one I prefer. I think @apeisa mentioned something about this at our last ProcessWire meetup, so he'll probably know better3 points
-
Couldn't find any translation for Ryan's member title. What is "Reiska"? Google shows some weird Estonian pages... I guess, it is something like "The god of all heavens" or "Megamacho" in suomi, but i would like to fully understand the title of our "beloved leader and godfather of all wires and processes" .2 points
-
This Module didn't have it's real own thread, now it has Markup RSS Enhanced This Module is the enhanced version of Ryan's Markup RSS Module and is completely compatible with it. In addition, this enhanced module supports the usage of enclosures a way of attaching multimedia content to RSS feeds. Give the RSS enhanced module a PageArray of pages and it will render a RSS feed from it. The Module should be used directly from your template file. In the examples the $rss variable is used for as instance of the module. $rss = $modules->get("MarkupRSSEnhanced"); Basic usage In case you only need 1 feed for your site, you need to setup the defaults in the Modules config. then you can use the code below. $items = $pages->find("limit=10, sort=-modified"); // $items, PageArray of Pages $rss = $modules->get("MarkupRSSEnhanced"); // load the module $rss->render($items); // render the feed Setup channel elements The channel element describes the RSS feed. There are 3 required channel elements: title $rss->title link $rss->url description $rss->description $rss->title = ''; // (string) Title of the feed. $rss->url = ''; // (string) URL of the website this feed lives. Example: http://www.your-domain.com/ $rss->description = ''; // (string) Phrase or sentence describing the channel. $rss->copyright = ''; // (string) Copyright notice for content in the channel. $rss->ttl = ''; // (string/integer) Number of minutes that how long it can be cached. Setup item elements Every page from the PageArray use the item element. $rss->itemTitleField = ''; // Fieldname to get value from $rss->itemDescriptionField = ''; // Fieldname to get value from $rss->itemDescriptionLength = ''; // Default 1024 $rss->itemEnclosureField = ''; // Fieldname to get file/image from $rss->itemDateField = ''; // Fieldname to get data from $rss->itemLinkField = ''; // Fieldname to get URL from or don't set to use $page->httpUrl $rss->itemAuthorField = ''; // If email address is used, itemAuthorElement should be set to author $rss->itemAuthorElement = 'dc:creator' // may be 'dc:creator' or 'author' Item element enclosure RSS enclosures are a way of attaching multimedia content to RSS feeds. All files with proper mime types are supported. If you asign an image field to the itemEnclosureField there are 3 extra options you could set. width The width of the image. height The height of the image. boundingbox Checking boundingbox will scale the image so that the whole image will fit in the specified width & height. This prevents cropping the image $rss->boundingbox = 1 // (integer) 1 or 0, on or off $rss->width = 400; // (integer) Max width of the image, 0 for proportional $rss->height = 300; // (integer) Max height of the image, 0 for proportional Prettify the feed Prettifying the feed is not supported by all clients. $rss->xsl = ''; // path to xls file $rss->css = ''; // path to css Download on GitHub View on the modules directory2 points
-
Nik you are a godsend. you're right and I slap my head for going in circles for so long. I noticed that if(!$property->viewable()) continue; was a filter of sorts already as it removes non-viewable items and I should have clued in that that was where to try to filter results from the other parameters but this line if(!$property->matches($filterSelector)) continue; is something I've never seen before and it works great. I'll remember it. It's gratifying to know that when you reach the limit of your abilities you can still come here and get access to such an enormous well of knowledge and insight. Thank you again.2 points
-
I don't know for sure what Reiska means either, but @apeisa told me that was apparently my Finnish name and that it means something along the lines of handyman. I had a member-title spot open, so I put it there. But if it's translating anywhere as "god of all heavens" or something like that, then I need to change it. I'm okay with being a handyman or somebody that fixes things, but need to change it reads as something egotistical.2 points
-
Hello! About the same time Hari KT asked about "Remember Me" functionality, I identified this as a feature I wanted to implement in some sites under development. Having done this twice before (in CodeIgniter) and based on previous research, I decided to build a ProcessWire module to provide this feature. So far, I have developed and tested this on ProcessWire 2.3. I would welcome any feedback, comments, suggestions and problems from people who are keen to use this. To re-iterate the readme, this module allows users to remain logged in across browser sessions. The module can operate in two ways:Automatically. No code changes, but users do not have a choice. Manually. The module must be called from a site's custom code. Options can be changed in the module configuration page. Enable fingerprinting (IP address and User Agent) as an additional security check. Limit the persistent login functionality by role. Set the name and age of the cookie. Sets an identifier in the session when a user is logged in via a persistent login cookie. This should be used to control access to sensitive information and actions within a site's custom code. Clears login tokens when a potential theft has been identified. Updated: LoginPersist on GitHub1 point
-
The Module Blog for ProcessWire replicates and extends the popular Blog Profile. Blog is now in version 2. Please read the README in the Github link below in its entirety before using this module As of 20 December 2017 ProcessWire versions earlier than 3.x are not supported Blog Documentation is here (Work in Progress!) See this post for new features in version 2 or the readme in GitHub. To upgrade from version 1, see these instructions. ################################################## Most of the text below refers to Blog version 1 (left here for posterity). Blog version 1 consists of two modules: ProcessBlog: Manage Blog in the backend/Admin. MarkupBlog: Display Blog in the frontend. Being a module, Blog can be installed in both fresh and existing sites. Note, however, that presently, ProcessBlog is not compatible with existing installs of the Blog Profile. This is because of various structural and naming differences in respect of Fields, Templates, Template Files and Pages. If there is demand for such compatibility, I will code a separate version for managing Blog Profile installs. In order to use the 'Recent Tweets Widget', you will need to separately install and setup the module 'MarkupTwitterFeed'. Please read the README in the Github link below in its entirety before using this module (especially the bit about the Pages, etc. created by the module). I'll appreciate Beta testers, thanks! Stable release works fine. Download Modules Directory: http://modules.processwire.com/modules/process-blog/ Github: https://github.com/kongondo/Blog You can also install from right within your ProcessWire install. Screenshots (Blog version 1) Video Demos ProcessBlog MarkupBlog Credits Ryan Cramer The Alpha Testers and 'Critics' License GPL21 point
-
new site just launched... http://www.charleswuorinen.com/ major modules that were essential: admin template columns AIOM+ colorpicker (for custom page background colors) Font Awesome Page Label Form Builder ProCache jQuery DataTables Modules Manager Changelog Get Video Thumbs Field Change Notifier Hanna Code Redirects Template Notes Version Control Some custom modules for auto page titles, and custom page for managing works Front end Bootstrap Masonry/Isotope Flexslider dataTables Magnific Popup Soundmanager2 Fresco lighbox html5 video (using jackbox) extensively used Hanna codes to output lists of links, PDFs in various places; hanna code is also outputting the music players, scrolling flexslider galleries etc; the compositions list is using dataTables, and shows extra info in a magnific lightbox, which loads from ajax... once again, a site that really could not have been realized without PW!1 point
-
hello everyone. I was trying Ace Text Editor module on my localhost and its amazing (combined with Images Tags module). it make me want to start a blog again, so I made one (using some domain name generator ). here's the url: http://pixlbendr.com/ Any feedback, comments and critics are highly appreciated. thanks.1 point
-
1.) $var = $page->mytextfield->placeholder 2.) don't know 3.) no, you can't do what you are requesting; if you need that behavior, use repeaters. 4.) you can't, the filenames need to be sanitized, and also they need to be maximally compatible, which is why lowercase and no spaces - also no international characters (though there is still a bug with uploading files that contain characters with accents etc.)1 point
-
Logical thinking has nothing to do with a language. jQuery solves compatibility issues ( can be solved without ). It's more obvious how to use. But requires jQuery & the plug-in to be loaded. ( extra requests ) On the other hand I don't know a project where I don't use jQuery (other people ?) And calling the jQuery plugin is so much easier for your eyes.1 point
-
A tricky part is eventually the behaviour in the dom. IE8 support should be not a real problem. ( only some JS fight over there )1 point
-
Nope, clever ! Do you think a jQuery plugin suits better, basically more like this ? // calling like this $(".adaptive").adaptive({ sizes: { 'tiny': 0, // from 0 till 399 'small': 400, // from 400 till 699 'tablet': 700, 'desktop': 1200 }, delay: 400 }); // or calling like this or something $(".adaptive").adaptive(<?= $wireAdaptiveImage->settings() ?>);1 point
-
Thanks Martijn, I will try out later, or tomorrow. one thing I think it could have is a log which versions it has loaded. Means if it has already a larger version, there is no need to load a smaller one when resizing the window. (assuming it is displayed fluid!) But the decision to load a new one or not cannot depend simply on the direction of window resize, resize smaller = no load | resize larger = load, that's wrong. onload it's medium resize small <= resize large => = only 3. need to load a new image onload it's large resize small <= resize medium => = no need to load a new image, even when window resizes larger Or is this stupid?1 point
-
@Horst, Maybe it's a little bit clumsy but I was playing around with my <div> & <noscript> adaptive image. I don't think it's fully compatible yet with old IE. I just post this as a rough idea. The image: $image = $page->images->first(); //thumbs $tiny = $image->width(100); $small = $image->width(200); $tablet = $image->width(400); $desktop = $image->width(800); // adaptive-image $img .= "<div class='adaptive'>"; $img .= "<img src='data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' "; $img .= "data-tiny='$tiny->url' "; $img .= "data-small='$small->url' "; $img .= "data-tablet='$tablet->url' "; $img .= "data-desktop='$desktop->url' "; $img .= "alt='$desktop->description' "; $img .= "/>"; $img .= "<noscript>"; $img .= "<img src='$desktop->url' alt='$desktop->description' />"; $img .= "</noscript>"; $img .= "</div>"; echo $img; The Javascript: //javascript var adaptive = { /** * The widths should be in an ascending order * Names can be changed but should match the datac attribute * */ sizes: { 'tiny': 0, // from 0 till 399 'small': 400, // from 400 till 699 'tablet': 700, 'desktop': 1200 }, // After window resize delay ( Change if you wish ) delay: 300, // Width of the viewport screen: 0, // Name of the current size sizeName: null, // Timeout for the window resize timeOut: null, // Calculate viewport width calcScreenWidth: function () { adaptive.screen = window.innerWidth > 0 ? window.innerWidth : screen.width; }, // Get the current size name (breakpoint) calcSizeName: function () { for (var sizeName in adaptive.sizes) { if (adaptive.screen > adaptive.sizes[sizeName]) { adaptive.sizeName = sizeName; } } }, init: function () { adaptive.calcScreenWidth(); adaptive.calcSizeName(); var containers = document.getElementsByClassName('adaptive'); for (var container in containers) { var container = containers[container]; var img = container.firstChild; if ( typeof img != 'undefined' ) { img.src = img.getAttribute("data-" + adaptive.sizeName); } } // do it again after resize end window.onresize = function() { window.clearTimeout(adaptive.timeOut); adaptive.timeOut = window.setTimeout(adaptive.init(), adaptive.delay); } } } // DOM ready $(function() { adaptive.init(); });1 point
-
I think so - check out this discussion: https://github.com/ryancramerdesign/ProcessWire/issues/4961 point
-
new german updates for actual PW dev 2.4.3 (31 May 2014). Zip contains only updated/added files (in comparison to the default 2.4 lang pack). updated files: wire--modules--inputfield--inputfieldfile--inputfieldfile-module.json pw-lang-de-dev-update.zip1 point
-
I had to figure this out as well. If you are using the thumbnail module, you won't need to define your width and height as variables in the template. See if this works. Instead of foreach($images as $image) { $thumb = $image->size($thumbWidth, $thumbHeight); try foreach($images as $image) { $thumb = $image->getThumb('thumbnail'); Then your <img src="<?= $thumb->url ?>" should change to <img src="<?= $thumb ?>" That might work.1 point
-
Not sure if there are any instructions posted yet, but if you install the module from the core list, the setup of a new field with this type is well documented. I am sure you'll get the hang of things from playing around for a few minutes. There is some discussion about PageTables from this post onwards: https://processwire.com/talk/topic/6417-processwire-profields-table/?p=628901 point
-
This module might be useful for you: http://modules.processwire.com/modules/batch-child-editor/ Use the Create/Overwrite mode.1 point
-
1 point
-
No need to post in two threads the same question. It has an effect but only for backend and in backend only user language defined in profile is used. The locale is set in LanguageSupport.module init(), and Front-end language is determined in LanguageSupportPageNames.module in ready() which is way later than the locale. I'm not sure it's possible to change that easily as language in backend and it's locale needs to be set early that various parts are translated (at least I think). Language support on front-end works different and is an "after thought" in that it's build with hooks. But maybe some locale setting there in LanguageSupportPageNames would fix it but then we'd have redundant settings. Also setting the locale in the backend has or had various issues with floats and date's as php date strtotime can't handle localized date strings, and floats , or . php also has problems. So I found it's easier and more convenient to set the locale as you did in the template, I use that too. I find it to cumbersome to set locale in a file somewhere hidden.1 point
-
update, so here's a super simple module that is doing this now and seems to be working... (where session_table is the PageTable) (moved revamped code to github..see next post)1 point
-
You might want to check out Login Persistent, perhaps that could be of help here? I've no experience of iOS Web Applications and no idea how they work, so this might be completely unrelated too1 point
-
Ryan's on fire! There's nothing too big missing from the selector engine after this update anymore. But it seems like someone should start a whole new project on testing PW. My old project (on selectors mainly) has fallen way behind and I'm not sure it's a good basis for any broader testing. There's a lot of new stuff in place already and I'm sure there will be much more in the future, along with fixes and optimizations. Regarding selector grouping from a while back: What about repeaters - if I'm not mistaken their not supported? This thread has an example of a situation where grouping would have made things a whole lot easier. And didn't try it out at all but I guess PageTable isn't supported either. I'm happy to ditch the rest of my repeaters if only PageTables would be supported in the future.1 point
-
i was just kidding. Don't know nothing about Estonian gods. As i got it, Reiska is someone like Tim from Home Improvement in US context. Only less funny and more of a jock (if i'm using the word right). Someone who fixes things and looks good doing that.1 point
-
Seems like the main processwire site now uses that engine too: http://processwire.com/apigen/. Maybe old news, but i have not seen a link to that usefull resource anywhere.1 point
-
Maybe I'm old fashion for class names. But I do like the ' ul ul ul ' way Soma suggested. I see a few advantages in doing it the Soma way: Portability ( you don't rely on 'variable' class names, so you could drop that code to an other project without problems ) It's apparent from the CSS how the DOM looks like. It doesn't clutter the DOM with classes as CSS can handle it self on element level. Where I do use classes in menu's is for the last-child. :first-child is widely supported if elements are already in the DOM from the beginning. But :last-child, is only supported from IE9 and up.1 point
-
Loving these additions ryan. One question though - is it more efficient the old way (separate selectors) or the new way? Do these new options make a more efficient DB query (as in one with some joins instead of two in the case of sub selectors) or is there not much in it?1 point
-
yeah, i always need to nag the clients during development to keep their page names consistent with the titles.. maybe a module where you could enable a "development mode" which would prompt the user when changing title if they also want to rename (update slug)... some might even want to leave it on and then rely on the page path history to redirect..1 point
-
$page->numChildren includar.hidden y unpublishado .. alos.s u have $page->numVisibleChildren1 point
-
I actually really agree with you on this being enabled during development - I often change page titles at this time and it can become painful to remember to change the names as well.1 point
-
Thank you! Two pieces of code is much more than i could expect. I will try them out. I am aware of the importance of consistent urls. I want to use that function mostly while developing. The pages get renamed and i want urls to change accordingly. Simply renaming default "about" page requires that.1 point
-
@Horst, I was just thinking loud there, so I don't have a real test case & no js. But I have a site where I swap a transparent pixel, with no fallback if js is disabled. Nothing special there. After you posted your code I instantly thought about a module as the extra markup I don't want to type manually every time. Adaptive images must be easy to use. And should work without Javascript. After That I searched the net for the <picture> element, ( not that I'm keen with those HTML5 tags for those things ) Then the baby starts crying. Will come back to this.1 point
-
Pete, that's a good way to go. With the creation of different sized images, I would do it at uploading images through the images inputfield, the most common way I think. And if someone add images through the API somehow, he simply can add some more line of code to craete the images. It can go like this: public function init() { $this->addHookBefore('InputfieldFile::fileAdded', $this, 'createImages'); } public function createImages($event) { $inputfield = $event->object; if('images' != $inputfield->name) return; // we assume images field !! name of the field is: images !! otherwise change it $p = $inputfield->value['page']; // get the page if('gallery'!=$p->template) return; // don't do it on other pages than galleries $image = $event->argumentsByName("pagefile"); // get the image $image->width(400); $image->width(800); $image->width(1200); $image->size(200, 200); } This hooks into before the image gets added and creates the additional variations. It does not replace the event. After that the admin thumb is created. It is very basic and could be made a bit comfortable with checking the images filedname itself, etc. But it works fine for an individual single site.1 point
-
Comments on/off? Been thinking about a new feature. Ability to turn on/off comments both on a per post basis and on a Blog-wide basis. So, if a post has comments turned off, the user gets the usual 'Comments not allowed for this post' or something similar. Additionally, maybe also a feature to turn-off submitting of new comments on a post when approved comments hit a certain number, say '100'. What do you guys think? Need to think a bit more about how best to implement this...1 point
-
Mr-fan, you're right, the PW Hanna system seems to be very like the "WB-droplets" we are familiar with, coming from WebsiteBaker. There is even an integration with the editor, called HannaCodeHelper. Check it out in the Modules repo.1 point
-
@ozwim - not sure if you already know about this, but i follow Soma's suggestion and have a folder called 'hannas' and then keep all the hanna codes there; and then using this in the hanna code itself: include($config->paths->templates . "hannas/some-hanna-code.php"); @mr-fan - that's great - we should try and setup a place to share hanna codes... maybe github? I have a lot of examples also1 point
-
Update: Blog version 1.1 Read below before updating. For new installs, proceed as normal ------------------------------------- Changelog 1. Added new widget 'Post Author' - @adrian idea, thanks. - This widget allows you to add a post's author's biography with each post. You can add it before or after a post (or wherever you wish). See example in updated 'blog-post.php' example: $blog = $modules->get('MarkupBlog'); echo $blog->postAuthor(); - The widget can be enabled/disabled in the 'Settings' Tab of ProcessBlog. It is enabled by default - Updated the CSS to style the widget Screen 2. Made 'posts truncate length' configurable - @looeee idea, thanks. - This is for when you want to render a 'post summary' - e.g. as seen on /blog/posts/. - Was previously hard-coded to 450. Default is now 450 where no value is specified - Can be configured either on the page /blog/posts/ or 'Settings' Tab of ProcessBlog UPGRADING As I have said previously and repeat here (just in case you missed it ) a module of this kind must not be altering your data if you've already installed it or where there are potential conflicts. Therefore, to upgrade, some manual input is required. Once we hit a lock-down on new features, then this requirement will fizzle out... A. Author Widget 1. This comes with a new template without a template file. - Create a template called 'blog-widget-basic' - Give it a tag 'blog' and a label 'Blog Widget: Basic' //just for consistency with other blog templates - Add the field 'blog_summary' save. Then within the template (i.e. click on the upward arrow of the field), change the description to 'Widget Description' in the modal that opens up. Save... - Still on the edit template view, under the 'Family' tab, specify 'No' under 'May pages using this template have children?' and 'Yes' to 'Can this template be used for new pages?' Save... - Copy over the updated blog.css to /site/templates/css/ (this assumes you haven't made any custom changes to this file!!!) 2. Post Author page - Under /blog/widgets/ create a new page called 'Post Author' and assign it the the above template ('blog-widget-basic') - In the 'Widget Description' field enter a description, e.g. 'Renders Post's author biography.' Save... The Author Widget should then automatically appear under 'Settings' in the Widgets section in ProcessBlog B. Post Excerpt Length 1. Add Field to Template - In the template 'blog-posts', add the field 'blog_quantity'. Save. Change the field's description to 'Posts truncate length'. Save C. Update Blog to version 1.1 In PW, now update the module to version 1.1. This will copy over the new module files (ProcessBlog.module and MarkupBlog.module) and their related files. Note: installer will not run again! So, don't worry All done; now go write a post about how cool ProcessWire is1 point
-
...sorry don't read the whole threat, too short questions about HannaCode: -> Is ther a Overview/Post with contributed examples for "Hannas" -> If yes who can i contribute i've got a few of this little helpers from another system (the CMS Argos and i used and contributed before find PW) there was an Admintool that's called "Droplets". There exists a "Dropletgallery" and we had a WYSIWYG Plugin for choose one for the editor to use. Best Regards mr-fan Example for a "dropletCode" could this used in Hanna as it is or need special threatment or changes... //:genQR creates QR Codes with google Charts API //:Use: [[genQR?size=150&link=http://what-ever.com]] Parameters: $size - default is 200 px $link - default if nothing set is google.com if ( !isset($size) ){ $size = 200; }; $width = $size; $height = $size; if ( !isset($link) ){ $link = "http://google.com"; }; $url = urlencode(".$link."); return "<img src=\"http://chart.googleapis.com/chart?chs={$width}x{$height}&cht=qr&chl=$url\" />"; just for the starting point - i've more like this to share if it's usefull a starting point coudl even be a gist repo?1 point
-
http://www.owengildersleeve.com/ - illustrator (built by CodeByBoy and edited by myself) http://ciaraphelan.com/ - illustrator (built by CodeByBoy and edited by myself) http://thehackneypeddler.co.uk/ - vintage bike shop (built myself)1 point
-
Table Use this for tabular data, like rate tables or other things that you might typically represent in a spreadsheet. Use it for situations where you don't need the full-blown flexibility of repeaters, as it's technically more efficient with far less overhead than repeaters. Something like the Events Fieldtype could be very easily re-created via a Table field, but the potential uses are far broader. But for the most part, think tabular data when it comes to the Table field. Multipliers This is good for when you need a range of values (whether text, textarea, numbers, dates, etc.). If you are using repeaters with just one field in them, you might be a lot better off with a Multiplier. Like the Table field, Multipliers are very efficient and low overhead relative to something like Repeaters. Use Multipliers when you need to repeat a single input multiple times, optionally with a min and max number of inputs. Lets say you are building an employee directory, and each employee has between 1 and 3 email addresses. Rather than using 3 separate email fields, you would use 1 multiplier field and specify min=1 and max=3. Repeaters These are infinitely flexible in terms of what they represent, but each row of values is technically a page in the system. As a result, with the flexibility comes significant overhead. This is really only an issue when the quantity of repeater items gets high, or when you have lots (thousands) of pages using repeaters. I recommend repeaters for setting up things like homepage carousels. For example, if you go to the Villas of Distinction homepage, there are 3 separate repeaters in use on that page, each holding a photo, title, description, link. The client can have as many items in each of those sections as they want. Currently it looks like the first repeater as 6 items, the 2nd has 2, and the 3rd has 6. The possibilities of what can be represented with repeaters is endless, but look for potential alternatives when dealing with large quantities (whether large quantities of repeater items, or large quantities of pages using repeaters). PageTable This is one of the ProFields that is available for free (thanks to Avoine sponsorship) on the ProcessWire dev branch. Meaning, it'll be available for everyone to use as part of the core in ProcessWire 2.5. And you can use it now if you don't mind running the dev branch. PageTable has all the flexibility of repeaters, but with lower overhead from the admin/input perspective. Rather than trying to bundle all the inputs on one screen, PageTable shows you a table of items and you click on the item to edit it in a modal window. This enables it to be a lot more efficient from the admin UI perspective. It's also more flexible than repeaters are in terms of where you store your items. PageTable lets you choose where they should live, whether as children of the page being edited, or as children of some other parent page you designate. They might be a little more work to setup than repeaters, but I think that most situations where you need the flexibility of repeaters may be better served by PageTable. PageTable still can't compete with the speed and efficiency of Table or Multiplier, but consider using PageTable anywhere that you might have used Repeaters before. Repeaters and PageTable are fundamentally different from the admin UI/input perspective, so you'd want to compare them yourself to see what suits your individual input needs better. PageTable involves more clicking to create and edit items, making Repeaters potentially faster for entering data rapidly. But PageTable will scale much further in the admin UI than Repeaters will, so I would personally favor PageTable in more situations than Repeaters.1 point
-
A few new/minor additions on the dev branch: You can now paginate with "limit=1" selectors. Previously ProcessWire didn't build the pagination information when a limit of 1 was specified. Now it does. ProcessWire now preloads pages that it knows it's going to need on every request. This speeds up everything slightly, as what was previously done in 6-7 queries is now done in one shot. Should you want to, you can also specify additional preloaded pages, though I don't think many (any?) would need to. Several optimizations to the PageFinder engine which improves the speed of certain types of queries. One of them is a $pages->count("selector") query, which is now even faster than before. Selector Grouping Added support for selector grouping to change the behavior of how they match. This is best explained by example. Lets say we're building a big news site, and we have a template called news-item that represents each news article. Each news-item page has a field called cats that is a multi-page reference to one or more category pages. This is a pretty common scenario in ProcessWire. The site has a lot of categories, so want to designate some categories as featured so that we can display featured categories on the homepage and elsewhere, with accompanying news items. Rather than just adding a featured checkbox, we add two fields to represent the date range that we want them featured: featured_from and featured_to. On our homepage, we want to display articles from all the current featured categories, so we build a selector like this: $items = $pages->find("cats.featured_from<today, cats.featured_to>=today, sort=-date"); ...but we end up with more news-items than we expect, including some that have categories that aren't actually featured right now. Why? Because each news-item can have multiple categories, and that selector above is saying this: The keywords there are "at least one", as "categories.featured_from" and "categories.featured_to" may not be referring to the same category. The only way to solve it was this: $categories = $pages->find("template=category, featured_from<today, featured_to>=today"); $items = $pages->find("categories=$categories, sort=-date"); That's easy enough... but now you can also do it like this, by prepending an @ to identify a group: $items = $pages->find("@cats.featured_from<today, @cats.featured_to>=today, sort=-date"); The "@" symbol at the beginning of "cats" is telling ProcessWire those are grouped together and "these must match the same exact page". This was added because there are situations where you need to perform your query with 1 selector rather than breaking it up. An example would be when used with the new InputfieldSelector module and Lister, among others. We will likely be adding more ways to perform complex matching scenarios with a single selector as well. Currently this "@" grouping applies only to multi-page reference fields, as I'm not sure yet where else it might be useful. It is only supported by selectors that hit the database at present (though will be completing it for in memory selectors as well). Not planning to extend it into that area at this time, but good ideas to think about for the future or for modules. It should already be fixed. If we're talking about the same thing, someone recently posted this to the GitHub issues list and I added their fix on dev. Adrian already knows this because we've been chatting in the GitHub issues queue, but for anyone else reading this, it has also been fixed.1 point
-
Hey reno, You can set your defaults like this. Just put it before your init(): protected static $configDefaults = array( "defaultSelector" => "default value here" ); /** * Data as used by the get/set functions * */ protected $data = array(); Add this line to your inputfield: $field->attr('value', $data["defaultSelector"]); And add the following at the top of your static public function getModuleConfigInputfields(array $data) {: foreach(self::$configDefaults as $key => $value) { if(!isset($data[$key]) || $data[$key]=='') $data[$key] = $value; } You can then access this throughout your module using: $this->defaultSelector; At least that is how I have been doing it - maybe someone else has something cleaner Does that make sense? PS, Sorry for all the consecutive edits. I really shouldn't try to offer device when I am busy with other things and rushing EDIT Again - I just read that tutorial you pointed to and I see if uses: public function __construct() to set the default values. I haven't used that before. I guess I started by copying from other modules and never came across that approach. I guess there are a few different options, but construct does seem cleaner.1 point
-
My solution, which works nicely: I put the following code on the top of my template. (example for French as default, German and English) $date_lang = array(); switch ($user->language->name) { case 'en': setlocale(LC_ALL, 'en_GB'); $date_lang[0] = "%A %B %eth %Y at %I:%M %p"; $date_lang[1] = "%B %eth %Y"; $date_lang[2] = "%I:%M %p"; $date_lang[3] = "%A"; break; case 'fr': setlocale(LC_ALL, 'fr_FR'); $date_lang[0] = "%A %e %B %Y à %kh%M"; $date_lang[1] = "%e %B %Y"; $date_lang[2] = "%kh%M"; $date_lang[3] = "%A"; break; case 'de': setlocale(LC_ALL, 'de_DE'); $date_lang[0] = "%A, den %e. %B %Y um %k.%Mh"; $date_lang[1] = "%e. %B %Y"; $date_lang[2] = "%k.%Mh"; $date_lang[3] = "%A"; break; default: setlocale(LC_ALL, 'fr_FR'); $date_lang[0] = "%A %e %B %Y à %kh%M"; $date_lang[1] = "%e %B %Y"; $date_lang[2] = "%kh%M"; $date_lang[3] = "%A"; } Then I created a page field, where I store a date unformatted (go to setup->fields->mydatefield->details-> date output format ->"None"). getUnformatted() is only needed, if the date is stored formatted. Finally I can insert the date like echo strftime($date_lang[0], $mydatefield); /* output(de): Freitag, den 11. Oktober 2013 um 12.52h * output(fr): Vendredi 11 octobre 2013 à 12h46 * output(en): Friday October 11th 2013 at 12:46 pm */ echo strftime($date_lang[1], $mydatefield); /* output(de): 11. Oktober 2013 * output(fr): 11 octobre 2013 * output(en): October 11th 2013 */ echo strftime($date_lang[2], $mydatefield); /* output(de): 12.52h * output(fr): 12h52 * output(en): 12:52 pm */ echo strftime($date_lang[3], $mydatefield()); /* output(de): Freitag * output(fr): Vendredi * output(en): Friday */ Maybe you have to check out which string in setlocale is working on your Server. Try different: setlocale(LC_ALL, array('fi_FI.UTF-8','fi_FI@euro','fi_FI','finnish')); //put out the first supported string echo setlocale(LC_ALL, 0);1 point
-
First run this on your server: <?php echo '<hr>test WINDOWS server for locales'; /* try different possible locale names for english GB as of PHP 4.3.0 */ echo '<p>'; $loc_en = setlocale(LC_ALL, 'english_gbr', 'english_britain', 'english_england', 'english_great britain', 'english_uk', 'english_united kingdom', 'english_united-kingdom'); echo "Preferred locale for english GB on this system is '$loc_en'"; echo '<br/>' . strftime("%A %d %B %Y", mktime(0, 0, 0, 12, 22, 1978)); /* try different possible locale names for english USA as of PHP 4.3.0 */ echo '<p>'; $loc_enusa = setlocale(LC_ALL, 'english_usa', 'english_america', 'english_united states', 'english_united-states', 'english_us'); echo "Preferred locale for english USA on this system is '$loc_enusa'"; echo '<br/>' . strftime("%A %d %B %Y", mktime(0, 0, 0, 12, 22, 1978)); /* try different possible locale names for german as of PHP 4.3.0 */ echo '<p>'; $loc_de = setlocale(LC_ALL, 'de_DE@euro', 'de_DE', 'deu_deu'); echo "Preferred locale for german on this system is '$loc_de'"; echo '<br/>' . strftime("%A %d %B %Y", mktime(0, 0, 0, 12, 22, 1978)); /* try different possible locale names for spanish as of PHP 4.3.0 */ echo '<p>'; $loc_es = setlocale(LC_ALL, 'esp_esp', 'esp_spain', 'spanish_esp', 'spanish_spain'); echo "Preferred locale for spanish on this system is '$loc_es'"; echo '<br/>' . strftime("%A %d %B %Y", mktime(0, 0, 0, 12, 22, 1978)); /* try different possible locale names for dutch as of PHP 4.3.0 */ echo '<p>'; $loc_nl = setlocale(LC_ALL, 'nld_nld'); echo "Preferred locale for dutch on this system is '$loc_nl'"; echo '<br/>' . strftime("%A %d %B %Y", mktime(0, 0, 0, 12, 22, 1978)); ?> It will show you what setlocale setting your server accepts. I had to use "swedish_sweden" on my local xampp server and "sv_SE" on the live server. In your config.php put this: $config->timezone = 'Europe/Stockholm'; setlocale(LC_ALL, 'sv_SE'); Modify to your needs of course. And finally use this to output the date: <?php echo strftime("%e %B %Y", $page->getUnformatted("date"));?> Hope this helps!1 point