Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 12/28/2013 in all areas

  1. The goal is that there would be no difference from our perspective. But the reality is they are two totally different things behind-the-scenes, so there are sometimes minor differences. In time, hopefully there won't even be minor differences. But either way, it's good to know the difference just because database-querying selectors are more expensive to execute in terms of resources. Any function that accepts a selector and returns pages from the $pages or $page API variable is a database-querying selector. Whereas in-memory selectors are primarily used by PageArrays, as they represent a group of pages already loaded in memory and selectors are used to filter through them. $results = $pages->find("selector"); // database-querying $results = $results->find("selector"); // in-memory $children = $page->children; // database-querying $children = $page->children("selector"); // database-querying $children = $children->filter("selector"); // in-memory $children = $page->children->find("selector"); // database AND in-memory (just use children w/selector instead)
    2 points
  2. Just wanted to post it here for others that might look for an example. I'm currently working on importing a Site to PW2.1. Following code I figured is needed to create pages using the Bootstraped API: <?php include(./index.php) // bootstrap PW $p = new Page(); // create new page object $p->template = 'page'; // set template $p->parent = wire('pages')->get('/about/'); // set the parent $p->name = 'mynewpage_url'; // give it a name used in the url for the page $p->title = 'My New Page'; // set page title (not neccessary but recommended) // added by Ryan: save page in preparation for adding files (#1) $p->save(); // populate fields $p->image = 'path/to/image.jpg'; // populate a single image field (#2) $p->images->add('path/to/image1.jpg'); // add multiple to images field $p->save(); // testing echo 'id: '.$p->id.'<br/>'; echo 'path: '.$p->path; Note: in PW 3 with multi-instance support adding new Objects https://processwire.com/blog/posts/processwire-2.6.21-upgrades-comments-more-on-pw-3.x/#more-updates-on-processwire-3.0 [Edit by Ryan #1] Added first $p->save(); [Edit by Ryan #2] Changed $p->image('...') to $p->image = '...';
    1 point
  3. This module provides simplified (no fancy diff etc. features available, at least yet) version control for text type fields. Originally introduced in another post as a proof of concept, I'm now considering it stable enough to deserve a thread of it's own here. Just so that you know: I've tested this module in multiple ProcessWire installations, three or four different versions in total running on two different platforms, but it still hasn't seen too much real world use. Any information you folks can provide me about how well (or badly) it worked (or didn't work) for you would be considered extremely helpful! So, what does it do? When editing pages, fields with old revisions available show up with a new icon in their header bars. By hovering that icon you get a list of available revisions and by clicking any one of those the value of that particular field is reverted to that revision. No changes are made to page until you choose a revision and save the page, which means that you can keep switching between revisions to get an idea what's really changed without inadvertently causing any content to change. How does it work? Behind the scenes hooks provided by ProcessWire are utilized to catch page edits. If text fields (such as FieldtypeText, FieldtypeTextarea etc.) selected at module configuration to be tracked were changed, their values (along with some metadata) are saved to two custom database tables. See attached screenshots for better idea about how this thing works. Please note that before you've selected at least one template + field combination to be tracked via module settings nothing will be saved to database! Getting started Module is available at GitHub: https://github.com/teppokoivula/VersionControlForTextFields. Here's a direct download link if that's what you prefer. Installation instructions etc. are available at README.md. If you've got any questions, feel free to post them here or PM me!
    1 point
  4. Managing the Hierarchy could be fun, and I think PW default page structure is perfect for this, though I think a novel way of displaying it for management purposes might be worth investigating. If you look at it, it is a family tree with Home at the top and then departments, followed by subject, followed by shelf followed by items, just like in a library. If someone was clever, they could put together a JQuery tree that displayed to the Shelf level, but then changed display when you wanted to list everything on the shelf. For browsing/management, you simply work your way down the tree. At any point you can open the entire list that is beneath that point in the tree, or you could work your way till that branch runs out of twigs! Yep. its a TwiggyPedia! (Sorry ...) So, that is the standard way of laying it all out. But it is not the only way, and there is an argument to say that several ways should be employed all at once. The standard way is the equivalent of wandering into a library and looking around, heading eventually to the shelf that interests you. However, behind the scenes the library uses a different method like the Dewey Decimal Classification http://en.wikipedia.org/wiki/Dewey_Decimal_Classification These types of system use a number that is unique to each book and is based on category and other criteria. In libraries it makes books easier to return to the correct shelf, but of course in a digital wiki can be used for similar purposes. Moving on from that is tagging. Now tagging is often seen as a flat relationship between otherwise non-related items, but I suppose it could also be hierarchical if the tagging system was. My unformed theory here is that people are often inaccurate with their tags. If you do an article on Richard Branson, you may tag it "Entrepreneur" and "beard" But, is this very bearded? A bit hairy? ZZ Top? Time for a thesaurus! So, why not have a tagging system that is based on a thesaurus. You type in Beard and you are offered a choice of similes - stronger ones at the top and weaker ones lower down. If you choose a weaker one, you could choose to dig deeper. The result would be tag trail, starting with your first thought and then listing how you went from there. If you weighted them, then the tagging is becoming hierarchical - you could choose to look at other articles that shared strongest tags or weakest tags. Other categorisation can be geographical and of course time - WHEN is this about.(as opposed to when was it written) Now your wiki is becoming truly ordered
    1 point
  5. I agree with what you've said. In fact, after reading this insanely exhaustive write-up about password reset techniques, http://www.troyhunt.com/2012/05/everything-you-ever-wanted-to-know.html, I think it might be best to send the user a reset link that's only active for a few hours, and have them pick a new password rather than emailing them a temporary one.
    1 point
  6. It is possible to extend the existing images field (by code) to make it do what you want. But a simpler solution (especially on the multi-language side) would be to use a repeater, where each item has a single image field and you add whatever text/multi-language fields that you need.
    1 point
  7. Ryan, thank you for your feedback. We will look more closely at IP.Board and vBulletin, which seem powerful platforms and potentially good starting points. At the same time we would like to retain the flexibility in terms of design and functionality offered by PW and we are open regarding development budget. If any PW developer reading this thread would like to learn more, we are happy to provide details and discuss budget and time frame. @Beluga: we are not planning to include a forum in our website, however will be glad to coordinate efforts if we decide to have one at a later stage. We are also open to release other community building blocks developed for this project as open source
    1 point
  8. I wasn't aware of this issue and haven't ever experienced it myself. But just attempted to reproduce and sure enough I got the same thing. Here's a fix (attached), place this is /wire/modules/Process/ProcessPageAdd/ProcessPageAdd.js -- I'll commit this to dev when I get back in the office. ProcessPageAdd.js.txt
    1 point
  9. In your template files, you can always control access just by performing your own checks, and that may be the simplest route here. For instance, you could have something like this at the top of your template file: if(!$page->category->viewable()) $session->redirect('/path/to/login/page/'); Another way to do it is to hook into Page::viewable to perform your own permission checks. The benefit here is that you would keep it all in one place: wire()->addHookAfter('Page::viewable', function($event) { // if it was already determined page is not viewable, then we'll exit and stick with that // this may or may not be the behavior you'd want, but you probably want some "early exit" // thing to check so that you aren't completely disregarding what the existing // $page->viewable() returned if(!$event->return) return; // check that this page has a 'category' field that we are using for permission $page = $event->object; if(!$page->category) return; // we'll abort now if there is no category // if category isn't viewable, we'll say this page isn't viewable either if(!$page->category->viewable()) $event->return = false; // you could also do things like check user roles: // if(!$user->hasRole('some-role')) $event->return = false; });
    1 point
  10. I created this module http://modules.processwire.com/modules/page-edit-per-role/ exactly (almost) for this purpose. My use-case was that I needed to give users edit/add permissions on certain branches (sections) of the site - regardless of template. I believe this is also what you are looking for. There is also another module referred to by @soma http://processwire.com/talk/topic/3629-page-edit-per-role/?p=35510 which is another way of doing it. Anyhow, I hope these links will help you find what you need.
    1 point
  11. I may be way off here but I think Joss meant to use the cities' templates to control permissions; design-wise, the templates wcould be equivalents if you wanted to. Maybe you have other reasons why you want to use one (literal) template for all cities....?
    1 point
  12. Er ...I think this is a case of multiple templates. So, each City would have its own template and then you can give the permissions to each of those templates. The children pages inherit permissions from the parent template. You would need to try that to see whether all the children having the same template but different parent template pages get their permissions logically - I think they do.
    1 point
  13. What's wrong with Processwire + Foxycart? Working fine really well for one client of mine and soon to be integrated into another site. from the foxycart site: Use the CMS you already love. FoxyCart is built to complement your own preferred tools, and as such can be integrated into anything, whether it’s hardcoded HTML, a dynamic CMS, or a custom framework. Use the best tools for each specific job, not a one-size-fits-all system.
    1 point
  14. you can combine Hanna code and a multiple page field. this is just a hint and I'm on mobile on a bus, so I can't test or explain much better.
    1 point
  15. Just pushed some updates. Module is now v1.3.0 Form readme: Changes in 1.3.0 Changed module setting singular to false. This enables you load the module as a new instance with $nav = $modules->MarkupSimpleNavigation. This changes behavior for hooks attached to such an instance as it will only be called for this instance. This allows you to create multiple instances of the module to create different navigations with separate hooks. Added support for Page::listable. So you can exclude listing of pages in runtime by modifying this page permission. This can be done using a system hook on Page::listable and set the hook event to return false. Added new option date_format for created and modified native page properties. Added new option code_formatting, to enable or disable code formatting (indentation and newlines) of output markup. Added new option debug that will output rendertime and selector infos as commented inline html. Added support for Page::listable Usually you won't need this, but I needed it in a project so thought it wouldn't hurt. Usually you can hide pages from rendering in a list/navigation by setting the page to hidden in the admin. So this additional check in the module itself, allows you to make pages not listed on runtime. This can be used to check for logged in users that only should see the page listed when logged in. Example hook inside template just before calling render(): wire()->addHookAfter("Page::listable", null, "hookPageListable"); function hookPageListable($event){ $page = $event->object; if($page->template == "internal-page") { $event->return = false; // set listable to false if template "internal-page" } } Added new option debug If set to true this option will add an inline <!-- [MarkupSimpleNavigation Rendertime: 0.0171] --> after the markup output to show rendertime, and <!-- [Selector Level1: limit=3] --> on each item to see selector being used. This new version should still be compatible with older versions. But there could be instances where it could behave different when you have multiple navigations and using hooks. But chances are very small you run into this. If you have questions to the above just ask.
    1 point
  16. OK BIG thanks to soma, who helped me get this, here is the final one: <?php $limit = 5; // the "limit"-setting used on this page $children = $page->children("limit=" . $limit); $totalpages = ceil($children->getTotal() / $limit); // PAGINATOR: set SEO tags for Google if ($input->pageNum) { if ($input->pageNum < $totalpages) { echo "<a rel='next' href='" . $page->url . $config->pageNumUrlPrefix . ($input->pageNum + 1) . "'>Next "; } else { echo "Thanks for browsing, you have reached the bottom of this page!"; } } ?> Once again, thanks to all for thinking along, now the next hurdle, to get infinitescroll to do the rest!
    1 point
  17. No I mean the code for prev next by teppo, not the one I wrote cause that's different thing. if ($input->pageNum) { $limit = 15; // whatever limit you're actually using if ($input->pageNum > 1) { echo "<link rel='prev' href='{$page->url}{$config->pageNumUrlPrefix}".($input->pageNum-1)."' />"; } if ($input->pageNum * $limit < $items->getTotal()) { echo "<link rel='next' href='{$page->url}{$config->pageNumUrlPrefix}".($input->pageNum+1)."' />"; } } Or $limit = 12; // the "limit"-setting used on this page $children = $page->children("limit=" . $limit); $totalpages = ceil($children->getTotal() / $limit); // PAGINATOR: set SEO tags for Google if ($input->pageNum) { if ($input->pageNum < $totalpages) { echo "<link rel='next' href='" . $page->url . $config->pageNumUrlPrefix . ($input->pageNum + 1) . "' />"; } if ($input->pageNum > 1) { echo "<link rel='prev' href='" . $page->url . $config->pageNumUrlPrefix . ($input->pageNum - 1) . "' />"; } } I don't think modifiying the pager module is good or easy, as you're saying your not a coder even less. And pager module doesn't allow to do what you need. But with some custom code in template you can more easily generate a next link based on the pageNum etc. Maybe someone can help you getting the logic from the above script to what you exactly need.
    1 point
  18. Another one finished (only german/swiss at the moment, english is in the works): http://www.helveting.com/ Responsive (also with responsive images + art direction via thumbnail module for the slider/header images) Form Builder for applications as always, the great thumbnail module from Apeisa Thx to Soma for the always used SimpleMarkupNavigation module and countless others ;-) Perhaps worth a mention: The locations overview, a combination of a repeater and Ryan's map marker fieldtype: http://www.helveting.com/about/organisation-und-standorte/ rendered with styled Google Maps Feedback welcome
    1 point
  19. What are the language settings of ProcessWire? My guess is that maybe the locale is set different from PHP when you execute the Less script inside Pw templates. See : http://www.php.net/manual/en/function.setlocale.php
    1 point
  20. <?php wire('pages')->find("template=drink, category=whisky, type=middletons, ice=1, limit=1");
    1 point
  21. Sounds like your web host has some sort of caching enabled -- if you're using managed hosting, web hotel etc. I'd suggest taking a look at the help materials available and possibly asking the administrator(s) what could cause this. If you're hosting yourself.. well, you should know best what's installed and running
    1 point
  22. When it comes to the layout on the front end, well the world is your oyster. PW does not have any themes as such as with Drumlapress - instead it has a system where you can use any way you want of putting together how your site looks. You can use a framework like Bootstrap or Foundation, or you can simply hand code some html. For fun, when I wrote my basic site tutorial (http://wiki.processwire.com/index.php/Basic_Website_Tutorial) I actually used a really old copy of Dreamweaver, just to prove the point that PW is completely agnostic. Of course, this also means that if you want to use any fun JQery plugins, rather than have to create something that somehow works with a maddening API to make it even available to the site, let alone work, you just have to follow the normal instructions as if you were adding it to a static site, then bung in a bit of PW to produce the content. So, unlike the others, your hands are not tied - PW will serve up the content, it is up to you how you want to treat it.
    1 point
  23. This is something I learned through using Liferay which has the most comprehensive (and therefore mind boggling) permissions system I have ever come across. The rule was (much as had been inferred above) to create a core role that basically gives access to the areas for that particular group of people. You then create additional roles (call them addon roles if you like, though that is not how they are displayed) that give fine grained and specific access to functions - create, delete, edit, view and so forth, or access to specific applications - forum moderator, community manager .... Where Liferay gets a little more complicated is that you can then apply scope to roles - so you can have a global scope, or scope for just one area of the system (an organisation, for instance, as they are called in Liferay), or the scope can just be for one page. But then you can also allow access to certain roles within a specific page, or item and so on. The reason it is so complex is that roles need to be managed both globally and also locally within parts of the site, for instance, the Liferay version of Groups, where there is a local group manager, admin, moderator and so on who need to assign users to functions but not have those users suddenly gaining equal power with other groups! If you ever want to learn how a completely over the top permissions structure and management system can work, I strongly suggest you play with Liferay just as a learning tool Good luck!
    1 point
  24. @kyle: in case that this is related to creating files on the disk, have you considered installing SessionHandlerDB, i.e. moving sessions to database? If you can't log in to install it, you can do this with a very simple external script: <?php require 'index.php'; // path to PW index.php wire('modules')->install('SessionHandlerDB');
    1 point
  25. @Martijn: search engines have surely improved their algorithms a lot, but there are still things that are pretty hard for them to get right. One of these is whether alternate content is really relevant to the visually impaired, another is the general subject of usability. Sure, page speed matters, but what about totally unusable navigation, unreadable font face or inconsistent UI in general? Personally I'm a big fan of trying to analyze just about any data and making educated guesses about how good it is for purpose x, but I don't think we're quite there yet. According to some experts "human factors" are nowhere near the top of the list, at least. "Social" factors sure are, though in a different meaning than what you probably had in mind.. (Actually above link kind of seems to suggest that alt texts are considered good for SEO if they contain important keywords already visible in other content. This doesn't sound like a very good thing to me, as I fear it only encourages people to use them to repeat same things they've already mentioned in body content and headlines, which in turn doesn't necessarily imply any correlation with them being useful to the visually impaired.)
    1 point
  26. Aw man, this is the bomb! I was stressing my brain on ways to do exactly what @boundaryfunc was try to nail and it's so damn easy. How can permissions be so simple! PW continues to prove itself.....
    1 point
  27. You never know if Oracle is going to change anything in the future with MySQL. Look what they did with java when they took over Sun. With mariaDB we won't have to worry about similar MySQL scenarios.
    1 point
  28. Interesting point takin Teppo. As search engine becomes smarter and more 'human', fooling search engines with simple words has become questionable. I tend to think, search engines love 'packages' of information. A good header a few good paragraphs, a good link to related material and good naming conventions for images and their an alt text. In my opinion, search engines try to find what's best for a human to read. More, it's likely that search engines recognize some kind of social aspect. Is a site friendly for colour blindness ? What do users see when they have a poor connection. How is the bandwidth. All the little bit help if you asked me.
    1 point
  29. Looks like MariaDB is gaining some momentum. Red Hat going with MariaDB instead of MySQL is pretty big news for a lot of companies out there.
    1 point
  30. Technically speaking I've got nothing to add to above, but I couldn't resist commenting on one point here: alt text is not for "SEO guys." Please don't use it that way. Ever. The whole purpose of alt text is to provide meaningful alternative content for those who can't see your images -- using it to insert extra metadata for robots is very, very wrong. Sorry for the rant, but this is such a common usability fail that it's getting annoying; way too often alt texts are used either for SEO purposes ("hey, let's consider robots before humans!") or entirely useless metadata (a picture of a cat with alt text "a cat".. was that really useful for someone who can't see the image?)
    1 point
  31. Hey Ryan! That saved my day, thx! I got the same 500 on a server of german hoster 1und1 - if any other "Kraut" has the same "bratwurst" problem.
    1 point
  32. Just pushed a minor fix to prevent 403 forbidden errors when hitting the github page lists repository when starting the import process. Apparently they were forcing a user-agent header for several months now, but didn't seem to affect this module till recently. Anyway, should be fixed now. Sometime early in the new year I will sort out all the php notices/warnings in this module and add some more features for finer detailed selection of what you want to export/import.
    1 point
  33. Hello everyone! I launched yesterday another PW site: http://compab.it The modules that i have used are: • Site wide file manager. • CKeditor • Language Field Tabs • Modules Manager • Site indexer • Ergo ADMIN THEME Enjoy!
    1 point
  34. I all, i have update the module. Some fixes for repeater fields plus the addition of Diderik (Thank you!) ADB
    1 point
  35. Thank you Ryan! Yes, exec() was disabled and I changed that. I was able to confirm that /usr/bin/unzip actually is the path on my server. But changing the line in config.php like you mention above didn´t have any effect so far. I upload the zip with the images field and it is shown there, but only as the zip, the zipped images therein are not displayed. But like I said, this is not an important issue for me at the moment, just tried to make it work in case I need it at some point in the future. I really would like to thank you for your fast responses when a problem is mentioned here in the forums. I´m amazed at how you find the time to sort through all the different issues so quickly! And also the responses from other members I have found most useful. All this together with the great functionality really makes it a pleasure to work with Processwire!
    1 point
  36. I found I could listen to ProcessPageList::execute and just overwrite the breadcrumbs, that should do the trick.
    1 point
  37. You'd have to use the ID for the selector in this case. When no subfield is specified in a database-querying selector, a Page field will attempt to match the name or title of a selectable page if the given value is not numeric or a /path/. This is specifically for making it easier to do imports, like with ImportPagesCSV, where you'd be unlikely to maintain IDs in a spreadsheet. The reason it's not working in the above case is because the selector in question is not a database querying selector, just an in-memory one validating that the page matches the selector. Clearly it should in this case, and I think I can add support for this to the in-memory selectors. But I've been a little shy on this one because name and/or title aren't guaranteed to be unique in a set of selectable pages. So while they are convenient for things like importing, they aren't ideal for most definitions like this. Though the name is guaranteed to be unique, if the Page selection is limited by a parent. Roles is limited by a parent, so it would be fine in this case, but it could get you into trouble in other cases.
    1 point
  38. <pwired>I think nowadays a cms should have included this from the start.</pwired> I disagree on this. I prefer well formed structural information, not the graphical representation in one situation. Content should have an independent value, not fixed to one distribution, so it can be used on a multitude of platforms. There are situation where in-page editing makes sense, but we should not forget there's high value in structural information.
    1 point
  39. Greetings, What makes ProcessWire so excellent is the ability to do all kinds of work at the API level, so that you can essentially create a custom admin for your projects. Editing a page is of course a crucial part of any custom admin. NOTES: Of course, you must cutomize this to your project. Also, in my code I am editing the page directly inside the page itself. In other words, you display a page as usual, but inside it you have your edit code, as well as code to save the page after editing. The other option would be to link to another page just for editing. Editing does get rather involved. Below is a technique I've used. I'll break editing down to several steps, then later I'll put it all together as one. Here goes... Step 1: Isolate Who Has Editing Rights You don't want anyone who can view the page editing it! I use code like this to limit editing to people with either an "editor" or "superuser" role. We open it here, and close it later in Step 6: <?php if ($user->isSuperuser() OR $user->hasRole("editor")) { Step 2: Set the $page Variables (Except Title) to Hold Edited Values Take inputs received from a submitted form and use those values to replace current $page values. For this example, I am only using two fields to keep it simple. And they are text fields. We hold off on setting the title, since that needs special handling: <?php if ($input->post->title) { $page->set("first_name", $sanitizer->text($input->post->first_name)); $page->set("last_name", $sanitizer->text($input->post->last_name)); } Step 3: Edit Title Field, but Only if the Title is Unique, Then Save the Page You need something like this so you don't get an error if the title you apply to the edited page collides with the title of an existing page. The code below confirms that the title is unique and allows you to set the title, and only then save the page: $thistitle = $page->title; $matchedtitle = $input->post->title; $checktitles = $pages->find("parent=/[path]/[to]/[parent]/, title=$matchedtitle|$thistitle"); $titlecount = count($checktitles); if($titlecount < 2) { $page->of(false); $page->set("title", $sanitizer->text($input->post->title)); $page->set("name", $sanitizer->text($input->post->title)); $page->save(); Step 4: Refresh URL Think about it... If while editing this page we changed the title, the URL you are on is no longer valid. Here's a simple bit of Javascript to handle this. The code below also closes out the conditional set in Step 3: $refresh=$page->url; ?> <script type="text/javascript"> window.location = '<?php echo $refresh ?>'; </script> <?php } Step 5: Handle the Scenario When the Page Title Collides In Step 3, we edited the page title because it passed the "unique" test. But what if it fails that test? We would move to this section of code, where a message lets the user know there is a problem. A bit of Javascript helps make the warning fade in so it is more noticeable: else { ?> <div class="admin_error_box"> <p>Sorry, there is already a page using this title: <?php echo $input->post->title?>!</p> <p>Please enter a different title in the form.</p> </div> <script> $(function() { $('.admin_error_box').hide().fadeIn(3000); }); </script> <?php } Step 6: The Edit Form We need a form to capture the submission of edits. It would look the same as your page-creation form, but would have to be pre-populated with the current values of the page, which will also change upon submission of the form. The last bit of code closes out the check on user roles set in Step 1: <div class="page_create_form_box"> <p class="form_heading">EDIT THIS PAGE USING THE FORM BELOW</p> <form action="<?php echo $page->url ?>" method="post"> <ul> <li><label class="label_class" for="title">Page Title:</label> <input type="text" class="input_class" name="title" value="<?php echo $page->title ?>"></li> <li><label class="label_class" for="first_name">First Name:</label> <input type="text" class="input_class" name="first_name" value="<?php echo $page->first_name ?>"></li> <li><label class="label_class" for="last_name">Last Name:</label> <input type="text" class="input_class" name="last_name" value="<?php echo $page->last_name ?>"></li> </ul> <button class="admin_submit" type="submit" name="submit">SAVE EDITED PAGE</button> </form> <?php } ?> Step 7: Putting it all Together Now let's put all of this code into one continuous routine. <?php if ($user->isSuperuser() OR $user->hasRole("editor")) { ?> <?php if ($input->post->title) { $page->set("first_name", $sanitizer->text($input->post->first_name)); $page->set("last_name", $sanitizer->text($input->post->last_name)); } $thistitle = $page->title; $matchedtitle = $input->post->title; $checktitles = $pages->find("parent=/[path]/[to]/[parent]/, title=$matchedtitle|$thistitle"); $titlecount = count($checktitles); if($titlecount < 2) { $page->of(false); $page->set("title", $sanitizer->text($input->post->title)); $page->set("name", $sanitizer->text($input->post->title)); $page->save(); $refresh=$page->url; ?> <script type="text/javascript"> window.location = '<?php echo $refresh ?>'; </script> <?php } else { ?> <div class="admin_error_box"> <p>Sorry, there is already a page using this title: <?php echo $input->post->title?>!</p> <p>Please enter a different title in the form.</p> </div> <script> $(function() { $('.admin_error_box').hide().fadeIn(3000); }); </script> <?php } ?> <div class="page_create_form_box"> <p class="form_heading">EDIT THIS PAGE USING THE FORM BELOW</p> <form action="<?php echo $page->url ?>" method="post"> <ul> <li><label class="label_class" for="title">Page Title:</label> <input type="text" class="input_class" name="title" value="<?php echo $page->title ?>"></li> <li><label class="label_class" for="first_name">First Name:</label> <input type="text" class="input_class" name="first_name" value="<?php echo $page->first_name ?>"></li> <li><label class="label_class" for="last_name">Last Name:</label> <input type="text" class="input_class" name="last_name" value="<?php echo $page->last_name ?>"></li> </ul> <button class="admin_submit" type="submit" name="submit">SAVE EDITED PAGE</button> </form> <?php } ?> My apologies for any problems with the formatting of the code above (please use your editor to assure proper tabs). Notes: - If you include checkboxes or other field types in your page, the editing is a bit more involved. - If you have image fields, you would have separate actions connected with those. For more information on handling image fields in custom forms, take a look at this: http://processwire.com/talk/topic/3105-create-pages-with-file-upload-field-via-api/ That should get you started! Follow up if you have more questions! Thanks, Matthew
    1 point
  40. Welcome jzvanenk! Answering directly to your question. The snippets don't go inside the fields, they go directly on the template files. The code you have on the template files is PHP, just like the snippets yo are talking about. So, when you have this on the planets tutorial: <html> <head> <title><?php echo $page->title; ?></title> </head> <body> <h1><?php echo $page->title; ?></h1> <h2>Type: <?php echo $page->planet_type; ?>, Age: <?php echo $page->planet_age; ?> years</h2> <p><?php echo $page->planet_summary; ?></p> </body> </html> You can also have this: <html> <head> <title><?php echo $page->title; ?></title> </head> <body> <header> <ul id="all-planets"> <?php // list all planets and link to their pages foreach($pages->get("/planets/")->children as $planet){ echo "<li><a href='{$planet->url}'>{$planet->title}</a></li>"; } ?> </ul> </header> <h1><?php echo $page->title; ?></h1> <h2>Type: <?php echo $page->planet_type; ?>, Age: <?php echo $page->planet_age; ?> years</h2> <p><?php echo $page->planet_summary; ?></p> </body> </html> edit: that is the same as this (entering and leaving php to write html): <html> <head> <title><?php echo $page->title; ?></title> </head> <body> <header> <ul id="all-planets"> <?php foreach($pages->get("/planets/")->children as $planet): ?> <li> <a href="<?php echo $planet->url; ?>"><?php echo $planet->title; ?></a> </li> <?php endforeach; ?> </ul> </header> <h1><?php echo $page->title; ?></h1> <h2>Type: <?php echo $page->planet_type; ?>, Age: <?php echo $page->planet_age; ?> years</h2> <p><?php echo $page->planet_summary; ?></p> </body> </html>
    1 point
  41. This is something that a lot of us do because it's fun, not because it's something that we have to do. We might make a module so that we can do something like this because it's fun, satisfying, and efficient (plus it looks good) … echo $pages->find('brand=/brands/audi/, mpg>25')->renderCars(); But the reality is that it's also not necessary. You could perhaps more easily just package it into your include file and do this: $cars = $pages->find('brand=/brands/audi/, mpg>25'); include("./render-cars.inc'); And in your render-cars.inc: <?php foreach($cars as $car) { echo "<p>{$car->title}: {$car->mpg} mpg</p>"; } What I'm trying to get across is that much of the things we all create and use modules for is optimization and fun. Perhaps others feel differently, but in my case, most of my sites don't even use any modules other than what comes with PW. I create modules when I want something I can re-use on multiple sites or share more easily with the PW community. Another point about modules is that they are a whole lot simpler than you would ever imagine, once you get going with it. But the lack of ability to create modules is not going to limit your ability to use ProcessWire in any way. You can make it do pretty much anything without having to even know about modules. But when the time comes that you become interested in it, it will only increase your enjoyment of development. So when you see what appears to be complex development conversations about modules and such, don't worry. What you don't know isn't going to hold you back in ProcessWire. It already seems like you have a really good understanding of development and using ProcessWire. Based on your past posts, I feel confident you can push ProcessWire to do what you need when you want to. And we're always here to help with questions and problem solving. If I were you, I would keep using ProcessWire for everything that you are comfortable using it for. When situations come up that you feel can't be as easily solved with ProcessWire, then investigate services like what Pete mentioned (Lemonstand, Shopify, Google, Facebook, Flickr). There are services out there for nearly everything and this is where a lot of functionality is trending. For instance, look at the quality of a comments service like Disqus... it makes you wonder if we aren't far off from the time when built-in comments are no longer considered a required core feature of CMSs. When we had to setup a forum for ProcessWire, I never considered trying to create it myself in PW. Instead, we went with SMF, and then IP.Board. Services like these and others are better than what you can reasonably expect to build on your own, or what you could expect to come with (or be added-on to) any other CMS. Honestly, if you use ProcessWire and then utilize services for the things you don't want to build, then you will be able to do everything you could ever want. And more quickly, more securely and easier to support, than if you were trying to leave it all to a CMS. For the rare cases where you need something that won't be easy to do in PW, and your service options are limited, then bring WordPress into the mix. Not that WordPress can do much on it's own, but it's following is so much bigger than anything else that literally every possible thing has been coded for it. I certainly wouldn't want to use WordPress as my CMS, but I have no qualms about pulling it in when something that I need is available as a WordPress plugin. You aren't going to find any other CMS that has as much 3rd party stuff built for it. WordPress is easy-enough to figure out in a day (from a development perspective) that you also won't find yourself as frustrated as in Drupal (at least, this was my experience). It's not much prettier than Drupal from an output generation perspective, but it will be much more respectful of your time.
    1 point
  42. I would stick with PW, really I remember getting dizzy when I had to make pages in Drupal look the way I wanted: Where this margin is coming from? Ok, this module generates this HTML with 4 wrappers. Where it takes its css from? Let's see it has cached css-file which is generated every time I save module settings. Ok, let's take a look at its real css-file. Well, it's not really css-file, but css template written in php. Ok, what we see, it generates css depending on the options we set in module's properties, but I still can't see where this margin is set. I've spent already about 20 minutes trying to find this goddamn margin property. Ok, if it isn't here it should be somewhere else, let's dig through module's source files. Haveng spent another 10 minutes looking through module's source files I finally found this margin in module_name_API.php!!! WTF? Why put it here? Ok, I fixed my margin, but I have another page where this module's markup is output next to another's and now they overlay, because that another module generates its own markup and now I have to repeat this crazy procedure again for another module. No, not anymore! I have a lot of other things to do! Yes, Drupal is very powerful, but this continuos, never-ending hacking makes me suicidal I would rather spend time creating using the system then struggling with it. As for MODx, I really liked Evolution and still do, but PW makes it look unnecessary complex and is light years ahead in terms of intuitiveness and flexibility. I also tried to use Revolution, but to me it over-complicates things and I can't stand its sluggish back-end (thanks ExtJS). Their announcement IMO is pretty logical step to take as Revolution haven't equaled the hopes, but it gave really good understanding of what's really important for this CMS. I wish MODx team good luck with MODX3 because they've already made one of the best CMSs that I really like and just because they are great guys. Wish them to repeat their success with third version. Processwire brings joy to development, this is why I will keep using it It makes me learn and create rather then hack. And it has a brilliant community, in life of which I wish could participate much more then I do now.
    1 point
  43. I think that using pages in the system to maintain versions does simplify a lot of things, but it might be tricky and limited in others. If you are literally saving a version on every save, then you could end up with quite a large site tree and tables of data (whether visible or not). All the data in the tree is setup to be optimized for fast selection and searches. Everything is indexed. Past versions of pages don't really need that. So you end up with adding unnecessary overhead to the live tree. I am shy about the idea of having hundreds of thousands of pages in the system that don't contribute to the live site's data ... kind of like keeping all my past work projects on my desktop. But if you are in control of when you want to create a new revision (so that you don't end up with dozens-hundreds for each page) then the overhead might be a good price to pay for that capability. In fact, if you are using versions in a controlled and careful manner like this, then pages would probably be a good way to go. But if you are automatically creating a new page every time someone hits save, then I would be worried about the scalability of that. Either way, I like the way you are thinking about this and I think your ideas here have a lot of merit. The approach I took in the revisions module in development was to make a version on every page save() but just keep it JSON encoded in a flat table or files. I figured this is archived data and didn't need to be indexed in the DB. It prepares the array of data by calling each field's $field->type->sleepValue() function, which reduces the data for that page's field down to a format that can be stored anywhere. The big challenge is how to handle fieldtypes that involve files. I haven't solved that one yet. If you use pages to create your versions, you won't have to worry about that because PW's clone() function will take care of it for you. I wouldn't worry about things like users, roles, admin pages, etc. Instead, I would just suggest letting your module have a configuration option where one could check boxes next to all the templates they want to maintain versions for.
    1 point
  44. Thanks Soma, good post! A couple things to mention: 1. You need to save a page before adding files to it. So you'd want to have another $p->save() before the part where you add an image. This is because in order to place a file in the page, it needs to exist on disk first (so that it has a place to copy the image to). Before you save a page, it only exists in memory. Though if you found that actually worked, let me know–maybe I found a solution in a late night coding session and forgot about it. 2. To add a single image, you'd need to do $p->image = 'path/to/image.jpg'; rather than $p->image('path/to/image.jpg'). This is because there is no Page::image() function. I updated your post for this. 3. For others looking at this code sample, you may need to add a $page->setOutputFormatting(false) depending on the context and if PW gives you an error about needing to turn off output formatting.
    1 point
×
×
  • Create New...