Leaderboard
Popular Content
Showing content with the highest reputation on 05/26/2014 in all areas
-
here i'am I am sending my greetings to all cool guys here! WB was great CMS Idea easy especially for the "end"user - but like argos wrote it was...and has missed it's own future. (there are several Forks out there but no big communites - it's more like dividing the good guys and that sucks and helps nobody.....but like argos said my fist impression from processWire... It's my feeling, too I was a old-timer for WB CMS like setup a portable-project in 2009 (http://www.websitebaker-portable.com/CMS/en/about-portable-edition.php), helped with a tutorial project and did a lot of other stuff there (Like Argos forum Mod/Admin and so on). My idea of open source is take a free software and give work and time back to enhance the project. So i hope to find.. So far i read this forum - i'd like the sound and the way of treatment! Please excuse my bad english (bad german style...) so long Best Regards until the next post mr-fan6 points
-
The Module Blog for ProcessWire replicates and extends the popular Blog Profile. Blog is now in version 2. Please read the README in the Github link below in its entirety before using this module As of 20 December 2017 ProcessWire versions earlier than 3.x are not supported Blog Documentation is here (Work in Progress!) See this post for new features in version 2 or the readme in GitHub. To upgrade from version 1, see these instructions. ################################################## Most of the text below refers to Blog version 1 (left here for posterity). Blog version 1 consists of two modules: ProcessBlog: Manage Blog in the backend/Admin. MarkupBlog: Display Blog in the frontend. Being a module, Blog can be installed in both fresh and existing sites. Note, however, that presently, ProcessBlog is not compatible with existing installs of the Blog Profile. This is because of various structural and naming differences in respect of Fields, Templates, Template Files and Pages. If there is demand for such compatibility, I will code a separate version for managing Blog Profile installs. In order to use the 'Recent Tweets Widget', you will need to separately install and setup the module 'MarkupTwitterFeed'. Please read the README in the Github link below in its entirety before using this module (especially the bit about the Pages, etc. created by the module). I'll appreciate Beta testers, thanks! Stable release works fine. Download Modules Directory: http://modules.processwire.com/modules/process-blog/ Github: https://github.com/kongondo/Blog You can also install from right within your ProcessWire install. Screenshots (Blog version 1) Video Demos ProcessBlog MarkupBlog Credits Ryan Cramer The Alpha Testers and 'Critics' License GPL25 points
-
ProcessWire 2.4.2 Turkish Core Translations Status (100%) and some of modules translations included. Turkish Translation Github Repo (For Support)4 points
-
Ajax is working. Deactivated "autoload" stuff (don't need it). New pull request is on it's way4 points
-
I see two problems One, on this line, since this is within the foreach, everytime it gets a new record (page) - i.e. on each new loop, you are wiping out the previous value of $out...hence, in your last code, it will only output the last record having wiped out all previous ones. $out = "<div class='referenceTeaser post'>"; The second problem is with your first code; you are returning $out within the foreach. It should be outside the foreach. The idea is that you need to return what you want to finally output/use...So, we don't return anything too early... Try the below code, modified from your second code attempt. We first initialise $out outside the foreach...Subsequently, we concatenate it. In addition, it is not always a good idea to use the same variable name for different things. E.g., you already have $page = wire('page'); In your selector, I would use $children = ...blah blah. function renderReferenceList() { $out = '';//initialise the variable $out //$page = wire('page');//no need for this as well $pages = wire('pages'); //$page = $pages->get(1065); // Referenzen//no need for this here; combined below $children = $pages->get(1065)->children("limit=15, sort=-date");//changed variable name to $children foreach($children as $child) { $out .= "<div class='referenceTeaser post'>";//note the concatenation $out .= "<h3 class='articlehead'>{$child->headline}</h3>"; $out .= "<p>" . $child->summary . "<a href='{$child->url}'><i class='more'>Referenz ansehen</i></a></p>"; $out .= "</div>"; } return $out; }4 points
-
@Nico, I made the collection of diagnostics hookable to allow extension of the core collection and eventually allow all the collection to be outsourced. I already have a proof-of-concept "ExamineDatabase" diagnostic collection module (as yet unpublished) that hooks into this nicely. There's no reason why ProcessDiagnostics can't be extended by Soma's excellent Module Manager or even a "ExamineModules" diagnostic provider. Here's what I plan on adding to ProcessDiagnostics... Verbosity control (Low, Medium & High settings). Low => Only failures are listed, Medium shows failures and warnings while high shows everything. An "Email Report To" button allowing the generated report to be sent to your friendly sysops person. Storage of diagnostic results and detection of diffs between runs. Automatic squawking via a channel (SMS?, Email (yes!), Twitter?) when changes are detected. Move all diagnostic collection out into dedicated "Examine" modules, leaving ProcessDiagnostics to focus on aggregation, storage, diff detection and communication of the results. I hope that makes sense. Let me know if you think of other things to add to ProcessDiagnostics and feel free to work on "ExamineXyz" modules that hook into it.4 points
-
4 points
-
Just use the wonderful CropImage module. Say, you have a 300x300 image in your template. Define one 300x300 called "thumb" and one 600x600 crop called "thumb2x". Now you can use the picture polyfill like this: <picture> <img srcset="<?= $page->myimage->eq(0)->getThumb('thumb') ?>, <?= $page->eq(0)->myimage->getThumb('thumb2x') ?>, 2x" alt="<?= $page->myimage->eq(0)->description ?>"> </picture> Adding additional breakpoints with <source> is also possible (from the picturefill docs): <picture> <!--[if IE 9]><video style="display: none;"><![endif]--> <source srcset="examples/images/large.jpg, examples/images/extralarge.jpg 2x" media="(min-width: 800px)"> <source srcset="examples/images/small.jpg, examples/images/medium.jpg 2x"> <!--[if IE 9]></video><![endif]--> <img srcset="examples/images/small.jpg, examples/images/medium.jpg 2x" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia"> </picture> So you can also do some art direction where you output not only different sizes but also different formats (for example 2:1 on mobile, 1:1 on desktop etc)4 points
-
@horst Added your Image diagnostics and implemented sections. I updated the image in the opening post to show the results.4 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!3 points
-
Update: And we are off...'Blog' is now available in the modules directory. Updated first post...3 points
-
3 points
-
ProcessDiagnostics must be in the core! In line 264 'action' => $ht_ok && !$ht_write ? '' : $this->_('.htaccess must exist, must be readable, should <strong>not</strong> be writable.'), //replace <strong> with ** 'action' => $ht_ok && !$ht_write ? '' : $this->_('.htaccess must exist, must be readable, should **not** be writable.'), the double asterisk are for bold text in translation-files. But in this case it's not working?? Maybe one of the pro's can check this? Example in ProcessTemplate.module, line 922, 923 BTW: german translations nearly done...3 points
-
Guys, sorry to hear about the issue. I've never used RewriteBase before so I can't simply answer this but it strikes me there must be something @DV-JF can identify that's different between his two test sites. Firstly, how is the neu subdomain .htaccess different from the main domain .htaccess? Are you using RewriteBase in the subdomain case? Secondly, what version of PW are you running? Thirdly, I assume that commenting out RewriteBase in your .htaccess file and restarting the server causes PW's admin interface to stop working? Edited to add 1: It seems to me that RewriteBase only changes how the path part of a url is handled yet you are seeing problems with the domain part. I suspect this is some combination of your site's virtual host entry + file layout problem + .htaccess rather than something major in PW but I could be wrong. Edited to add 2: Are you 100% sure you ftp'd up a .htaccess file into www/sports-vitality.de/? and that it's readable by the webserver process? Also, is there a .htaccess file in www/? I see from Stack Overflow that you can get double domain parts if you are missing a readable .htaccess where you expect it (or it doesn't have mod_rewrite info) but one exists in the parent directory.3 points
-
Should I do module update stuff as a separate module or should it be part of the core? At least here is the code: /** * Returns a diagnostic array about installed modules and looks for updates */ protected function getModulesDiagnostics() { $defaultServiceUrl = 'http://modules.processwire.com/export-json/'; $defaultServiceKey = 'pw231'; $modulesRemoteVersions = (array)$this->session->get('ModulesRemoteVersions'); foreach($this->modules as $module) { $moduleInfo = wire('modules')->getModuleInfo($module->className()); $localVersion = $this->formatVersion($moduleInfo['version']); // check if core module $core = false; $pathParts = explode('/', str_replace($this->config->urls->root, '', $this->config->urls->{$module->className()}), 2); if($pathParts[0] == 'wire') { $core = true; } // only show installes /site/ modules if($core == false) { // if remote ersion is in session use this one otherwise load remote version from ... remote. if(!in_array($module->className(), array_keys($modulesRemoteVersions))) { $url = trim($defaultServiceUrl, '/') . "/".$module->className()."/?apikey=" . $defaultServiceKey; $http = new WireHttp(); $data = json_decode($http->get($url)); if($data->status != 'error') { $remoteVersion = $this->formatVersion($data->module_version); $modulesRemoteVersions[$module->className()] = $remoteVersion; } else { $modulesRemoteVersions[$module->className()] = $localVersion; } } $updatable = ($modulesRemoteVersions[$module->className()] > $localVersion); $updateUrl = $this->config->urls->admin.'module/?update='.$module->className(); $results[] = array( 'title' => $moduleInfo['title'].' ('.$module->className().')', 'value' => $updatable ? $this->_('Update available') : $this->_('Up to date'), 'status' => $updatable ? self::$warn : self::$ok, 'action' => $updatable ? sprintf($this->_('There is a new version available. <a href="%s">Click here to go to update page.</a>'), $updateUrl) : '', ); } } $this->session->set('ModulesRemoteVersions', $modulesRemoteVersions); return $results; } protected function formatVersion($version) { return preg_replace('/(\d)(?=\d)/', '$1.', str_pad( (string)$version, 3, '0', STR_PAD_LEFT)); }3 points
-
@Raymond Geerts - I ended up writing the login code in a template rather than a module (i figured it worked better that way). The code for integrating users is essentially taken from apeisa's Facebook Login Module - https://github.com/apeisa/FacebookLogin/blob/master/FacebookLogin.module code for authenticating with hybridauth: $hybridauth = new Hybrid_Auth( $ha_config ); $adapter = $hybridauth->authenticate( $provider_name ); $user_profile = $adapter->getUserProfile(); once you have successfully logged a user in with one of hybridauth's providers, you essentially need to call the processLogin function with the $user_profile object (I've made some modifications but they may not be necessary): Note: I have created a field - social_id and assigned it to users template. $social_id = $user_profile->identifier; $display_name = $user_profile->displayName; //you can capture additional information like email address, profile url, profile photo, etc from $user_profile object. see hybridauth for additional details. $name = $sanitizer->pageName($display_name, true).'-'.$social_id; $u = $this->users->get("social_id=$social_id"); // First we create random pass to use in login $uniqid = uniqid(); $pass = sha1($uniqid . $social_id . /*additional parameters can be added here*/); // User has logged in earlier with facebook id, great news let's login if ($u->id) { $u->of(false); $u->pass = $pass; /*$u->addRole(self::name);*/ //you can define a role for users $u->save(); } else { // User has not logged in before and autogenerate is on //I'm not using this but feel free to use this if you like. /*else if (!$this->disableAutogenerate) { $name = $this->sanitizer->pageName($fbUserData->name, true); $u = $this->users->get("name=$name"); // If there is already user account with same name than current logger has in facebook, then add a running number as a suffix //since i'm appending unique social ids in usernames, this problem will never arise if ($u->id) { if (!isset($fbUserData->counter)) { $fbUserData->counter = 2; $fbUserData->origName = $fbUserData->name; } else { $fbUserData->counter++; } $fbUserData->name = $fbUserData->origName . $fbUserData->counter; $this->processLogin($fbUserData); } */ // All seems to be fine, let's create the user // this is the main part $u = new User; $u->name = $name; $u->social_id = $social_id; $u->pass = $pass; /* $u->addRole(self::name);*/ $u->addRole("member"); //i've added a role called member //you can create additional fields like email, profile url, etc and add them here. $u->save(); } $this->session->login($name, $pass); $this->session->redirect(/*httpUrl*/); My code is a bit different as per my requirements, but the above code should work for basic hybridauth authentication and integration with PW users. Feel free to modify the code to suit your requirements. Hope this helps. Cheers!3 points
-
Great one. I was thinking about having this is PW just a couple days ago... and if you wait long enough someone else will do it I think this would be a must have in Core.3 points
-
2 points
-
@looeee, Welcome to the forums! I'm glad the module is of benefit... Currently, there is no comment moderation within Blog itself. This is deliberate. You have two choices: 1. You can install the module 'Comments Manager' to manage all your comments in one place. It would have been nice to integrate Blog and CM better but currently there are no plans to do so. 2. You can moderate comments on a per post basis. Just edit a post and you will find all comments awaiting your approval2 points
-
Try instead of: echo $out; this: return $out; You are now echo'ing the output within the function which is called before in your template file. With return it is outputted within the function renderReferenceList().2 points
-
:) even www.treasury.gov uses processwire !!! :) https://www.google.nl/#q=sort+results:processwire/talk&start=30 ps. just a joke: they use in-process wire transfer, but talk about promoting...2 points
-
2 points
-
2 points
-
You already have the code i see. Looks like a good solution. So method A is the right way to do so in this case. When you want to retreive a subset of data for example 4 pages out of 1000 records in the database i recommend sorting on database level (like you did in your code). This will be faster since the database fields all are indexed. And it saves you from loading the 1000 records in to memory and sorting it afterwards and then limiting. Because if you would limit it before sorting you never will get the right results.2 points
-
Or you could use this undocumented feature: Edit your /site/config.php and set $config->advanced = true; In your admin, go to Setup > Templates > your-post-template Click to the "System" tab. See the last field: "Allow the created user to be changed on pages?" Check that box and Save. Restore your config.php back to normal: Edit your /site/config.php again and set $config->advanced = false. Now you should be able to change the "Created User" on the Settings tab of any pages using that template.2 points
-
Since you are creating a user for each author, you can simply use a page reference field for this. If a user is selected on that field, that's the one considered the author, if there is no user selected it's assumed that the author is the user that was logged when posted. $author = $page->get('author|createdUser'); //if chosen "Single page (Page) or boolean false when none selected" on the field settings Of course not all authors have to be users. You could also have a "author" template, and create all authors there. In that case you could do something like: $author = $page->author ? $page->author : $pages->get("template=author, name={$page->author->name}"); edit: none of those were tested, i just want to illustrate a concept2 points
-
Here's a video of a module we're working on that I thought you guys might like. The module, Lister, provides a different type of Page List than the tree that you usually interact with in ProcessWire. It gives you a table of pages with customizable columns, filters and actions. Rather than try to explain what it does, I figured I'd show you. This module also uses a new (soon to be released) Inputfield invented by Apeisa, developed by me, and sponsored by Avoine, called InputfieldSelector – it's what you see on the configuration screen as well as the Filters tab. I recommend bumping up the size/quality to 720p so that you can properly see everything. The video has no sound... I tried to do one with narration, but that didn't work out.1 point
-
Great thanks! The comments manager is just what I was looking for. To make it it a bit more integrated I just moved the "Comments Manager" page from /admin/setup to /admin/blog, which doesn't seem to have caused any problems. A couple of things: to get widgets from the sidebar to display on non-blog pages, the module has to be called on every page: //CALL THE MODULE - MarkupBlog $blogOut = $modules->get("MarkupBlog"); I've just added it to the top of my sidebar.inc for the time being, I'll have to refactor my code a bit in the future to stop it being called twice on blog pages. Second, to get posts to show only an excerpt, in the template files change the line: $content .= $blogOut->renderPosts("limit={$limit}"); to $content .= $blogOut->renderPosts("limit={$limit}", $small=true); Currently it looks like the excerpt length is hardcoded to 450 characters - perhaps adding an option for people to set this themselves would be a good idea? In the meantime, for anyone that wants to change this, find the line $summary = strip_tags(substr($page->blog_body, 0, 450)); in MarkupBlog.module and set it to whatever you want. Great work, I'm getting more impressed the more time I spend with it!1 point
-
I think it would be much better if you could do this, for example: $options = array('crop'=>false, 'upscaling'=>false, 'withretina'=>true); $image = $image->width(400, $options); and it creates an image with width = 400 and one with width = 800 and add a @x2 or a x2 to the filename of the latter one. Also I think this is actually possible with the latest dev version and a little module.1 point
-
Yes, because the part behind the questionmark (in your case "?sort=titleASC") probably disappears if you're clicking a link. So you would have to add it to the pagination link as well. Didn't read the first line1 point
-
@dazzyweb: you should not use this quick fix anymore but use the dev version of PW. Speaking about image issues is hard to understand, best would be if you could create 2 or 3 thumbs of same dimensions from the same image and name the files according to it's used pw version. Different PHP versions aren't necessary. Would just see / compare a 2.3.1 and a 2.4.2. You can PM me or upload them as zip here to that thread.1 point
-
That's amazing - the very day I decided to put a blog on my site, this gets uploaded! Thank you so much! I've installed it and incorporated it into my site with surprising ease. The only issue I've had is with comment moderation - how do I do it? There's no option in the blog admin. EDIT: I found it - edit the post that the comment is on and the section for approving comments is at the bottom. Guess I should have watched the video tutorials!1 point
-
Edited above code in my post to make it tighter...+ clarified some stuff...1 point
-
1 point
-
Fancy doing the checks in the background via ajax Nico? Initial version check can take a long time and I'm wondering if users are going to think this has "broken" their admin UI.1 point
-
the german lang pack is up to date for the PW 2.4. You can also take it directly at Github: https://github.com/yellowled/pw-lang-de if you want to work with the newest PW dev version, than you need to replace some files (look at files from the post above yours). Name and description of modules depends on the module itself. Following strings are needed to be translatable: public static function getModuleInfo() { return array( 'title' => __('Diagnostics Page', __FILE__), 'summary' => __('Allows evaluation of run-time environment and detection of changes.', __FILE__), ... ...1 point
-
I would wrap this translating thing with html_entity_decode(). Should be possible to use normal html after that.1 point
-
I've pulled horst's image handling diagnostics out into the first external diagnostics collector (ExamineImagehandling.module) for this suite. If anyone else wants to have a go at extending ProcessDiagnostics, you now have an example collector to use as a base. You can also play with the verbosity level by changing ProcessDiagnostics.module line 51 to either "MEDIUM_VERBOSITY" or "LOW_VERBOSITY" - UI control will come. Example medium verbosity output: And the same listing but with low verbosity:1 point
-
Hello, There seems to be so many topics about newsletters that I don't really know where to post. I was thinking of perhaps using the Newsletter plugin with Seo Panel one day, for some particular use cases. I've just found mailerlite, while reading a blog article/interview. It seems to be already integrated with some well-known and less known CMSs. It could be interesting to also have something like: "MailerLite plugin for ... is here. Download it and receive a 50% discount for subscription. Boost your email marketing!" Just wanted to share what I've found . Their services are apparently very affordable. Updates: https://www.mailerlite.com/international http://docs.mailerlite.com/1 point
-
Mary, I am really pleased to hear that you are working on a set of PW video tutorials! The more the merrier. I like short focused tutorials that build from previous episodes. Your MODx tutorials were so helpful for so many people...1 point
-
You can sort any WireArray with $a->sort("property") as shown in the API cheatsheet $a = your WireArray (or PageArray) property you can set to sort the array But you already have a $pages->find as far i understood, why not modify the selector of that and extend it with the get variable. This way you can sort on database level which is faster then getting the data from the database first and then sorting it afterwards.1 point
-
Thank you @Ryan for sharing the information and test scripts you did. I will try to benchmark on the coming days with the same. I have more than 50K pages .1 point
-
Thanks Hari, excellent observation and I will take a closer look at this. While COUNT(*) is very fast in that context, ProcessWire never executes such a query with no where or join conditions. If I recall that speed difference doesn't hold true once you are counting the results of a rather complex query (as most PW page queries are). Though if we can tweak a little more speed out of using a count rather than a select found_rows() then I'd be all for it. I've been through this consideration before and had settled on sql_calc_found_rows being the better option at the time, but it's been awhile and I'd like to revisit it. I'm now working on a project with apeisa where we deal with hundreds of thousands of pages and we're always looking for ways to optimize performance, so it seems like a good opportunity to benchmark this again. One thing to mention also is that the PW dev branch is more optimized in this respect. It is quite a bit more selective as to when it uses SQL_CALC_FOUND_ROWS, which ensures it's not putting that overhead on top of situations where it doesn't absolutely need it. You can also disable the behavior in your $pages->find() call by specifying the 'getTotal' option as false, which tells PageFinder not to attempt to determine the total number of matches. But specifying it wouldn't be necessary unless your selector string included a limit=n in it, as PW dev doesn't attempt the count unless you are using a limit (presumably for pagination). $options = array('getTotal' => false); $items = $pages->find("selector", $options);1 point
-
$page = $this->pages->get($data->article_id); if ($page->template == 'something') { $stmt = $this->database->prepare( 'update field_update_field set data=:data where pages_id=:pages_id' ); $stmt->bindValue(':data', 'some.data'); $stmt->bindValue(':pages_id', $page->id); $stmt->execute(); } ..but woluld be.that any faster then this : ? i woluld think.not $page = $this->pages->get($data->article_id); if ($page->template == 'something') { $page->update_field = 'some data'; $page->save( 'update_field' ); } If you want queries that PW did while inserting or updating those pages, in debug mode use $database::getQueryLog(). That'll return you the full query log, from which you can grab just the parts you need. getQueryLog() not full queer ys bound values.they contain not1 point
-
If you want queries that PW did while inserting or updating those pages, in debug mode use $database::getQueryLog(). That'll return you the full query log, from which you can grab just the parts you need. Another method would be updating database tables manually with custom SQL, but then you'd have to update/insert at least pages (including sort fields), pages_access, pages_parents (in some cases) and each field-specific table individually. You said that "[...] insert and update certain images and [...]". Depending on various factors (amount of images, file sizes, resize settings etc.) updating and/or fetching images could be very expensive operation. Just saying.1 point
-
Hey. After playing around with the navigation for a bit I was curious if it is possible to use images instead of titles in the navigation. $homepage = $pages->get("/"); $children = $homepage->children("limit=21"); $children->prepend($homepage); foreach($children as $child) { $class = $child === $page->rootParent ? " class='on'" : ''; echo "<li><a$class href='{$child->url}'>{$child->nav_image}</a></li>"; } At the moment I have this which ofcourse won't work. Is there a way to display $child->nav_image as a image?1 point
-
So I spent the last couple of hours in creating a module which imitates the Textpattern thing. Take a look. LanguageInstantInstall.module (You have to go to Setup -> Languages and add a new language). It's not completely finished (a function to update, etc. will follow) but it does what it has to do What do you think? / nico1 point
-
ryan - just a thought, but would it be possible to make it so that fields can be shown depending on whether a user has a certain role, or even ID? Certainly roles would take you one step closer to a system I used to use where there was an editing flow with a website's content - someone would work on content, then their manager would fill out some other fields on the same page, sometimes in another tab in the editor, before finally publishing a page. It's not something that everyone needs, but to my untrained eye it also doesn't look like it would be too difficult to add (*ducks for cover*), would make it even more powerful and could be useful in many different scenarios. I guess the selector for that would be something like user.role=editor|manager as well as user.id=41 maybe for scenarios where the main admin user wants to test some stuff or have hidden fields that other superusers can't see (though that's silly as other superusers could give themselves access anyway - just thinking of odd scenarios!). Can anyone else think of uses for this?1 point
-
I have thought a bit about newsletter integration and how an emailer setup would work from within ProcessWire, either by building something natively or integrating with Campaign Monitor / Mailchimp. I have a couple of sites for organisations with medium-sized memberships. These need to email their members from time to time so I built a dead simple module to do this which supports a single email template. You can take a look here. Please feel free to build upon this, or just take the basic idea and run with it. https://github.com/ffub/ProcessMailer These are the benefits I can see from building a complete web mailer in PW: Ease of use My clients already know how to use the PW backend All of them find Campaign Monitor and MailChimp very hard to understand and use, especially the latter Content management all in one place. They can manage their web presence all from the backend of their site [*]Tight integration with user database. You can easily create a mailing lists with PW’s awesome selector engine, eg: $users->find(“roles=5810, newsletters=news|offers”) [*]Create email templates based on the PW templating and field system Multiple email templates Familiar API Keep your templates alongside your front end templates Use templates for system messages [*]Because sent mails would be stored in the system as Pages and the templates would be on the server, These are the negatives Your server will get blacklisted! Preventing users from marking your email as spam is a pretty herculean task. If you use the web server the site is hosted on to send the email then a blacklisting will also affect the system messages send out by all the sites on that server. You can work around this somewhat by allowing the web mailer to use a separate SMTP host in its settings. Hiring an SMTP host for bulk mailing will typically cost you more than just using Campaign Monitor or MailChimp. Hosts such as Gmail will only let you send up to 500 messages and will frown upon sending bulk mailings through their service. Performance: Sending multiple HTML emails can be very slow. I’m not sure how much offsetting the sending to an SMTP server improves this, but it’s definitely a concern on a web server. Bounces: You would have to setup the mailer on your server to route these to ProcessWire. Even then, it’s quite a job working out which are actual bounces and which are Out of Office messages or genuine replies. Metrics: Email analytics is a task best suited to the big boys. How would you build an emailer in processwire? I think it would actually be pretty simple to build a pretty powerful Mailer. Lists would be created by choosing a role, or using a selector for more advanced ones. Templates would be stored alongside regular page templates and you’d use the familiar $page API within them. Eg $page->subject. The rich text editor field might need some trickery to make sure all links and image paths are absolute URLs including the hostname. Campaigns or Messages would be created as pages. You could have draft and sent statuses or parents. It would be possible to view them on the front end too. Your email templates could easily pull in data via the Page field type, allowing you to sent out emails for events and the like with ease. Text versions could either be based on an alternative template (multiple files per template may be tricky) that strips out any HTML or by running the HTML template through Lynx on the server, which makes for a unix/cygwin dependency. If you used Textile or Markdown for your body field rather than TinyMCE this would be less of an issue to work around. An analytics field in the settings would let you enter a Google Analytics ID. Links could then be tracked with Google's campaign tracking I’m certainly keen to look into the templating side of this over Spring as I’d like to use HTML templates to send some of my notification messages. thanks, Stephen1 point
-
function listChildrenTree($children, $current, $w) { echo "<ul>"; foreach($children as $page) { $class = ''; if($page === $current || $current->parents->slice(1)->has($page) ) { $class = "class='on' style='font-weight:bold'"; } $rootid = $w->pages->get("/")->id; echo "<li><a href='{$page->url}' $class>"; if($page->id == $rootid) echo "<img src='" . $w->config->urls->templates . "styles/images/home.png' width='24' height='28' alt='' />"; echo "{$page->title}</a> "; if($page->numChildren && $page->id != $rootid) listChildrenTree($page->children, $current, $w); echo "</li>"; } echo "</ul>"; } $children = $pages->get("/")->children(); $children->prepend($pages->get("/")); listChildrenTree($children, $page, $wire);1 point