Leaderboard
Popular Content
Showing content with the highest reputation on 11/03/2014 in all areas
-
6 points
-
Hi, I don't know if this is the right section for this but I collected some thoughts and a kind of manual about how to increase the performance of your website under load with nginx and fastcgi_cache. At best, this could be a kind of ProCache for nginx users, as not everyone is using Apache and thus not able to use ProCache on their sites. Additionally, this solution comes with the benefit of server side mobile detection and selective caching. http://svn.matthiashaak.com/website-performance-with-processwire-nginx-and-fastcgi_cache/ Please let me know your thoughts or questions about this. Be aware however, that with this solution you end up serving static pages, so no hooks or PHP functions will be called. I am currently working on a module that eases the cache purging, so kindly be patient if you need this. "Wait, and thou shalt receive"5 points
-
Maybe that comment tag could be more descriptive. Should we set a standard for modules that add markup?4 points
-
As far as I am aware, Google definitely don't use Meta Keywords, Bing definitely doesn't and it looks like Yahoo don't either. Keywords are also a lovely way of telling your clients' competitors what words are important to your client. I use them all the time - reading them from the competitor's website.3 points
-
Most likely your php.ini file has set error_reporting to some value that contains E_NOTICE Setting $config->debug = true; will do the same and show E_NOTICE. In a devlopment environment this can be desirable. On a live server i would change this to something like E_ALL & ~E_NOTICE See the following page for more information on error reporting. http://php.net/manual/en/function.error-reporting.php If you want to hide the notices when $config->debug = false; you should change error_reporting to E_ALL & ~E_NOTICE if you have access to the php.ini file.2 points
-
Hi everyone, I'd like to announce a complete overhaul of this module - problem is that I am not sure whether to release it as an update to this module, or perhaps as something completely new, perhaps called PageProtector. UPDATE: The functionality described in this post is available as a separate module: PageProtector This new version (not on github just yet) makes it very easy for site editors to set up various password protected areas on their site, or to simply protect a new page or section while they are still working on it. New functionality Ability for your site editors to control the user access to pages directly from Settings tab of each page Includes whether to protect all children of this page or not Optionally allows access to only specified roles Ability to change the message on the login page to make it specific to this page Option to have login form and prohibited message injected into a custom template Access to the above "Protect this Page" settings panel is controlled by the "page-edit-protected" permission Table in the module config settings that lists the details all of the protected pages Shortcut to protect entire site with one click What do you all think - replace the existing module, or release this functionality as a separate version? Module Config Settings Page Protection Settings2 points
-
Introducing ProcessDiagnostics and it's helper module suite. (Is this ProcessWire's first community-created module suite?) Description This suite adds a page under the setup menu that displays information about your installation. Each section's data is provided by a specialist diagnostic helper module but it is all collected and displayed by ProcessDiagnostics. The ProcessDiagnostics module itself does not encode any knowledge about what makes up a good or bad setting in PW - (that's done by the helper modules) - but it does the following... Gather the diagnosics (thanks to PW's hook system) Display the collected diagnostics Provide helper functions for describing some common things Dispatch actions to diagnostic provider modules (again thanks to PW's hook system) And eventually it will: Allow control of the verbosity of the output Allow the output to be emailed to a sysop Store the results between visits to the page Detect differences between results at set times Send a notification on detection of changes Although I am curating the collection, anyone is welcome to fork the repo, make changes in a topic branch, and submit pull requests. I've already had submissions from horst and Nico. Diagnostic Providers The current diagnostic providers include... DiagnosePhp - Simple diagnostics about the PHP envirnoment on the server DiagnoseModules - An ajax based module version checker by @Nico DiagnoseImagehandler - Lets you know about GD + Imagick capabilities by @horst DiagnoseDatabase - Checks each DB table and lets you know what engine and charset are in use DiagnoseWebserver - Checks the webserver setup DiagnoseFilesystem - Looks at how your directory and files are configured and warns of permission issues (currently incomplete) There is also a bare bones demonstration diagnostic module... DiagnoseExample - minimal example to get module authors started. Translations English & German (thank you @Manfred62!) Help translating this suite to other languages is always welcome. On The Net Check out Nico's blog post about this suite on supercode.co!1 point
-
This module adds a "SEO" tab to every page where you can define a special title, description, keywords, etc. Try it http://aluminum-j4f.lightningpw.com/processwire/ Name: demo Pass: demo123 How to use You can choose between include automatically or use the following methods: $config->seo // includes all the default values and configuration settings // e.g.: $config->seo->title $config->seo->keywords $page->seo // includes all the default values mixed with the page related seo data // e.g.: $page->seo->title $page->seo->keywords // for rendering: $page->seo->render . . Screenshot Download You can download it in the modules repository: http://modules.processwire.com/modules/markup-seo/1 point
-
Field Generator is a module to help you create random character strings and automatically assign them to one or multiple fields of your choice when a page is created. When setup, it will automatically do so whether you create a page through the administration panel or through code, meaning you don’t need to set $page->name or any other field of your choice, it just works automagically. Field Generator uses PHP’s openssl_random_pseudo_bytes() function to generate its random strings. It thus has both PHP >= 5.3.0 and OpenSSL as dependencies. Usage After installation, add rules through Setup > Field Generator. That’s it! Rules only run when first creating the page. For more information : https://github.com/plauclair/FieldGenerator Release : Version 0.9.0 This is the initial release. This is near stable and you shouldn’t be too worried to use it in production. Here is a screencast on how to use it.1 point
-
Websites often provide content not only as on list of stuff, but with some sort of category. The most flexible way in ProcessWire to manage such a categorization are with PageFields. Form example with a structure like this. - Magazine (magazine) - Articles - Article 1 (article) - Article 2 - Article 3 - … - Categories - Category 1 (category) - Category 2 - … Templatenames in parentheses Now all articles have a url structure like: "…/magazine/articles/articlename/" The categories are looking like: "…/magazine/categories/categoryname/" But it can be useful to also provide the articles as part of the categories like this: "…/magazine/categories/categoryname/articlename/" Because ProcessWire doesn't provide such functionality by default, we'll use urlSegments. These have to be enabled in the template-settings for the category template. This template therefore fulfills two different jobs. Displaying a list of containing articles, as well as rendering the articles which are linked by the list. A simple example of a existing category.php could be: <?php // category.php $articles = $pages->find("template=article, category=$page"); // This example uses a deligated template approach. // Feel free to use your own way of templating, // but this is also a simple way to explain this. $content = renderArticleList($articles); include("./_main.php"); Now we need to include the logic to seperate the default rendered article-list to the now added rendering of the called article. <?php // category.php // Throw a 404 Error if more than one segment is provided if($input->urlSegment2) throw new Wire404Exception(); if($input->urlSegment1){ // Show the called article // Sanitize the input for pageNames $name = $sanitizer->pageName($input->urlSegment1); // Search for the article with this name $article = $pages->get("template=article, name=$name"); // Throw an 404 error if no article is found if(!$article->id) throw new Wire404Exception(); // Explicitly set the original url of the article for the <link type="canonical" href=""> tag $article->canonical = $article->url; // Render the page, like if it was normally called. // $page->url will not updated to the "categorized" url for the rendering-part // so you need to have that in mind if you provide some sort of breadcrumb echo $article->render(); }else{ // Show the list of articles of the current category $articles = $pages->find("template=article, category=$page"); // The generateCategoryUrls() function is new, because // $page->url would provide the wrong urls. // Details are provided later $content = renderArticleList( generateCategoryUrls($articles, $page) ); include("./_main.php"); } Now if we call this "…/magazine/categories/categoryname/articlename/" we'll get the right article rendered out instead of the article-list. Now we need to talk about the article-list, which would - without changes - still render the "wrong" urls to all those articles. Therefore I added the generateCategoryUrls() function. This function iterates over the pageArray and adds a second url to all those articles. <?php // part of _func.php function generateCategoryUrls($list, $category){ foreach($list as $item){ $item->categoryUrl = $category->url.$item->name."/"; } return $list; } The last thing missing is the actual template which gets rendered by renderArticleList(). This would normally call for $article->url to get the url to the article. We want this to render our second url if we are on a category site. To let the template still be useable by non category sites, we just change the parts, where to url is used form the current $article->url to $article->get("categoryUrl|url"). Only if the additional urls are provided they get rendered or it falls back to the normal urls of the articles. There we go, with such a setup all categorized articles are reachable via both urls. A small addition to explain the $article->canonical I used in the category.php. For SEO it's not good to provide the same content on multiple pages without explicitly declaring which of the duplicated ones should be the original / indexed one. By providing the following link tag we provide this declaration. The extra field I use isn't really necessary, because $page->url still is the standart ProcessWire url of the shown article. But I like this to be visibile in the code, that this is a dublicate. <link rel="canonical" href="<?php echo $page->get("canonical|url") ?>"/> Hope you like the explanation. Feel free to give feedback on this. Based on the example shown in the wiki: http://wiki.processwire.com/index.php/URL_Segments_in_category_tree_example1 point
-
Today I've created a really simple little module that is configurable and attaches to hooks. So it has more or less everything of a real world module in it. I thought processwire beginners would be interested in reading how to create such a module so I added some comments to the source code in a way the module should explain itself... Here it is: /** * BackgroundChanger module for demonstration purposes * * Demonstrates the Module interface and how to add hooks in a more real world manner... * * ProcessWire 2.x * Copyright (C) 2014 by Domenic Helfenstein * */ class BackgroundChanger extends WireData implements Module, ConfigurableModule { public static function getModuleInfo() { return array( /* * the __("text") methods are used for multilanguage support * see: https://processwire.com/api/multi-language-support/code-i18n/ */ 'title' => __('BackgroundChanger'), 'summary' => __('This is a simple real world module that can change the background color.'), 'version' => 105, /* * autoload must be true if the module depends on hooks * see: http://wiki.processwire.com/index.php/Module_Creation#Details_of_what_the_.22autoload.22_property_means */ 'autoload' => true, /* * it is wise to run modules in singular mode when using hooks * see: http://wiki.processwire.com/index.php/Module_Creation#Details_of_what_the_.22singular.22_property_means */ 'singular' => true, ); } public function __construct() { //set default values $this->backgroundColor = 'yellow'; /* * !!! the value in the db will be automatically injected into this var * because it is named equal to the value of $field->name in * getModuleConfigInputfields !!! */ } public function init() { // add a hook after each page is rendered and modify the output $this->addHookAfter('Page::render', $this, 'changeBackground'); } public function changeBackground($event) { $page = $event->object; //do only modify non-admin pages if($page->template == 'admin') return; $extension = <<< _OUT <style> body {background-color:{$this->backgroundColor};} </style> _OUT; $event->return = str_replace("</head>", $extension."</head>", $event->return); } public static function getModuleConfigInputfields(array $data) { //create a fieldset $inputfields = new InputfieldWrapper(); //create field for background color $field = wire('modules')->get('InputfieldText'); $field->name = 'backgroundColor'; $field->label = __("Enter the hex-code or name of the desired background color. (visit colorpicker.com)"); //if there is already a value stored, set this value to the field if(isset($data['backgroundColor'])) $field->value = $data['backgroundColor']; //add the field to the fieldset $inputfields->add($field); //return the fieldset to display return $inputfields; } } I hope this helps others creating their own modules! BackgroundChanger.module1 point
-
Out of interest, do you have any details on the Bing and Yahoo parts? Google is obvious, but as far as I can tell, Bing and Yahoo still use keywords, though they're not exactly important ranking factors (quite the opposite, really -- they seem to have much less weight than regular body copy). Also, for anyone targeting the Russian or Chinese markets, it should be noted that Yandex specifically suggests using meta keywords (they're not revealing how important these are as ranking factors though) and according to some sources Baidu considers meta keywords "very important" (though keyword stuffing is a major negative signal there too).1 point
-
Just going to add a note for something I noticed. When building your selector don't use the revers() sorting/filtering function as makes renderPager() output nothing. So use sort=something in the selector instead. I went with sort=created to sort the pages by created date.1 point
-
Or even: <!-- Diogo says that I should tell you that this bit of code is to do with that very nice EMO module, okay? -->1 point
-
Sass is one of those things that will save you tons of time in the end. The mostly difficult part (depending on your code editor) is getting your environment all set up. I use Sublime Text 3, so there are packages and build systems for it that can be installed in a minute or 2. Might take a little longer depending on what you use.1 point
-
1 point
-
The first issue was fixed and will be available in the dev branch. You mention that you see the System Updater messages on each page load in the admin section, this is something Ryan might have to take a look at since it actualy has to run only once, so it seems its not applying the system updates in the database. On PW 2.5.6 and 2.5.7 i do not see these notifications when $config->debug = true; edit: forgot the not in "i do not see"1 point
-
Are you using email obfuscation? That script is the email obfuscator doing its job.1 point
-
@toothpaste: I need much more information. Please paste the error message you get. I'm using the latest ProcessWire as well and everything is going well.1 point
-
Report: So I ended up modifying the core to cope with this... (yeah I know this is not a good idea but I need this to be functional for my Chinese clients) In WireUpload.php line 240 I added: $filename = 'file-' . $filename; after: $filename = $this->getTargetFilename($filename); $filename = $this->validateFilename($filename); This will force every file uploaded to start with a 'file-' prefix so that the system will not have files with a filename consisting Chinese characters only. However I ran into another problem: If I upload 'test.jpg', I get 'file-test.jpg' which is good. But if I upload '未命名.jpg', I get 'file-' instead, missing the extension. Then, if I upload '未命名.jpg' again, I get 'file--1.' again missing the extension but with a trailing dot... This inconsistency is really just weird to me. For English filenames I got the extension, for the first Chinese filename I got the filename without the extension. And if I upload another file of Chinese filename, I got the filename and the dot (e.g.: file--1. ) Despite all this, I can still view these files as images in my browser, so ...../file-test.jpg , ...../file- , ........../file--1. all display the image without any error. If I insist I need to modify the core in order to make this work (before any official fix is available). Where is the best place to do so? The way I did it works in some sense but produces all these weird filenames which are not really desirable. Anyone familiar with the core willing to help out here? Thank you so much in advance!1 point
-
Hi hettiger, Welcome to ProcessWire! Do you have template cache enabled or using MarkupCache by any chance? If it's a multilang site: Does the guest user maybe have a language where the image description isn't filled/translated? Cheers1 point
-
This is clearly a common request and just needs to be added to the core. @ryan I went ahead and added a "checked by default" option - please have a look.1 point
-
Yeah, I just thought it would be nice to get language updates via module manager1 point
-
Hey, I would love to have something like $config->defaultTemplateFile in the config.php. What it should do: If set to "true" every template (except admin of course) should use the defined template file instead of its own. If you want to use another file (or the default file like page.php for page) you have to define it as "alternate template filename". Advantage: It's great if you're using a ajax driven site if you don't have to set every template to use e.g. "main.php" or "app.php" or whatever. What do you guys think? -- Nico1 point
-
Nico, I like what you are getting at, but think an option like that might be a source of confusion because it would change the entire way that templates work, as well as the way that viewability is determined. Most likely this would be problematic for PW's internal templates and logic. What I would suggest instead is repurposing of the existing $config->appendTemplateFile option and letting that serve is your defaultTemplateFile. In order to make sure that PW considers your page viewable, you'd still have to have a file for the template, but it could be completely blank. While I'd prefer the method mentioned above, another alternative would be to automatically populate the altFilename property of every template that you wanted to behave this way. For example, in your /site/templates/admin.php file you could add something like this: foreach($templates as $template) { if($template->flags & Template::flagSystem) continue; if($template->filenameExists()) continue; $template->altFilename = 'ajax.php'; $template->save(); }1 point
-
You could fix this by modifying the given line from if($data['searchFields'] == 'title body') { to if(isset($data['searchFields']) && $data['searchFields'] == 'title body') { Seems that $data['searchFields'] is undefined, thats causing it to throw a notification. In general notifications are not much of a problem, altough if it occurs a lot the error.log file can grow tremendously large. I remember having to look at a site suffering from undefined variables in a loop, causing it to write 5 lines to the log file for every visitor to the page, by the time the problem was noted the log file was over 2 GB. Not that the specific notification you mention will do that, as far i know that SystemUpdate script is only run once.1 point
-
1 point
-
I hate to resurrect an old topic, but the page-publish permission does not work... was this changed since this was posted? Edit- Um, never mind. Its page-publish not page-publsh I feel so dumb...1 point
-
Its down to me finding time to learn, really. The list of things to learn is getting depressingly long.....1 point
-
So the only thing missing now is an official PW Shirt. Maybe I'm going to make one in the copyshop next to my flat1 point
-
I wouldnt recommend using my code as it was merely to demonstrate how i did it inside a module. SInce the module isnt standalone and still in development its no use to give the full code. Besides that using a scope (like public, private, protected) for a function/methods can only be used inside a class. When you define a function outside a class leave away the scope. function actionHybridAuth() { // rest of the code } But again using my code without the rest of the modules that belong with it will not work. Sorry i cant be much of a help there. Anyway i would recommend to read some into using classes, methods and such, since the HybridAuth is a class by itself. Implementing it in to your ProcessWire project will require some basic understanding of how to use PHP classes and methods.1 point
-
You could make a template that initializes the Hybrid Auth class, assign it to a page and use that as endpoint URL. For example: /** * Provides HybridAuth actions * */ public function ___actionHybridAuth() { if (!$this->isHybridAuth) return; if ($this->page !== self::$fup['hybridauth']) return; if ($this->sanitizer->name($this->input->urlSegment1)) { $this->initializeHybridAuth(); } else $this->endpointHybridAuth(); } /** * Initializes HybridAuth endpoint * */ public function ___endpointHybridAuth() { if (!$this->isHybridAuth) return; if ($this->page !== self::$fup['hybridauth']) return; @require_once (dirname(__FILE__) . '/Hybrid/Auth.php'); @require_once (dirname(__FILE__) . '/Hybrid/Endpoint.php'); Hybrid_Endpoint::process(); } (note: above example is part of a module i'm working on, the code is just for illustrating a way of using hybridauth class inside a module, the code itself wont do much without the rest of the module)1 point
-
Hybrid Auth will look for a path or array that you pass as $ha_config in to new Hybrid_Auth( $ha_config ); So if you have a config file somewhere assign its path to $ha_config before you assign an instance of the class. Altough in the project i'm working on i'm passing an array with all the config values into it. /** * Gets HybridAuth config data from module configuration settings * */ public function ___getHybridAuthConfig() { if ($this->page->template == "admin") return; if (in_array('active', $this->get('hybridauth'))) { $this->isHybridAuth = true; $this->hybridAuthConfig = array( 'base_url' => $this->getHybridAuthBaseUrl(), 'providers' => array( "AOL" => array( "enabled" => $this->get('hybridauth_aol_status') == 'enabled' ? true : false ), "Facebook" => array( "enabled" => $this->get('hybridauth_facebook_status') == 'enabled' ? true : false, "keys" => array( "id" => $this->get('hybridauth_facebook_app_id'), "secret" => $this->get('hybridauth_facebook_app_secret') ), "trustForwarded" => in_array('trust_forwarded', $this->get('hybridauth_facebook_trust_forwarded')) ? true : false ), "Foursquare" => array( "enabled" => $this->get('hybridauth_foursquare_status') == 'enabled' ? true : false, "keys" => array( "id" => $this->get('hybridauth_foursquare_app_id'), "secret" => $this->get('hybridauth_foursquare_app_secret') ) ), "Google" => array( "enabled" => $this->get('hybridauth_google_status') == 'enabled' ? true : false, "keys" => array( "id" => $this->get('hybridauth_google_app_id'), "secret" => $this->get('hybridauth_google_app_secret') ) ), "LinkedIn" => array( "enabled" => $this->get('hybridauth_linkedin_status') == 'enabled' ? true : false, "keys" => array( "key" => $this->get('hybridauth_linkedin_app_id'), "secret" => $this->get('hybridauth_linkedin_app_secret') ) ), "OpenID" => array( "enabled" => $this->get('hybridauth_openid_status') == 'enabled' ? true : false ), "Twitter" => array( "enabled" => $this->get('hybridauth_twitter_status') == 'enabled' ? true : false, "keys" => array( "key" => $this->get('hybridauth_twitter_app_id'), "secret" => $this->get('hybridauth_twitter_app_secret') ) ), // Windows Live "Live" => array( "enabled" => $this->get('hybridauth_windowslive_status') == 'enabled' ? true : false, "keys" => array( "id" => $this->get('hybridauth_windowslive_app_id'), "secret" => $this->get('hybridauth_windowslive_app_secret') ) ), "Yahoo" => array( "enabled" => $this->get('hybridauth_yahoo_status') == 'enabled' ? true : false, "keys" => array( "key" => $this->get('hybridauth_yahoo_app_id'), "secret" => $this->get('hybridauth_yahoo_app_secret') ) ) ), // If you want to enable logging, set 'debug_mode' to true. // You can also set it to // - "error" To log only error messages. Useful in production // - "info" To log info and error messages (ignore debug messages) "debug_mode" => "", // Path to file writable by the web server. Required if 'debug_mode' is not false "debug_file" => $this->config->paths->logs . "hybridauth.txt", ); } }1 point
-
SEO Module? What is this? 1999 again? But seriously:1 point
-
Martijn, I know that. Even Mac, though being a unix, is not case sensitive by default. But that is not the issue. If the name is the same regardless of the case of letters, it should replace the file. I prefer the system not to touch my filenames by some algorithm, but give me the possibility to keep the uppercase letters. By the way, I like the new addition of file replacing the file with the same name that was just introduced in the latest dev-versions, because I think it was annoying that I first had to remove the file before replacing with a new version of the same file.1 point
-
+11. Nope, not a typo -- just how much I want this to happen. I'm not much of a fan of AJAX driven sites, but I do tend to implement template level front controller pattern to all the sites I work on. Being able to route all requests to specific file without having to define that file separately to each and every template as an alternate template file would be very, very nice addition.1 point
-
Using MarkupCache and needed to switch the page to MultiLanguage. First I thought oooh my god how can I achieve this without having code duplications within complex conditions?! But it's PW (in this case it's just PHP logic^^) but PW is great! You "only" have to set the name of the cache file dynamically based on the language. Nothing easier than that. Just replace the normal initialization of the cached section from <?php if(!$data = $cache->get("something")) { to <?php if (!$data = $cache->get("something_lang-{$user->language->name}")) { Then, assuming whe have 2 languages, default and de, it's generating one cache file called "something_lang-default" and "something_lang-de" of course you can set the name format to whatever you prefer Just wanted to share my achievement for everyone else looking for MarkupCache on a multi language site cheers Can1 point
-
Just used this on a 2.4 site and it looks like it is working AOK (only noting that since the listing does not mention 2.4 compatibility). I've probably said it before, but this Module provides functionality for which there is in my view a good case for including in core PW. Providing a DRY way to manage assets is very valuable. The only 'big' thing I would love to work out how to provide, via this Module I assume or via the image or file field, is an easy way to swap a file for a replacement. This too I think has been a big-ish discussion before and I think it's not as simple as I am assuming. All I know from management of a large TextPattern site is however that a centralized place to see all assets and from where you can easily re-upload a new version or a file or image is a real boon. Oh for enough spare synapse that I could add this functionality myself and give back to the community, sorry I'm too thick!1 point
-
I'm not exactly sure what you're thinking "combine" means here, but this field does exactly what the description says; it grabs data from other fields, mashes it all together into one big blob of (JSON) content -- and that's just about it. One very simple (yet sometimes very practical) use case is if you've got, say, 15 different text fields and you need to find pages that contain value "john doe" in any of those. Instead of doing this: $john_does = $pages->find('field1|field2|field3|field4|field5|...|field15%="john doe"'); .. you can create a cache field, select all of those fields to be cached in it, and then do this: $john_does = $pages->find('my_cache_field%="john doe"'); Not only does this look clean, in certain situations it can wildly improve query performance.1 point
-
thanks Soma. Yup got it working with this: $page = $event->arguments('page'); $clone = clone($page); $clone->uncache(); $this->pageStatusBeforeSave = $clone->myfield;1 point
-
Not sure if you got it working or not, but I did a quick test and you you're right it doesn't save formated fields like page fields. I got it working by creating a clone of the saved page and then uncache and get the page from DB to get old value. Now it also saves the page fields. public function saveReady($event) { $p = $event->arguments("page"); $p = clone($p); echo "new headline: " . $p->headline; // debug $this->pages->uncache($p); $old = $this->pages->get($p->id); // get page from db echo " | old headline: " . $old->headline; // debug // exit(); // debug }1 point
-
Adding the style to valid elements solves the problem to not get stripped of in tinymce. Works fine here and I use it all the time. When I remove the style from valid elements tinymce strips the inline style when viewing source thus also on save even though the text is aligned when clicking align button.1 point