Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/22/2014 in all areas

  1. Hey all, Here's a new PW site we launched in the end of last week. The site is a active archive of research documents from the areas of urbanism and territory planning, and was commissioned by the University from Aveiro, in Portugal. Again, PW was invaluable to achieve exactly what we wanted, since we built a quite complex website that required almost no training to the client. We made a heavy use of page fields to achieve all the filtering effect on the documents page. Special mention to Aleo and Varela. Two beautiful typefaces. Hope you guys like it as much as we and the client do http://www.ordenaracidade.pt/ http://www.milktop.co.uk/projects/ordenar-a-cidade/
    3 points
  2. Since we are at it, here is one more website we built with PW—this one for a Chauffeur Service in the UK—and launched already some time ago (we were too busy building our own website, and forgot to post it here ). http://www.signaturevip.co.uk/ http://www.milktop.co.uk/projects/signature-vip-chauffeur-service/
    3 points
  3. sessionFingerprint is a great security feature - if your connection works with it enabled, I really suggest keeping it installed.
    3 points
  4. I certainly don't see anything wrong with your approach, but if you set up a settings page in the admin and added a "signature_image" field to it, it would be easier for you / your clients to change this image in the future. Then you could simply echo the image in the same place using: $pages->get("/settings/")->signature_image->url();
    2 points
  5. For what it is worth: after digging half a day looking for the cause of the problem I found that it was not my: 1. wifi 2. ftp 3. laptop 4. pw 5. file manager. It turns out that the hosting server is not capable of extracting zip files without errors. After every new try to extract the zip file it gets extracted differently with randomly files and folders not being extracted or extracted as empty folders. I am now using a php unzip script together with pclziplib.php and now extracting goes perfect. I find it very strange that in 2014 a hosting server is not capable of something simple like extracting zip files without errors.
    2 points
  6. If rendertime is between 0.3 and 1.3 seconds for the same page? Then it's definately your server that is slowing down not ProcessWire. Could be the server being busy or the database connection is slow and latent. My guess it's a cheap shared server hosting? You could test a little more and maybe find more details, that you could tell the hoster. If they can't do anything I would change hoster.
    2 points
  7. Templates -> Filters -> Show System Templates : look for "admin" template. Edit and go to -> "URLs" and look for https etc.
    2 points
  8. PROCESSWIRE PROFILE EXPORTER This module serves two purposes: To enable exporting of ProcessWire 2.0 sites to a profile that can then be imported into ProcessWire 2.1 (i.e. to upgrade to 2.1). To enable exporting of ProcessWire 2.1 site profiles for sharing or distribution with others. In either case, the profile exporter does not touch your existing site. It just creates files in a directory (/site/install/) that can then be used for a fresh installation of ProcessWire. PLEASE NOTE: Consider this module alpha test only. It has not had a lot of use or testing yet so it's advisable to use it in a test environment and not on a production server at this time. I am posting this for those that indicated they wanted to help test the PW 2.0 to 2.1 upgrade process. HOW TO INSTALL Download at: https://github.com/r...ssExportProfile Place the file ProcessExportProfile.module in /site/modules/ Login to your admin, click "Modules" at the top, and click "Check for new modules" Click "install" for the Process > Export Profile module. It will create a new page where you can access it under the Setup menu. HOW TO EXPORT A PROFILE A profile consists of your site's database, files and templates. To create a profile, Go to Setup > Export Profile. Read the instructions and continue. Once the profile has been created, you can copy it somewhere else, zip it up, or [if performing an upgrade] copy it directly into your PW 2.1 directory as indicated in the 'upgrading' section below. The profile consists of files in these directories: /site/install/ < required /site/templates/ < required /site/modules/ < optional: use only if you have custom modules to include in the profile /site/templates-admin/ < optional: use only if you have a custom admin theme to include in the profile /site/assets/ < optional: use only if exporting all of /site/, and it should be left empty like PW's default profile* /site/config.php < optional: use only if you want to specify custom config settings, leave out otherwise** These directories collectively form the entire /site/ structure of a ProcessWire installation. If using the profile to upgrade ProcessWire from 2.0 to 2.1 then you'll only want the first two directories above (install and templates)–see the 'Upgrading' section following this one, as the instructions for upgrading are a little different than if you were exporting profiles for distribution. If you intend to share/distribute your profile with others (as opposed to upgrading), you'll want to ZIP them up into an archive (or use something like GitHub). You may want to make your profile include the entire /site/ directory for easier installation by others. If using the entire /site/ directory as your profile, then just copy all the /site/ files from ProcessWire's default uninstalled profile and replace the directories/files that you want to. For instance, you'll always want to replace the /site/install/ and /site/templates/ directories, but if your profile doesn't include plugin modules or configuration file changes, then you'd keep the default /site/config.php file and /site/modules/ directory from ProcessWire's default profile. *Any time you are including the entire /site/ directory as your profile, you'll want to include the /site/assets/ directory exactly as it is in the default ProcessWire uninstalled profile. That means the directory is empty, minus an index.php file. During installation, the installer copies files from /site/install/files/ to /site/assets/files/ and ensures they are writable. ProcessWire's installer also creates several other directories under /site/assets. But you don't need to worry about that. **If you ever do include a /site/config.php in your profile, make sure to remove the last 5 lines that contain confidential information about your database and user system hash. Once you've saved your profile somewhere else, you should delete the files that this module saved in /site/install/ (they might be consuming a lot of disk space). You'll see a link to do this after you've finished exporting a profile. UPGRADING FROM PROCESSWIRE 2.0 TO 2.1 This upgrade process is a little different from what you may have seen before. We won't actually be upgrading your current site. Instead we'll be exporting a profile of it, and using it to install a new/fresh copy of ProcessWire 2.1. To make this work, you'll have to install your copy of ProcessWire 2.1 in another location or another server. Once you've completed the installation and verified that everything is how it should be, you may then replace the original ProcessWire 2.0 site with the new one. It should be noted that this upgrade does not cover user accounts or access control. You will have to re-create any user accounts and access settings in the new system. This was necessary because PW 2.1 uses an entirely different user system and access control than PW 2.0. Should you have a lot of user accounts that need to be converted, let me know more in the PW forums and I can guide you through how to handle your specific case. Performing the upgrade 1. Export a site profile as described in the previous section. 2. Download the latest copy of ProcessWire 2.1 at http://processwire.com/download/ and install in a new location. If you are installing on the same server in a different directroy, then don't use the same database as you did in 2.0. Instead create a new database that you will be using for 2.1. 3. Before starting the 2.1 installer, copy these directories from your ProcessWire 2.0 installation to your ProcessWire 2.1 files (completely replacing the directories in the 2.1 files): /site/install/ => /site-default/install/ /site/templates/ => /site-default/templates/ 4. Now run the ProcessWire 2.1 installer by loading the URL to it in your browser. If all goes as it should, you'll see your 2.0 site now running 2.1. There are some likely issues that may occur, so read the following section about troubleshooting whether you think you need to or not. 2.0 TO 2.1 UPGRADE TROUBLESHOOTING I installed 2.1 using the new profile but now I get a 404 Not Found for every page If you run into this problem, login to ProcessWire 2.1 (/processwire/), edit the template used by your homepage, click the "access" tab and "yes". Then check the box for "guest" view access, and save. Your site should now be functional. I installed 2.1 using the new profile but now many pages have no title ProcessWire 2.0 assumed that all pages had a title field whether it was ever officially assigned to the template or not. ProcessWire 2.1 is different in this regard. So if you run into pages without titles, edit the templates used by those pages, add the field 'title' and hit save. The issue should now be fixed. I ran out of memory or had a timeout when exporting a profile or installing the 2.1 site with the profile On a large site, it's possible that the resources dedicated to PHP might not be enough for the exporter or installer to complete it's job. Should this happen to you, we may need to do one or more parts of the process manually. So if you run into this scenario, please post in the forum and we'll get it figured out. I installed 2.1 and all went well but I now have a non-working "Export Profile" page on my Setup menu (last item) This is the page used by the Profile Exporter module on your 2.0 site. Your 2.1 site won't have the Profile Exporter installed and you can safely delete this page or drag it to the trash.
    1 point
  9. What does autojoin do? Using the 'autojoin' optimization can increase performance on fields that get used a lot. Not using it can reduce the page's memory footprint. What is more desirable in each instance depends on your situation. What sites should use autojoin? Autojoin is most applicable with larger sites. On smaller sites, there may be no benefit to using it or not using it. But it's good to know what it's for regardless. Where do you control autojoin? Autojoin is controlled per-field. You can turn it on by editing each field under Setup > Fields > [your field], and you'll see it under the 'Advanced' heading. When should you use autojoin? Autojoin causes the field's data to be loaded automatically with the page, whether you use it or not. This is an optimization for fields that you know will be used most of the time. Fields having their data loaded with the page can increase performance because ProcessWire grabs that data in the same query that it grabs the Page. Autojoin is a benefit for fields that are always used with the Page. This is best explained by an example. Lets say that you have a template for individual news stories called news_story. The news_story template has these fields: title date summary body sidebar We'll assume that when you view a page using the news_story template, all of the fields above are displayed. Fields that should have autojoin ON: Now consider a separate news_index template that displays ALL of the news stories together and links to them. But it only displays these fields from each news story: title* date summary In this case, the 3 fields above would be good to autojoin since they are used on both the news_index and news_story templates. If your title, date and summary fields didn't have autojoin turned on, then ProcessWire wouldn't go retrieve the value from the database until you asked for it it (via $page->summary, for example). Because the news_index template displays all the stories at once, and always uses the title, date and summary fields, it will perform better with title, date and summary having autojoin ON than with it OFF. In this case, it reduces the query load of the news_index template by 3 for each news story. To take that further, if it were displaying 20 news stories, that would mean 60 fewer queries, which could be significant. Fields that should have autojoin OFF: Now lets consider the body and sidebar fields, which are only used on the news_story template: body sidebar It would be desirable to leave autojoin OFF on those fields because there is no reason for the body and sidebar to be taking up space in memory when they are never used on the news_index template. While it might mean 2 fewer queries to view a news story, that is not significant and certainly not a worthwhile tradeoff for the increased memory footprint on the news_index template. Keeping autojoin OFF reduces a page's memory footprint. Conclusion Using the 'autojoin' optimization can increase performance on fields that get used a lot. Not using it can reduce the page's memory footprint. What is more desirable in each instance depends on your situation. But if your situation doesn't involve lots of pages or data, then you don't need to consider autojoin at all (and can generally just leave it off). Additional Notes Not all fields have autojoin capability. You won't see the option listed on fields that don't have the capability. *The title field has autojoin on by default, so you don't need to consider that one. It was included in the examples above because I thought it's omission might cause more confusion than it's inclusion. Be careful with multi-value fields that offer autojoin capability (page references and images, for example). Because MySQL limits the combined length of multiple values returned from a group in 1 query, autojoin will fail on multi-value fields that contain lots of values (combined length exceeding 1024 characters). If you experience strange behavior from a multi-value field that has autojoin ON, turn it OFF. If you want to play it safe, then don't use autojoin on multi-value fields like page references and images.
    1 point
  10. MarkupCache is a simple module that enables you to cache any individual parts in a template. I'm working on a site now that has 500+ cities in a select pulldown generated from ProcessWire pages. Loading 500+ pages and creating the select options on every pageview isn't terribly efficient, but I didn't want to cache the whole template because it needed to support dynamic parameters in the URL. The solution was to cache just the code that generated the select options. Here's an example: $cache = $modules->get("MarkupCache"); if(!$data = $cache->get("something")) { // ... generate your markup in $data ... $cache->save($data); } echo $data; I left the markup generation code (the part that gets cached) out of the example above to keep it simple. Below is the same example as above, but filled out with code that finds the pages and generates the markup (the part that gets cached): $cache = $modules->get("MarkupCache"); if(!$data = $cache->get("city_options")) { foreach($pages->find("template=city, sort=name") as $city) { $data .= "<option value='{$city->id}'>{$city->title}</option>"; } $cache->save($data); } echo $data; That was an example of a place where this module might be useful, but of course this module can used to cache any snippets of code. By default, it caches the markup for an hour. If you wanted to cache it for a longer or shorter amount of time, you would just specify the number of seconds as a second parameter in the get() call. For example, this would keep a 60-second cache of the data: $cache->get("city_options", 60) I hope to have it posted to GitHub soon and it will be included in the ProcessWire distribution. If anyone wants it now, just let me know and I'll post it here or email it to you.
    1 point
  11. Here are some API additions to the dev branch, primarily for WireArray/PageArray/etc. I've found these very handy lately, and would have on almost any project I worked on, so decided they'd add value to the core. I'll add these to the cheatsheet once 2.4 replaces 2.3, but for now, here they are. The examples here use PageArray, but note that these API additions apply to any WireArray derived type, not just PageArray. WireArray::implode() Implode all elements to a delimiter-separated string containing the given property from each item. Similar to PHP's implode() function. Usage: $string = $items->implode([$delimiter], $property, [$options]); Arguments: $delimiter - The delimiter to separate each item by (or the glue to tie them together). May be omitted if not needed $property - The property to retrieve from each item (i.e. "title"), or a function that returns the value to store. If a function/closure is provided it is given the $item (argument 1) and the $key (argument 2), and it should return the value (string) to use. [$options] - This argument is optional. When used, it's an array with modifiers to the behavior: skipEmpty: Whether empty items should be skipped (default=true) prepend: String to prepend to result. Ignored if result is blank. append: String to prepend to result. Ignored if result is blank. Examples: $items = $pages->find("template=basic-page"); // render all the titles, each separated by a <br>, for each page in $items echo $items->implode('<br>', 'title'); // render an unordered list of each item's title echo "<ul><li>"; echo $items->implode('</li><li>', 'title'); echo "</li></ul>"; // same as above, but using prepend/append options, // this ensures no list generated when $items is empty echo $items->implode('</li><li>', 'title', array( 'prepend' => '<ul><li>', 'append' => '</li></ul>' )); // same as above, but with all items now presented as links // this demonstrates use of $property as a function. note that // we are also omitting the delimiter here as well, since we don't need it echo $items->implode(function($item) { return "<li><a href='$item->url'>$item->title</a></li>"; }, array('prepend' => '<ul>', 'append' => '</ul>')); WireArray::explode() Return a plain array of the requested property from each item. Similar to PHP's explode() function. The returned PHP array uses the same keys as the original WireArray (if that matters). Usage: $array = $items->explode($property); Arguments: $property - The name of the property (string) to have in each array element (i.e. "title"). You may also provide a function/closure here that should return the value to store. When a function/closure is used it receives the $item as the first argument and the $key (if needed) as the second. Examples: // get an array containing the 'title' of each page $array = $items->explode('title'); // get an array containing the id, url and title of each page $array = $items->explode(function($item) { return array( 'id' => $item->id, 'url' => $item->url, 'title' => $item->title ); }); WireArray::data() Store or retrieve an arbitrary/extra data value in this WireArray. This is exactly the same thing that it is jQuery. I've personally found this useful when building search engines: the search engine can store extra meta data of what was searched for as a data() property. Then any other functions receiving the WireArray/PageArray have access to this additional info. For example, the search engine portion of your site could populate an array of summary data about what was searched for, and the render/output code could render it to the user. Usage: // Setting data $items->data('key', 'value'); // Getting data $value = $items->data('key'); // Get array (indexed by key) of all data $values = $items->data(); Arguments: The above usage section explains all that's needed to know about the arguments. The only additional comments I'd make are that 'key' should always be a string, and 'value' can be anything you want it to be. Example: function findSkyscrapers() { $floors = (int) wire('input')->get->floors; $year = (int) wire('input')->get->year; $items = wire('pages')->find("template=skyscraper, floors=$floors, year=$year"); $items->data('summary', array( 'Number of floors' => $floors, 'Year constructed' => $year )); return $items; } // the render function can focus purely on output function renderSkyscrapers($items) { echo "<h2>You searched for:</h2>"; // render the summary of what was searched for foreach($items->data('summary') as $label => $value) { echo "<p>$label: $value</p>"; } echo "<h3>Skyscrapers found:</h3>"; // note use of new implode() function, though a foreach() would be just as well here echo $items->implode(function($item) { return "<p><a href='$item->url'>$item->title</a></p>"; }); } WireArray::and() WireData::and() Return a new copy of the WireArray with the given item(s) appended. Primarily as a syntax convenience for various situations. This is similar to jQuery's add() and andSelf() functions, but I've always felt "add" implied adding something to the original rather than creating a new combination, so went with "and" in this case. The term "and" is actually a reserved word in PHP, so you can't usually have a function named "and()", but through the magic of hooks, ProcessWire can. This function should reduce the instances in which you'd need to do "$a = new PageArray();" for example. Usage: // create a new WireArray with $items and $item (appended) $myItems = $items->and($item); // create a new WireArray with $items and $moreItems (appended) $myItems = $items->and($moreItems); // create a new WireArray with $items and $item (prepended) $myItems = $item->and($items); // create a new WireArray with $item and $anotherItem (appended) $myItems = $item->and($anotherItem); // create a new WireArray 4 items $family = $pappa->and($mamma)->and($brother)->and($sister); Examples: // generate breadcrumb trail that includes current page foreach($page->parents->and($page) as $item) { echo "<a href='$item->url'>$item->title</a> / "; } // check if page or its children has a featured checkbox if($page->and($page->children)->has("featured=1")) { echo "<p>Featured!</p>"; }
    1 point
  12. One thing I think is important is that all of this advanced back-office functionality needs to be modular - for most sites out there none of this is needed, but for those that benefit from this level of complex management, offering a full solution is quite a game changer. Hey, I talk to myself all the time - or is that not the same problem??
    1 point
  13. @SiNNuT Will update the docs - 5.4 is the minimum version because of traits. Traits are only used in the ApplicationController and can easily be placed inline if that suites better. For us it generally doesn't matter as we use 5.4.
    1 point
  14. Ryan, I don't see need for it, at least not because of this module. Solution we have now should work as good as the earlier (I am bit disappointed that I didn't invented that, since it isn't codin magic, but plain old selectors...).
    1 point
  15. This is a php setting, so if you have access to your php.ini file you can adjust the max_execution_time there. If not, you could edit the profile export module's .module file and add this at the top: ini_set('max_execution_time', 300); That will give you 300 seconds, instead of the default 30. Of course any updates to the module will override this, but hopefully it will get you through this current task.
    1 point
  16. You mean like here https://github.com/somatonic/AutoSave/blob/master/AutoSave.module
    1 point
  17. Last days I'll see that for some inline text, the elements are faulty rendered to a default serif font. When hovering the element, the intended font-family is shown. After a page scroll the text gets back to normal most of the time. It effects lots/all webpages here with chrome 32 ones in a while. ( MacOSX 10.8.5. ) Do more people experience this ?
    1 point
  18. Give this module (attached) a try. To install, upload into /site/modules/ServicePinger/ServicePinger.module. Go to your Modules menu and click "check for new modules". Click install for ServicePinger. The module configuration screen has a textarea input where you can put in all the service URLs you want to ping. I recommend pinging one of the services that pings others, like pingomatic or weblogs.com, rather than trying to make this module do all of them. Actually, those are the only two services I've tested this with yet. When you install, it creates a new field called "pinger". Go and edit any templates you want to use it on and add the field "pinger". In your case, I'm thinking you'll just add it to the "post" template. Now edit a page with that template and see the "pinger" field you added. If you want it to ping those services, check the pinger box and save. You might want to test this out on one of your smaller sites first before migrating to your main site, as I put this together quickly and haven't yet tested it a lot. But I'm planning to add a README file and maybe a couple other details and then add it to the modules directory soon. ServicePinger.module
    1 point
  19. No, that's normal. Read ryan's post about it here: http://processwire.com/talk/topic/2387-the-structure-of-fields-and-templates/?p=22762 Basically, since any field can be used in multiple templates, you can't simply have a table for each template with the PW fields as mySQL table fields. Plus, several of the more advanced ProcessWire fields have multiple fields of their own in their table in phpMyAdmin (in fact I think most/all have more than one). Therefore any other way of storing them in the database simply wouldn't work as well and would presumably be a nightmare to program for.
    1 point
  20. I realise that Marty and many others fully understand the issues here, but for anyone else with similar problems, here it is in a nutshell... PW selectors use mySQL fulltext indexes (indices? I'm never sure) mostly, as they are very fast. However Fulltext indexes miss out some common words (stopwords) because they are too common to influence search results meaningfully for the most part. And Fulltext indexes ignore words shorter than 4 letters, unless you have enough control of the server to change that default behaviour. (Think VPS or better.) However PW's %= selector operator uses mySQL's LIKE operator, which while slower than a fulltext search, is still very fast (certainly on fewer than several thousand records) and isn't restricted by stopword lists or word length.
    1 point
  21. Hello, what is the proper way to save data to the database in PW? Lets say I create a template file which contains a form and I like to save some data to the database while using the PW templates (data templates not visual) with its fields Is the $fields->save($field) meant to be used for such kind of things ? How about more complex thing like the following: Lets say we have the following tables: User //the users Tags //the tags itself Tag-relations //stores the tag relations, contains references to document_id and the tag_id Documents // some kind of document such as pdf's, has a relation to a user How would I add tags to documents, while documents belong to a user ? Cheers Marc
    1 point
  22. Here is the same thing as a Textformatter module. To use, paste the following into /site/modules/TextformatterImagesToPages.module. Then, in your admin, to to Modules > Check for new modules. Click install on the new module. Then go to Setup > Fields and edit the field you want it to operate on ('body' for example). On the "details" tab, choose the "Images to Pages" text formatter, and save. The text formatter will be applied automatically when you access any $page->body field from the front-end of your site. /site/modules/TextformatterImagesToPages.module <?php class TextformatterImagesToPages extends Textformatter { public static function getModuleInfo() { return array( 'title' => 'Images to Pages', 'version' => 1, 'summary' => "Takes image links in HTML and converts them to page links." ); } public function format(&$str) { $rx = '{href="' . wire('config')->urls->root . 'site/assets/files/(\d+)/.+?"}i'; if(!preg_match_all($rx, $str, $matches)) return; foreach($matches[1] as $key => $id) { $page = wire('pages')->get((int) $id); if($page->viewable()) $str = str_replace($matches[0][$key], "href='$page->url'", $str); } } }
    1 point
  23. 1. I dont see a good way to check/inspect if my Jquery libs are correctly linked as are my CSS sheets. In Chrome, click 'inspect' element, then click the network tab inside the inspector, there you can see what is loaded.2. I want to debug step by step the PHP code. In your config.php put: $config->debug = true; // Under no circumstance should you leave this ON with a live site. echo out, var_dump variables, to see if they have the expected outcome. 3. Read or watch movies about PHP. 4. Be eager !
    1 point
  24. Dragan, have a look in your image/file field settings (Setup > Fields > your-file-field) on the "input" tab. There is a option there asking how many row you want available for the description.
    1 point
  25. Personally I really have no need for language translations (although perhaps I should - maybe it is a typical english speaker's arrogant oversight ), but I am still amazed at the work you have put in on this. It does make me think we need to revisit this topic though: http://processwire.com/talk/topic/2583-delivering-module-translations/
    1 point
  26. check_access, include ...shouldn't they go into the offiicial documentation? - I think they are pretty important!
    1 point
  27. I think I understand. I should say though that PW's fields and inputs are designed for administrative use rather than front end use. If I'm building something for the front end, I might still use PW pages to store the data, but I'm handling the input on my own and populating fields into page objects. That's what I recommend because you'll be able to do whatever you want without limitation and use PW's API in the manner it was built for. But if the Inputfields are suiting your need, then here's what you'd do to extend all of them. In the example, we add a hook to the field rendering (to add a select box with each one) and another hook to the input processing. This example module should be pasted into a file called /site/modules/InputfieldHookTest.module <?php class InputfieldHookTest extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Inputfield Hook Test', 'version' => 100, 'summary' => 'Just a test.', 'singular' => true, 'autoload' => true, ); } public function init() { $this->addHookAfter('Inputfield::render', $this, 'render'); $this->addHookAfter('Inputfield::processInput', $this, 'processInput'); } public function render(HookEvent $event) { $inputfield = $event->object; // optional, but better to limit to those you want if(!$inputfield instanceof InputfieldText && !$inputfield instanceof InputfieldTextarea) return; $name = $inputfield->name; $event->return .= "<p><select name='test_$name'><option></option><option>test</option><option>test2</option></select></p>"; } public function processInput(HookEvent $event) { $inputfield = $event->object; $name = $inputfield->name; $post = $event->arguments[0]; $value = $post["test_$name"]; if($value) $this->message("You selected '$value' for '$name'"); } }
    1 point
×
×
  • Create New...