Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/01/2013 in all areas

  1. I just updated the sheet to 0.3 with hooks from latest dev version. + 22 hooks registered. - added teppo's article to info section links (http://www.flamingruby.com/blog/using-hooks-to-alter-default-behavior-of-processwire/) - added link to ryan's tutorial using hook to add method to PageArray (http://processwire.com/talk/topic/4834-simple-hooks-tutorial-turn-a-pagearray-into-a-list-of-links/)
    5 points
  2. I'm actually adding this to the ProcessPageEditImageSelect module configuration just to avoid having to update two modules for this, as well as to minimize the configuration options in the Setup > Fields > field screen, as I'm guessing this option isn't needed by most. I've already put it in place, so will test here and then commit soon.
    4 points
  3. I have been testing with this method all night! This is great, the approach is so clean once we understand it. Thanks
    3 points
  4. Hi Gespinha, ProcessWire is trying to tell you that "projects" is not a valid selector. See http://processwire.com/api/selectors/ on how to write selectors, this being the key here: "An individual selector consists of three parts: the field you are looking for, an operator (like an equals '=' sign), and the value you want to match. For example, a basic selector might be: title=products". So you could use for example "name=products". But just fixing the selector is not enough here; you're using find() which returns a PageArray (even if there's just one match), not a single Page. If you're trying to get a specific page, you could use get() instead. It works like find() but returns only the first match (a Page object). Or you could say find()->first()->url to access the first found Page inside the returned PageArray.
    3 points
  5. I know it might seem confusing and unintuitive at first, but this is the PW way and I am certain you'll be convinced of the value of the approach in time. Here is some more reading on page fields: http://wiki.processwire.com/index.php/Page_Field Have a read of this thread from here on: http://processwire.com/talk/topic/201-fieldtype-select-aka-drop-down/?p=13637 We have all struggled with what seems overly complicated, but it really does work and it works well! Page fields reference child pages, but they are used as a way to allow the user to select from these items (pages) using select, multiselect, radio etc. Try not to think of pages as just being pages - they are used for everything in PW. Maybe someone else will chime in and be better able to explain how it all works, but I would say just dive in and try it - it will soon make sense once you have tried it.
    3 points
  6. In this tutorial we make a simple function that becomes part of every PageArray. Once hooked to the PageArray class, you can call this function from anything returned from $pages->find(), $page->children(), or your own page references like $page->categories from the blog profile, etc. It essentially becomes a new function available to you from any PageArray anywhere in your site. First, lets look at what convenience the hook function adds and how we might use it. We'll call the hook function "renderLinks", but you could of course call it whatever you wanted. We call that renderLinks() function from any PageArray, and it returns a string representing that PageArray as a list of links. By default, this renderLinks() functions separates each page with a comma, and outputs the page's title as the anchor text. We can change that to be anything by specifying arguments to the call. The first argument is the delimiter, which defaults to a comma ", " if not specified. The second argument is the name of the field to output, which defaults to "title" if not specified. Next are 3 examples of how this renderLinks hook function could be used. Usage Examples: Example 1: render a comma-separated list of links: echo $pages->find("parent=/")->renderLinks(); Output: <a href='/about/'>About Us</a>, <a href='/contact/'>Contact Us</a>, <a href='/site-map/'>Site Map</a> Example 2: render a <ul> of $categories links: <ul> <li> <?php echo $page->categories->renderLinks('</li><li>', 'title'); ?> </li> </ul> Output: <ul> <li><a href='/categories/category1/'>Category 1</a></li> <li><a href='/categories/category2/'>Category 2</a></li> <li><a href='/categories/category3/'>Category 3</a></li> </ul> Example 3: render a breadcrumb trail: <p class='breadcrumbs'> <?= $page->parents->renderLinks(' / ') ?> </p> Output: <p class='breadcrumbs'> <a href='/parent1/'>Parent 1</a> / <a href='/parent1/parent2/'>Parent 2</a> / <a href='/parent1/parent2/parent3/'>Parent 3</a> </p> Those examples above show some of the potential of how you might use such a function. Next is the hook function itself. In order to be available to all templates in your site, it needs to be defined somewhere consistent that is always loaded... Where to put the hook function: If using the basic profile (that comes with ProcessWire) you could put the hook function at the top of your /site/templates/head.inc file. If using the Foundation or Skyscrapers profile, you could put the hook function in your /site/templates/_init.php file. This is the method that I use. If using something else, you could create a /site/templates/_init.php file with your hook function(s) in it, and then edit your /site/config.php to point to it with the $config->prependTemplateFile = '_init.php'; so that it is automatically loaded on every request. Note that the name "_init.php" is not required, you can name it whatever you want. You could put it in an autoload module... but that might be overkill here. The actual hook function: wire()->addHook("PageArray::renderLinks", function(HookEvent $event) { // first argument is the delimiter - what separates each link (default=comma) $delimiter = $event->arguments(0); if(empty($delimiter)) $delimiter = ", "; // second argument is the property to render from each $page (default=title) $property = $event->arguments(1); if(empty($property)) $property = "title"; // $out contains the output this function returns $out = ''; // loop through each item in the PageArray and render the links foreach($event->object as $page) { $value = $page->get($property); if(!strlen($value)) continue; // skip empty values if(strlen($out)) $out .= $delimiter; if($page->viewable()) { // if page is viewable, make it a link $out .= "<a href='$page->url'>$value</a>"; } else { // if page is not viewable, just display the value $out .= $value; } } // populate the return value $event->return = $out; }); If using PHP before 5.3, or using an older version of ProcessWire, you'll need to change the first line to this (below). This syntax also works with newer versions as well, but it's not as pretty as the new syntax. wire()->addHook("PageArray::renderLinks", null, 'hookRenderLinks'); function hookRenderLinks(HookEvent $event) {
    2 points
  7. Hi all, we lauched this big website for a festival last week, and pout a lot of work and love into this. Check out: boomfestival.org Hope you like it! and it has been received very well so far.. ( 60 000 visits in less then 1 week) It uses processwire as CMS , and I must say awesome decision to replace Wordpress we used the last editions, processwire is highly superior to wordpress as CMS . I even managed to import a lot of content from Wordpress with the Processwire bootstrap API and JSON and the help of this forum Content is loaded all with Ajax , and still backbutton does work and everything can be deeplinked . Ryan ProCache module has helped very much with Site speed and our high traffic server load If I find the time I might do a case study here...as this ajax approach moight be interesting for other developers
    2 points
  8. I know the bulk of you are coders and likely can figure this out on your own but for those who are not, I thought I'd throw this solution in here just in case someone else has a need for it. I created a simple widget-google-plus.php file for those who want to add a Google Plus widget to their sidebar (or elsewhere) in Processwire. To use, simply upload the attached widget, changing the profile URL to yours and add the CSS / tweak as needed. I've no clue how to build a module so I am doing this as a tutorial. First the logic: If you are anything like me, you crave customization. I hated the fact that Google wouldn't let me remove the border from around their google plus badge so I decided to create a solution of my own. Here's how it looks straight from Google: To get rid of this obnoxious border, I created a new widget (attached) with this code: <div id="googleplus_widget"> <span> <div class="g-plus" data-width="275" data-height="69" data-theme="light" data-href="https://plus.google.com/your-profile-id-goes-here"></div> <script type="text/javascript"> (function() { var po = document.createElement('script'); po.type = 'text/javascript'; po.async = true; po.src = 'https://apis.google.com/js/plusone.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); </script> </span> </div> As you can see, it's wrapped in divs which I then styled with the following CSS: #googleplus_widget{ width: 280px; height: 50px; } #googleplus_widget span{ width: 200px; height: 50px; float: left; overflow: hidden; background: #fff; } #googleplus_widget span div{ margin: -1px 0 0 -1px !important; position: relative; } To use, simply modify the attached widget-google-plus.php with your google plus profile URL, upload to your ProcessWire installations /site/templates directory and go to Setup and then Templates within the back end of your install. The new widget php file should show up under the "Templates found in /site/templates/*.php" , check it off, click add template and then add it to your sidebar if you choose to do so. That's it. Hope that helps someone. I know it's a minor contribution but at the very least, this is recorded for me to reference later when / if I forget BTW. If there's an easy way to make this into a module, I'd love to be able to do so even if just for myself and future newbs. widget-google-plus.php
    2 points
  9. http://www.tamperemusicfestivals.fi/jazz/ The four-day jazz festival starts today. There will be a lot of traffic on the website, but I'm sure everything will run smoothly since ProCache makes the site run very lightweight and fast. In previous years this website has been running on WordPress or MODX. This year we switched to ProcessWire, and it has been a huge improvement. Everything on the site is fully editable, which makes the client very satisfied. Also, PW has revolutionized my workflow as well. I have quite the same feeling as when I switched from Windows to OS X : ) Logo is designed by the artistic director of the festival, everything else by me.
    2 points
  10. I've updated this module to support the new admin theme. It just required a few changes to the VersionControlForTextFields.js file (I had to rename it to .txt because the forum won't accept a .js attachment). It should support both new and old admin theme. But I'm posting here rather than doing a pull request because I haven't had time to adequately test it beyond my own environments where I'm using it. Teppo: I've also attached a patch/diff. rc-patch.txt VersionControlForTextFields.js.txt
    2 points
  11. Not currently, but if there's enough demand for it perhaps we could add a checkbox to the FieldtypeImage field settings that amounts to the effect of "prevent this field from being used in textarea fields".
    2 points
  12. Thanks for the reverse honeypot method! I'm now using both a regular honeypot (don't fill the field) and your reverse method in all my input forms. I can also recommend adding simple logging to see if it works or not. if ($honeypot == 1 || $securityfield != 1) { $log = new FileLog($config->paths->logs . 'detectedspam.txt'); $log->save('Spam catched: '.$sanitizer->textarea($input->post->body)); $session->redirect($config->urls->root); exit(); } 30 seconds after I implemented this, I got a spam message logged. urgh.. bitter sweet feeling..
    2 points
  13. To create a sitemap.xml you can use Pete's Sitemap XML module, or you can create a template file and page to do it for you. This post explains how to create a template to do it for you. The benefit here is that you may find it simpler to tweak a template file than a module, though either is a good solution. Here is how to do it with a template file and a page: sitemap-xml.php <?php namespace ProcessWire; /** * ProcessWire Template to power a sitemap.xml * * 1. Copy this file to /site/templates/sitemap-xml.php * 2. Add the new template from the admin. * Under the "URLs" section, set it to NOT use trailing slashes. * 3. Create a new page at the root level, use your sitemap-xml template * and name the page "sitemap.xml". * * Note: hidden pages (and their children) are excluded from the sitemap. * If you have hidden pages that you want to be included, you can do so * by specifying the ID or path to them in an array sent to the * renderSiteMapXML() method at the bottom of this file. For instance: * * echo renderSiteMapXML(array('/hidden/page/', '/another/hidden/page/')); * */ function renderSitemapPage(Page $page) { return "\n<url>" . "\n\t<loc>" . $page->httpUrl . "</loc>" . "\n\t<lastmod>" . date("Y-m-d", $page->modified) . "</lastmod>" . "\n</url>"; } function renderSitemapChildren(Page $page) { $out = ''; $newParents = new PageArray(); $children = $page->children; foreach($children as $child) { $out .= renderSitemapPage($child); if($child->numChildren) $newParents->add($child); else wire('pages')->uncache($child); } foreach($newParents as $newParent) { $out .= renderSitemapChildren($newParent); wire('pages')->uncache($newParent); } return $out; } function renderSitemapXML(array $paths = array()) { $out = '<?xml version="1.0" encoding="UTF-8"?>' . "\n" . '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">'; array_unshift($paths, '/'); // prepend homepage foreach($paths as $path) { $page = wire('pages')->get($path); if(!$page->id) continue; $out .= renderSitemapPage($page); if($page->numChildren) $out .= renderSitemapChildren($page); } $out .= "\n</urlset>"; return $out; } header("Content-Type: text/xml"); echo renderSitemapXML(); // If you want to include other hidden pages: // echo renderSitemapXML(array('/path/to/hidden/page/'));
    1 point
  14. Hey, The Form API has CSRF protection build in, but if you for some reason don't want to use the API you can however use the CSRF protection. Its very simple but it took some time for me to find out, so i figured i share my findings with the rest. What is CSRF? First you need to create a token and a token name you do that as following: $tokenName = $this->session->CSRF->getTokenName(); $tokenValue = $this->session->CSRF->getTokenValue(); Very simple. Now what you want to do is create a hidden input field like this: $html .= '<input type="hidden" id="_post_token" name="' . $tokenName . '" value="' . $tokenValue . '"/>'; Now this will generate something that will look like this: You are done on the form side. You can now go to the part where you are receiving the post. Then use: $session->CSRF->validate(); This will return true (1) on a valid request and an exception on a bad request. You can test this out to open up your Firebug/Chrome debug console and change the value of the textbox to something else. Basicly what this does is set a session variable with a name (getTokenName) and gives it a hashed value. If a request has a token in it it has to have the same value or it is not send from the correct form. Well I hope I helped someone.
    1 point
  15. Hi i would like to share with you guys, a website i made thx to Processwire. Im super happy with processwire and this community. Ty for help everyone. here is the site: chemik-police.com
    1 point
  16. Chinese Language Packs. note: The TinyMCE works in English, because I can't set the language code to zh-CN. click this link for detail. http://processwire.com/talk/topic/4803-i-want-translate-pw-to-chinese-and-need-support/ you can download this pack from github too. https://github.com/liyiwu/Chinese-ProcessWire update: cd wire grep -Rl '[>_][_nx](' * | uniq I find 90 files, and translate all of them that is translatable. Hope this can help others. Chinese-ProcessWire.zip
    1 point
  17. I have two image type fields in my template. One is used to upload images to be used for a slideshow on the page the other is general images that a user can embed into the page content using TinyMCE. I'd like only the general images to be available in TinyMCE when you click on the image toolbar icon. Is there anyway to limit the popup image selection dialog to just one of the two fields?
    1 point
  18. Hi guys, i finally finished my personal website. PW and jQuery as always and Bootstrap as css framework. English version coming soon... http://complementaryart.com
    1 point
  19. Hey folks, just found etherpad lite and I'm quite liking what I'm seeing. It's a live document collaboration tool and Mozilla has a server up and running where you can start public or 'team' documents you want to work on with others. I've just started one here to play with and invite you to join in and try it out. I wonder if this might be a way that we, as a community, might be able to work on documents for the wiki or something? Anyway, give it a try and see what you think.
    1 point
  20. Okay that makes sense. We entity encode everything coming from the translation functions for security. I believe that htmlspecialchars/htmlentities have a boolean argument that when 'true' can tell it to not double-encode. But for a quick solution in your case, you could update that line in your module to this (below), and I'll update the ProcessModule to have that boolean argument. 'summary' => html_entity_decode(__('Here comes the text')),
    1 point
  21. Take a look at this video for an explanation of how page fields work: http://processwire.com/videos/page-fieldtype/ They can be a little tedious to set up, but they are so very powerful compared to the way most CMSs handle storing content for select/radio etc fields that they are more than worth the effort. That module I pointed you to can make the entire process much quicker though - give it a try
    1 point
  22. This one is solved as far as the 404 - i just received a reply from the hosting people: I confirmed that those were blocked by our mod_security rules. still would be good to figure out about sanitizing keywords fields the correct way...
    1 point
  23. In the admin or a front-end form? In the admin you need to use the page fieldtype and then on the details tab choose single and on the input tab choose Radios in the input field type section. The page field select creator module can make this setup much easier: http://modules.processwire.com/modules/process-page-field-select-creator/ If you are after the radio buttons in a front end form instead, let us know and we'll show you through that.
    1 point
  24. thanks to everybody who replied so far. i get a better understanding now. very helpful indeed. in particular thanks to matthew and mademyday for your profound insights. not yet. the project is at a very early stage. but unfortunately the project lead, the person that engaged me, made some determinations before they got me on board. one of this determinations are the joomla orientated coders. my advise to her was to set up information architecture first and to make a list of features required and then to decide which cms fits best - as it would be natural to all of us. if you don't mind i'll get back with more detailed questions once the concept has evolved and it comes to decision making.
    1 point
  25. The answer is relatively simple and there would be different ways but best would be to: In a autoload module (HelloWorld.module) add the hook to ready() where the page being rendered is already set in $this->page So this would only add property to basic-page templates: public function ready(){ if($this->page->template == "basic-page"){ $this->page->addHookProperty('hello', $this, 'helloHook'); } } public function helloHook(HookEvent $event){ $event->return = "Hello World"; } After all I'm not sure this would make a lot of difference to just add it pages globally. But I could see this being useful for certain situations.
    1 point
  26. You can add hooks in the template files themselves. Here is a great post about hooks by teppo: http://www.flamingruby.com/blog/using-hooks-to-alter-default-behavior-of-processwire/
    1 point
  27. joomla really is a dead end.. spent a large part of the last year converting joomla sites to processwire; IMHO i wouldn't start anything new with that, especially with all of the other options out there now. I still have a few sites that are stuck in Joomla 1.5, because of certain components that are being used which are no longer being developed and the functionality that those offer is too complicated/expensive to replicate in processwire. Echoing what Matthew said, the whole template override thing can get incredibly frustrating; as i mentioned in this post: http://processwire.com/talk/topic/3671-ohmspeakercom/?p=35862 , we started that project in Joomla and spent about 1 year (on and off) trying to get it right, and in the end it proved easier to just start over with PW. I recall spending hours writing CSS to get things to go where i wanted them, overriding the joomla classes output for modules.... aargh!
    1 point
  28. Just. Don't. Use. It. Seriously: I worked with Joomla exclusively a while ago (around 2004/2005) and the whole concept hasn't changed imho. The main problem is: It is by no means a flexible content management system, it is more a portal system. Let me explain what I mean: Let's say you have a large scale company with 1000 employees. All of those employess have a name, an email, a title and a linked department. You want to display one/several employees on each page in a kind of sidebar. The PW way: - Create a employees template - Add desired fields - Create page field in your other templates for selecting employees - You are then totally free to select employees in your template and you are able to output what you like (HTML, CSS). - You also have the possibility to use that information somewhere else because these are just usual PW fields. - An editor selects the employee(s) where it is needed: While editing the page The Joomla way: - Look if a module exists for that does this job for you (perhaps there is one, but probably not). - even if there is one you have to add your employees in some kind of extra database, where you are tied to the output of the module (not necessarily, perhaps the script kid lets you customize it). - But the biggest problem: Your editor will not be able to select the employees where it is needed. They have to go the modules section in the backend, have to find the module, have to identify the page they want to edit and then have the possibility to select an employee. This is a ridiculous workflow, image you have not only an employee to select but also header images, other side information and so on. The rest of Joomla can be summed up: - Bloated - poor security - inflexible - poor templating Joomla totally is okay for smaller groups, clubs or where ever no technical experience is needed and where the requirements are low. Everyone can set up a site really fast and choose from a lot of plugins (mostly poorly coded though). But when it comes to comfort, flexibility for editors... it is just poor.
    1 point
  29. There is a great post (I think of Matthew's somewhere) where he goes on a big rant about Joomla, that would be a good a start. No custom fields Very poor security track record Bloated code Nightmare to template with
    1 point
  30. I don't think this is possible, but just in case you are not aware, you can limit the available templates to makes things simpler. I pretty much never give the user the ability to choose the template by making sure that only one option is available by using the template access and family settings.
    1 point
  31. Hey guys, The company I'm working for has launched two new pw's recently built with my Spex module, and there are more coming! http://www.deluca.ca/ http://alpine-animal.net/
    1 point
  32. I don't know what the general stand is on this, but for me, I really like how in WordPress scripts and styles can be queued, and in the header and footer (via wp_head() and wp_footer() respectively) they are loaded with their dependencies sorted out. Then, anytime before the template is output, you can do a call to: wp_enqueue_script('script-name-id', '/url/to/script.js', array('dependency-script-id', 'jquery'), "version", true); and you can be sure that the script will be loaded AFTER "dependency.js" and "jquery.js" has been loaded. And oh, the last parameter specifies whether the script should be loaded in the <head> or in the footer (or wherever wp_footer() is in the theme). Now, I understand for many situations, this may seem like overkill especially if you are loading the same scripts/styles on all the pages. But there are situations where you need a script only for *that* page and don't want it loading on all other pages. if you're using only one view template to output your pages, then that means you'll need to create another view template which includes the specific script/style on this page.
    1 point
  33. So far I know this is not possible. But I love to have this to. ( It's something for the wish list I think )
    1 point
  34. Just finished our companies new website build with Processwire. Main site: http://www.agrio.nl/ A few branding pages: http://www.vee-en-gewas.nl/ http://www.melkvee-magazine.nl/ http://www.agriomediaplanner.nl/ fully responsive pro-cached several "one page" pages for each section / brand unique structure with templates as building blocks Our companies home page structure is shown in the attached screenshot. It contains several templates used as building blocks. The goal was to have a reproduceable structure and design to be able to easily create new landingspages without the need to code anything on the front-end level. An additional benefit from this structure is the posibility to give content editors only access to the content templates (orange coloured). Another thing to mention is the shared (green) pages, which contains content that needs to be re-used on several places in the website. For example the footer contact and google maps. But also structures for certain content.
    1 point
  35. I think the admin page tree would benefit from a state saving feature. In jsTree for example you can on state saving which uses cookies to save a hash with open nodes. If there's already a option somehwere I missed, I'm sorry. Else do you think we can implement this feature?
    1 point
  36. @mackski, thanks for your module, please add to the modules directory when you get the chance. To be honest, I can't tell the difference here on my desktop, but then just tried on my notebook and it did seem faster (maybe) but cutting out the animation. I went ahead and added it as a module configuration option for ProcessPageList (Modules > Process > PageList), now available on the dev branch. Try changing it from 200 to 50 ms (or even 0 ms) and see if it makes a difference? It might. I think we just need more people to test it.
    1 point
  37. Hey guys! Another tiny little PW site we have built in the last few weeks. Really really reaaaaaally small budget, so nothing is really perfect on this website. But the client (a friend of mine, he is a teacher and a hobby author) is happy to now have more control about his content, speaking of his short stories and novels. See for yourself - feedback welcome: http://www.peterhohmann.net
    1 point
  38. The double click thing was annoying me too. I removed it on dev.
    1 point
  39. Like mentioned above, urlSegmentStr is your ticket. Note that it has no trailing slash, so you may need to add one to it in some instances. Also want to mention that the $input->urlSegments Array is not useless at all – I use it all the time. Just one small example is to count the number of urlSegments: count($input->urlSegments);
    1 point
  40. It's urlSegmentsStr or urlSegmentStr (typo)
    1 point
  41. try $input->urlSegmentsStr $input->urlSegmentStr #280 WireInput.php
    1 point
  42. Something like this? $image = $page->images->first(); $img = null; if ($image->width >= $image->height) { // Lancscape $img = $image->width(900); } else { // Portrait $img = $image->height(900); } echo "<img src='{$img->url}' alt=''>";
    1 point
  43. Let that sink in. Ryan, I can't absorb the knowledge you share fast enough — thank you!
    1 point
  44. I stumbled upon this thread when I went looking EXACTLY for this, ha. Using the above jQuery solution shared by Soma. I was able to get jQuery highlights on my client site search page. It was/is incredibly simple! AND FOR ME to claim something is simple (I know no javascript) ... it's the simplest solution, believe me! Save the jquery plugin to your 'js' folder and call it after your jQuery.js: <script src="<?php echo $config->urls->templates; ?>js/jquery.highlight.js"></script> Then stick this in the bottom of your search.php page: <script> $("body").highlight("<?php echo $q; ?>"); $(".highlight").css({ backgroundColor: "#FFFF88" }); </script> The $q variable if what results from your input search box. EDIT (sun.aug.10.2014): here is the latest jquery link <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    1 point
  45. I see what you mean. Row quantity really isn't a problem so long as the indexes are good. So I suspect even a single table would scale just fine. But if you still prefer a file-based storage option, using the existing $page->filesManager->path might be a good place to do it, as ProcessWire will maintain one directory per page (i.e. /site/assets/files/[id]/. You wouldn't want the version files to be publicly accessible, so you'd probably want to put them in filenames that PW prevents direct access to (like .php). Either of these seem like good options too. One table per field would be consistent with the way PW stores its fields... though that's for DB-related reasons that wouldn't apply to the case we are talking about. I guess the main benefit of splitting things into separate tables per field or fieldtype would just be to allow the possibility of versioning different data types. But your table with the single mediumtext column still allows for it, because all PW field data stored in the DB can be reduced to an array or JSON string: $data = $field->type->sleepValue($page, $field, $value); // convert to array $json = json_encode($data); // convert to JSON string Once it is stored as a string in the DB, then it's no longer "findable" except by possibly a fulltext index. But it seems like these versions probably would not need to have that search accessibility for storage anyway. I think you've got a lot of good ideas here. Though I'm not sure that you necessarily need anything more than what you've already got, with regards to data storage. From what I can tell, the data doesn't need to be selectable by anything in the data itself... just indexed attributes of the data: page_id, field_id, user_id, date. That combination would always be unique regardless of row quantity. It doesn't seem like you'd ever have to worry about potential for "full table scan" in MySQL. But there may be things I'm not thinking of. I haven't had my morning coffee yet. I do agree that splitting tables by fieldtype or field sounds better… but I don't know if it would ultimately matter. It would be interesting to take a table with 1m rows and a field_id index, and compare that to 10 tables with 100k rows and no field_id index. Assuming just straight selection from the table by page_id (no joins) and date-sorted results, would it make any difference? I have a feeling it would not, but haven't tried. But having it in one table you could select all field versions for a page in 1 query and your date-based maintenance could do its thing in 1 query. From a scalability standpoint, probably the only thing it would need there is just some limit on the number of versions it would load at once [25, 50, 100]? I'm assuming it doesn't load the actual version "text" here (it looked like you were doing that with ajax), but just the attributes. So maybe it would just need some kind of pagination or "older versions" link that loads the next block of [25, 50, or 100]. Either that, or you could just have version 1.0 say "we will store a maximum of 100 versions and no more", which would probably be fine for 99.9% of folks. No pagination worries. I think this is what the 37signals guys would say to do, at least for version 1.0.
    1 point
  46. Are you proposing rolling this editor setup into a Processwire collaborative module or something. Editing a Processwire page with something like that would make for some awesome app-like experience idea starters! Great find! -fanboy
    1 point
  47. Here's a start on creating modules documentation. I still need to write a whole section on hooks, but it's fairly complete in other areas. Please feel free to edit/add to this. http://wiki.processwire.com/index.php/Module_Creation
    1 point
  48. Few things that are "nice to know" when building PW modules: Autoload and non-autoload modules: autoload ones are loaded on every page load. So if you need to hook into core, then you probably need autoload. Non-autoload modules are run only by request: $modules->get("myUberModule")->doSomething() When you need hooks? Well.. common things are "do something when page is saved", "alter the output that is generated", "do something before page is accessed" etc.. Actually there is quite a many hooks and best way to find right hook for you need is to ask for it here. Building modules is pretty similar to working with templates. Nothing "special" there. Few notes though: You cannot directly access the PW API variables like $pages, $session, $input etc.. Those are available at $this->pages or wire('pages'). If you have static method(s) in your modules then you need wire('pages') there - so if you want to play it safe always use that (it works on command line scripts also) Modules can have settings - those are very easy to implement (just look examples from other modules that have settings) Modules are cool. init() is run before page is loaded, so if your autoload module needs to know the current page, that is available at ready() method. Forums is your friend, just ask and someone (probably Soma with his quick editing skills) will surely help.
    1 point
  49. I will add this to the roadmap as a module (most likely a Fieldtype). But also wanted to follow up with the strategy that I use, and the reason why the need for a publish/unpublish by date has not come up before. It's because this is so easily accomplished with the API. It also gives you more control over how you want to react to such dates. Here's how: Lets say I added a datetime field for publish date and/or expire date to the page's template. That template checks it's dates before it outputs anything. For example, lets assume we added a datetime field to the job_advert template called "expire_date". When we edited a job advert, we selected an expire_date of February 1, 2011. The job_advert template might have code like this: <?php if(time() > $page->getUnformatted('expire_date')) { throw new PageNotFoundException(); // or print "sorry this posting has expired" if you don't want a 404 } // print the job advert Note that the getUnformatted() function above is necessary because ProcessWire will return a formatted date according to the format you specified when you created the field, "January 21, 2011" as an example. So using getUnformatted() is a way to ensure it returns a timestamp that you can use for comparison with other timestamps (like that returned by PHP's time() function). (Btw, that getUnformatted() function works with any field, returning text fields without entities or runtime markup, etc.) Lets say that you also wanted to move the job advert to the trash since we now know it's expired: <?php if(time() > $page->getUnformatted('expire_date')) { $pages->trash($page); // move it to the trash throw new PageNotFoundException(); } // print the job advert Next lets assume that you didn't move the page to the trash, but you are just leaving it where it is and not disabling it or anything. If that's the case, you'll want to check that it's not expired when you links to your job adverts. So here's what your list_job_adverts template might look like: <?php $now = time(); $jobs = $page->children("expire_date>$now"); foreach($jobs as $job) { // print the job listing, being confident that it's not expired } If you had both expire_date and publish_date fields, then you'd find those jobs with something like this: <?php $now = time(); $jobs = $page->children("expire_date>$now, publish_date<=$now");
    1 point
×
×
  • Create New...