Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/21/2015 in all areas

  1. you can use it in several scenarios: Progressive Enhancement of forms: Return json for inline form validation (using the same url for the "good old form roundtrip action" and json_encoded responses: $response = array( error => true, status => 'unsubmitted', msg => 'no valid form data given' ); do { if ($_SERVER['REQUEST_METHOD'] != 'POST') break; $response['status'] = 'submitted'; if(!$someValidator->validate($_POST)) break; // more validation logic here... $response['error'] = false; } while (false); if( $config->ajax ) { if (!headers_sent()) { header('Content-type: text/json'); header('Content-type: application/json'); } echo json_encode($response); return; } Rendering different templates when urls are accessed via ajax: $template = $config->ajax ? "ui/projects_ajax.php" : "ui/projects.php"; $content = wireRenderFile( $template, array( "title"=>$title, "CategoryData"=>$pages->find("/categories/,include=hidden"), "PageData"=>$page )); ... we use this technique here (in combination with pushstate/history.js): http://www.accom.kg/ - If templates are accessed via ajax they are rendered without footer and header. This way we only load the necessary parts to be displayed. If the user (or google) visits the "real" page, navigation and footer are rendered. Redirecting users that accidentally visit some api endpoint that should only be used via ajax: if( !$config->ajax ) { $session->redirect('/'); } // API-LOGIC HERE. .... plus a billion other examples
    6 points
  2. And here's some code for those that may need it: $myfieldset_start = false; foreach ($page->template->fields as $field) { // or something like $this->templates->get('templatename')->fields if ($field->name == 'myfield') { // opening element of a fieldset is just the field name you gave it $myfieldset_start = true; } elseif ($field->name == 'myfield_END') { // ending element is field name with _END on it - break out of the loop if we reach this break; } elseif ($myfieldset_start == 'true') { // otherwise we are iterating fields in the chosen fieldset so do what you like here echo $field . "<br>"; } }
    4 points
  3. A very simplified example. Reloading only the page content via ajax: if( !$config->ajax ) include("head.inc"); echo $page->body; if( !$config->ajax ) include("foot.inc");
    4 points
  4. Some parts of this module, mainly those related to the cleanup features and settings, have been completely rewritten recently. I've also removed some old hacks, mainly from the UI side, that were carried over from Version Control for Text Fields. Test suite has been updated accordingly, and so far I've been unable to find any further issues, at least in the core features of this module. While some todo items still remain, I've just bumped the version number of the module to 1.0.0, and removed the "beta" status from the modules directory and from the first post in this thread. 1.0.0 should be considered the first stable release of this module, but of course if anyone spots any issues, I'd be more than happy to hear about them, either here or via GitHub. Big thanks to anyone who's been using this module, reporting issues, etc.!
    3 points
  5. FCM release 0.5.0 (no documentation at the moment... sorry!) requires FormHelper add / edit pages default sanitizer based on field type (textarea or text) if no sanitizer is set to the field skip fields optional use admin form styles file / image upload during page add (check input, page pre-save, set field values and add files and again save the page...) usage / example // load FCM $fcm = $modules->get('FrontendContentManager'); // ADD a page to given parent with parent template $output = $fcm->renderAdd($parentPage); // or EDIT given page $output = $fcm->renderEdit($pageToEdit); // echo jsConfig inside the html head element echo $fcm->JsConfig(); // outpunt needed scripts for inputfield modules, ... inside your html head element foreach ($config->styles as $file) { echo "<link type='text/css' href='$file' rel='stylesheet' />\n"; } foreach ($config->scripts as $file) { echo "<script type='text/javascript' src='$file'></script>\n"; } // echo $output inside your template / html body element echo $output; PW module repo: http://modules.processwire.com/modules/frontend-content-manager GIT repo: https://bitbucket.org/pwFoo/frontendcontentmanager/src/
    2 points
  6. If you prefer some type of delayed output, you also can use both (regular and ajax) very close together: $out = ''; $out .= {html head part}; $out .= {my menu content}; $out .= {some other content}; // her we come to the individual content if ($config->ajax) $out = ''; // delete all collected output til here and start new $out .= {my individual content}; //... collect until individual content is complete, then if ($config->ajax) { echo $out; // send it out as html exit(); // stop any further processing } // if it isn't a ajax call you collect also footer etc. $out .= {my footer content}; // send out the complete html page echo $out;
    2 points
  7. An update to the xsl sylesheet above. Tablesorter is not required for zebra striping, and so jquery is not required. Added CSS3 nth-child(odd) styling instead. <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:html="http://www.w3.org/TR/REC-html40" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1" xmlns:sitemap="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" version="1.0" encoding="UTF-8" indent="yes"/> <xsl:template match="/"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>XML Sitemap</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <style type="text/css"> body { font-family: Helvetica, Arial, sans-serif; font-size: 18px; color: #545353; } table { border: none; border-collapse: collapse; } #sitemap tr.odd { background-color: #eee; } #sitemap tbody tr:hover { background-color: #ccc; } #sitemap tbody tr:hover td, #sitemap tbody tr:hover td a { color: #000; } #content { margin: 0 auto; width: 1000px; } .expl { margin: 10px 3px; line-height: 1.3em; } .expl a { color: #da3114; font-weight: bold; } a { color: #000; text-decoration: none; } a:visited { color: #777; } a:hover { text-decoration: underline; } td { font-size:14px; } th { text-align:left; padding-right:30px; font-size:12px; } thead th { border-bottom: 1px solid #000; cursor: pointer; } tbody tr:nth-child(odd) { background-color: #E8E8E8; } </style> </head> <body> <div id="content"> <h1>XML Sitemap</h1> <p class="expl"> Generated by <a href="http://processwire.com/">Processwire</a> this is an XML Sitemap, meant for consumption by search engines. </p> <p class="expl"> You can find more information about XML sitemaps on <a href="http://sitemaps.org">sitemaps.org</a>. </p> <p class="expl"> This sitemap contains <xsl:value-of select="count(sitemap:urlset/sitemap:url)"/> URLs. </p> <table id="sitemap" cellpadding="3"> <thead> <tr> <th width="75%">URL</th> <th width="12%">Last Change</th> </tr> </thead> <tbody> <xsl:for-each select="sitemap:urlset/sitemap:url"> <tr> <td> <xsl:variable name="itemURL"> <xsl:value-of select="sitemap:loc"/> </xsl:variable> <a href="{$itemURL}"> <xsl:value-of select="sitemap:loc"/> </a> </td> <td> <span> <xsl:value-of select="sitemap:lastmod"/> </span> </td> </tr> </xsl:for-each> </tbody> </table> </div> </body> </html> </xsl:template> </xsl:stylesheet>
    2 points
  8. That's my article, using Ajax is quite easy in PW, just make an Ajax call to your page, now the HTTP Header contains Ajax header in it, so $config->ajax will flag as true when it is an Ajax call and false if not, Do this 1. Make an Ajax Call to the Page 2. var_dump something if Ajax and exit and you will see your result 100% cleaner than WordPress and i stick to that statement, also thanks for reading my blog. If you have something you want me to write on please let me know, quite bored at home.
    2 points
  9. For those onload-hash-jumps, I would suggest a smooth scroll behaviour, so that the visitor can see what's going on.To implement this "aha-effect", just wait that the page has loaded completly, scroll to 0 on x and y axis* (immediately, no tweening), get the corresponding DOM-Node (with the id or name attribute) where you want to go, get its absolute vertical and horizontal offset and animate the scroll-offset to this point. This could let your visitors think "ahaa", instead of "achso". Or, if something fails (browser quirks, loading order problems, browsing the history back/forwards etc.) "aaaah!"... *you could skip this, if the hash doesn't match any id or name attribute in your DOM, but this would not work without js. Another could be removing the id or name attribute, before the page is loaded, but after the dom is ready. Hope this helps
    2 points
  10. if you want to make icons searchable (when setting them on a template), you can use chosen select.. 1) add chosen min.css, min.js and sprites in AdminCustomFiles folder. 2) enable ProcessTemplate in the ACF module settings 3) add lines to load chosen assets (in the dependencies box) ProcessTemplate AdminCustomFiles/chosen.min.css ProcessTemplate AdminCustomFiles/chosen.jquery.min.js 4) create processTemplate.js, inside AdminCustomFiles folder $(document).ready(function(){ $("select#Inputfield_pageLabelIcon").chosen({ disable_search_threshold: 10, no_results_text: "Oops, nothing found!", width: "25%" }); }); this will probably end up being a module, so that it can also extend to fields; for now if you want to do it on fields you have to repeat the instructions for ProcessField and also change the jquery selector
    2 points
  11. when a PageListSelect is populated it looks like this: if you want to clear the value of this field rather than changing the referenced page, you have to do lots of clicking if your selected page is somewhere down the tree: it would be great to have a "clear" button right beside the "change" button
    1 point
  12. When in template context you could return instead of exit. Somehow return gives me a better feeling then die the script.
    1 point
  13. Well, the fields are not really inside the fieldset, so you can’t get them in an easy way. What you can is look for the fieldset_open and get all the fields after that and before fieldset_close. Have to go, so no code example, I’m sure you’ll get it from here
    1 point
  14. Hi, the error in your first screen advices you to define $config->uploadTmpDir (in site/config.php) and ensure that it is writeable. So, I don't know MAMP and how it manages things, but I would simply try to find a place for uploads by try and error if there are no useful docs for Windows. For example you can try to create C:\MAMP\htdocs\tmp, and set this in your site/config.php $config->uploadTmpDir = 'c:/mamp/htdocs/tmp/'; // yes, you can use forward slashes, PHP and Apache on Windows converts this internally where needed, also try with trailing slash first! And if this doesn't work, go to that folder with the windows explorer and set it rigths to writeable for everyone as a quick and dirty test. Than try again. If this doesn't help come back here and tell us. (missing trailing slash for the directory ?) You may also try $config->uploadTmpDir = 'c:/windows/tmp/'; // traing slash !!
    1 point
  15. I use the last example a lot in my work if the site is simple enough (only the content area changes and there nav stay and hold state). For a more complex site you may want to write some more logic but I try to keep Ajax and static page templates request as close as possible so as not to do double the work.
    1 point
  16. Slightly unrelated, but I love this small add from Perch
    1 point
  17. It is certainly possible, I don't think it would be that big a deal. Note though that your usage would not be linear, would probably be something like a Gaussian curve so better measure peaks that way, and compound with days of the week. Storage is cheap so that's clearly not an issue, places like Digital Ocean provide you with good performance and you can upgrade/downgrade easily. I would start with a prototype of the site, and test using Apache JMeter, top and whatnot. Launch an instance, install your prototype and start stress tests watching if your site is more CPU, storage or memory bound, then adjust accordingly by tweaking your server and application settings, and throwing more hardware if need be. I am not an expert on infrastcture, but if I need it it's how I typically go at it. Hope it helps.
    1 point
  18. Nice one Nico! I have some trouble with the nav, though. It's not the first time I see this, but linking to anchors of other pages feels very confusing to me because you skip the header. Really not the first website where I feel this way, happens from time to time and the process and reaction is always the same: click link > have the feeling that something is missing > scroll down, see unrelated content > scroll up, find the header > "achso, i was halfway down already!" PS: I hope you liked my "achso" there
    1 point
  19. It's just a simple typo diogo: // if this field doesn't exist continue if(!field) continue; You're missing the $
    1 point
  20. Ah, that is indeed a bad assumption on my part. Because the REQUEST_URI in this case is for the root, PW will not return a 404, and thus Jumplinks won't come into effect. Unfortunately, this is the caveat of hooking to the 404 event. I will look into this when I rewrite the module. As a suggestion, and if you're using mapping collections, you can add the following to your condition and rule to .htaccess (right at the beginning to be safe): RewriteCond %{QUERY_STRING} ^p=(\d+)$ RewriteRule ^$ /postid_querystring?p=%1 [R=302,L] Then you can create a jumplink with postid_querystring?p={id} as the source. (Not tested, but it should work.)
    1 point
  21. Perfect! Thank you so much for this, adrian!! ( also, I think this should be the core functionality )
    1 point
  22. Maybe it could be by choice in the field settings?
    1 point
  23. Here is something I hacked together quickly for automatically adding new child pages to the pagetable field. This is only if you are using the page as the parent. It also handles deletion of items if they are trashed externally. I also disabled the internal check for orphans - because they have been automatically added already, there is no need for the "Children were found that may be added to this table. Check the box next to any you would like to add." option. I seems to be working great here, but please test carefully!! Add this to your admin.php file: wire()->addHookBefore('InputfieldPageTable::render', function($event) { $pp = wire('pages')->get(wire('input')->get->id); $ptf = $event->object; //remove pages from pagetable field if they were externally trashed foreach($pp->{$ptf->name} as $item) { if($item->is(Page::statusTrash)) $pp->{$ptf->name}->remove($item); } //add pages to pagetable field if they were created externally foreach($pp->children as $child) { if(!$ptf->has($child->id)) { $pp->{$ptf->name}->add($child); $pp->of(false); $pp->save($ptf->name); } } //reset orphans property so that we don't get a message asking to add new pages that are now already automatically added $ptf->setOrphans(new pageArray()); });
    1 point
  24. Hello Gabe and welcome, Are we talking about a one single template called material here? Are all of the characteristics usually defined for all of the materials? And the problem is that you don't want to give your client access to the templates and fields of the system? If the answer to all questions is 'yes', then I think approaching the problem with autoloading modules, hooks, PageTables etc is a bit overkill. It is amazingly simple to create a Process-module that you can give the client access to, which simply allows the client to add/edit/remove such fields on the material-template. Here are all the relevant API-methods $template = wire('templates')->get('material'); // Adding a field $field = new Field(); $field->name = "c_durability"; $field->label = "Durability"; $field->type = "Integer"; $field->save(); $template->fields->add($field); $template->save('fields'); // Updating the label $field = wire('fields')->get('c_durability'); $field->label = "Characteristics: Durability"; $field->save(); // Removing the field $field = wire('fields')->get('c_durability'); $fieldGroups = $field->getFieldgroups(); if($fieldGroups->count() > 0) { foreach($fieldGroups as $fieldGroup) { $fieldGroup->remove($field); $fieldGroup->save(); } } wire('fields')->delete($field); Now of course you still need an UI with some confirmation dialogs and validation, but I'm sure you get the idea (if not, ask away). If you really, really want to create a module that does this automatically based on pages, then yes, that can be done with the same methods as well. Such module could be something like this class PageFieldCreator extends WireData implements Module { protected $material_template = "material"; protected $char_template = "characteristic"; protected $template; public static function getModuleInfo() { return Array( 'title' => __('Page Field Creator', __FILE__), 'summary' => __('Demo-module that creates fields from pages'), 'version' => 1, 'singular' => true, 'autoload' => true, ); } public function init() { $this->addHookAfter('Pages::saved', $this, 'saveHook'); } public function saveHook(HookEvent $e) { $page = $e->argument(0); if($page->template->name != $this->char_template) return; if($page->parent->isTrash()) $this->handleDelete($page); else $this->handleSave($page); } protected function handleDelete(Page $page) { $fieldname = $this->getFieldname($page); $field = $this->fields->get($fieldname); if(!$field) return; $fieldGroups = $field->getFieldgroups(); if($fieldGroups->count() > 0) { foreach($fieldGroups as $fieldGroup) { $fieldGroup->remove($field); $fieldGroup->save(); } } $this->fields->delete($field); $this->message(__("Characteristic {$fieldname} deleted")); } protected function handleSave(Page $page) { $fieldname = $this->getFieldname($page); $field = $this->fields->get($fieldname); if(!$field) $this->handleNew($page); else $this->handleUpdate($field,$page); } protected function handleUpdate(Field $field, Page $page) { if(strcmp($field->label, $page->title) == 0) return; $field->label = $page->title; $field->save(); $this->message(__("Characteristic {$field->name} updated")); } protected function handleNew(Page $page) { $field = new Field(); $field->name = $this->getFieldname($page); $field->label = $page->title; $field->type = "Integer"; $field->save(); $tpl = $this->getTemplate(); $tpl->fields->add($field); $tpl->save('fields'); $this->message(__("Characteristic {$field->name} created")); } protected function getFieldname(Page $page) { return "c_".$this->sanitizer->fieldName($page->name); } protected function getTemplate() { if(!isset($this->template)) $this->template = $this->templates->get($this->material_template); return $this->template; } } Such module would create/update/delete a field and update the template called material when a page that has the template characteristic is created/updated/trashed. The demo creates the field using the name of the page prefixed with "c_". While this would technically work, I'd still just create a Process-module for managing them to gain more fine-tuned control. Like I mentioned in the beginning, hooking is also a bit overkill since the fields are rarely modified.
    1 point
×
×
  • Create New...