Leaderboard
Popular Content
Showing content with the highest reputation on 02/24/2013 in all areas
-
6 points
-
Okay this was very short notice so it is incredibly rough! But this is for Diogo and all those others wedded to PW http://21stcenturyblues.co.uk/pwdream1.mp3 (Organized, try listening at less than 120db!)4 points
-
This module provides simplified (no fancy diff etc. features available, at least yet) version control for text type fields. Originally introduced in another post as a proof of concept, I'm now considering it stable enough to deserve a thread of it's own here. Just so that you know: I've tested this module in multiple ProcessWire installations, three or four different versions in total running on two different platforms, but it still hasn't seen too much real world use. Any information you folks can provide me about how well (or badly) it worked (or didn't work) for you would be considered extremely helpful! So, what does it do? When editing pages, fields with old revisions available show up with a new icon in their header bars. By hovering that icon you get a list of available revisions and by clicking any one of those the value of that particular field is reverted to that revision. No changes are made to page until you choose a revision and save the page, which means that you can keep switching between revisions to get an idea what's really changed without inadvertently causing any content to change. How does it work? Behind the scenes hooks provided by ProcessWire are utilized to catch page edits. If text fields (such as FieldtypeText, FieldtypeTextarea etc.) selected at module configuration to be tracked were changed, their values (along with some metadata) are saved to two custom database tables. See attached screenshots for better idea about how this thing works. Please note that before you've selected at least one template + field combination to be tracked via module settings nothing will be saved to database! Getting started Module is available at GitHub: https://github.com/teppokoivula/VersionControlForTextFields. Here's a direct download link if that's what you prefer. Installation instructions etc. are available at README.md. If you've got any questions, feel free to post them here or PM me!2 points
-
Hello Processwire folks, today I want to show how to implement piwik into Processwire to show some specific site details to visitors or, if you create a special frontend login, for yourself. First Step (preparation): What do we need? Well, to grab piwik data we need the piwik open source analytics suite. Grab your copy here: http://piwik.org/ Now copy piwik right into your Processwire folder, you get a folder structure like: piwik, site,wire next install piwik! After installation log into your piwik dashboard and setup your site, we need some information from piwik later in the tutorial, so just let the piwik dashboard open in the background. Now we have to think about data presentation. I´m currently working on a Webapp to let customers create their own Landing Pages and measure their performance, to show the data I´ve choosen morris.js a goodlooking javascript based on raphael.js and jQuery. So, we need jQuery. morris.js and raphael.js. jQuery : http://jquery.com/ morris.js : http://www.oesmith.co.uk/morris.js/ raphael.js : http://raphaeljs.com/ Install all three scripts in your Processwire templates folder and dont forget to copy the provided .css file, too. Second Step (Connect to the piwik API): To grab data from piwik we have to include the piwik API in our Processwire installation and we need some special settings to do. We need 2 informations about our piwik installation: 1st our own Auth Token 2nd the SiteID of our tracked page You could find your Auth Token in the piwik Dashboard. Just click on API in the head menu and there it is, in this little green box. Now we need to know the site id of our page we want to show in our template files. If you only setup one page in piwik the SiteId is 1, if you setup multiple sites click on "all websites" in the head menu now click on add new site. Now you could see all your pages and their own site Id. Remember where to find this informations, we need them in our next steps. Third Step (templating and API connection): Go to your PW Admin and create a new Template. We don´t need any fields so far, so title and body would be enough, now create a new page with your new template. Thats it on clicki bunti side, we now have to open our favorite ninja code editor. Create a new file in your templates folder named like the template you created. Create a new file in a subfolder of your templates folder, maybe if exists in scripts or includes, wherever your include files are. Name this file analyticSettings.php This is our piwik API connector. Copy and paste the following code: <?php // if you don't include 'index.php', you must also define PIWIK_DOCUMENT_ROOT // and include "libs/upgradephp/upgrade.php" and "core/Loader.php" define('PIWIK_INCLUDE_PATH', realpath($config->paths->root.'/piwik')); define('PIWIK_USER_PATH', realpath($config->paths->root.'/piwik')); define('PIWIK_ENABLE_DISPATCH', false); define('PIWIK_ENABLE_ERROR_HANDLER', false); define('PIWIK_ENABLE_SESSION_START', false); require_once PIWIK_INCLUDE_PATH . "/index.php"; require_once PIWIK_INCLUDE_PATH . "/core/API/Request.php"; Piwik_FrontController::getInstance()->init(); function piwikRequest($piwikSiteId,$piwikMethod,$piwikPeriod,$piwikDate,$piwikSegment,$piwikColumns, $piwikColumnsHide) { $piwikGetData = new Piwik_API_Request (' method='. $piwikMethod .' &idSite='. $piwikSiteId .' &period='. $piwikPeriod .' &date='. $piwikDate .' &format=php &serialize=0 &token_auth=AUTH TOKEN &segment='.$piwikSegment.' &showColumns='. $piwikColumns .' &hideColumns='. $piwikColumnsHide .' '); $piwikGetData = $piwikGetData->process(); return $piwikGetData; } ?> line 1 - 14 sets the paths to the piwik API and setup some error handling for piwik. Enter your own Auth Token in line 26. Thats it, connection to piwik allready done. Now lets see how we grab our data. There is a function beginning in line 15. I named this little friend piwikRequest. You could pass 7 values to our function to define which, how many, which date,period and method we want to request from piwik. $piwikSiteId = from which tracked page we need data. $piwikMethod = which data method do we need? You could find a full list here: http://piwik.org/docs/analytics-api/reference/#toc-standard-api-parameters $piwikPeriod = day, year, moth, week $piwikDay= today, yesterday $piwikSegment = Segment of data, e.g. pageTitle==home $piwikColumnsShow = Only grab Data from this columns in the piwik database $piwikColumnsHide = Do not grab data from this columns So, if we want to grab the visitor count from yesterday we could call our function like this: <?php echo piwikRequest('3','VisitsSummary.getVisits','day','yesterday' ?> 3 = id of tracked site from piwik (I use piwik to track frontend, backend and the user created landing pages in its own site) VisitsSummary.getVisits = our API Method to tell piwik which data we need day = our period yesterday = well yes, data from yesterday This request returns just a neat integer so there is no need to do additional logic, if we use methods providing more data the function returns an array which could be displayed by an print_r() or json_encode() Well our piwik connection is ready, now we want to show some data on our template file. The Templating: Open your template file, make sure you included all needed files from jquery, morris and raphael. Include on top of the page your piwik api connector file. Make sure that jquery, morris.js and raphael.js are included in this order and above the html code. Order: jQuery Rapaehl.js Morris.Js We now want to show 2 Donuts with 2 data values each. Visits today and Yesterday. Total pageviews from this year, unique and all. Copy and paste the following code to your template file: <h2>Visitors</h2> <div id="donut" style="height:200px;"></div> <h2>Page Views</h2> <div id="donut2" style="height:200px;"></div> <script> Morris.Donut({ element: 'donut', data: [ {label: "Yesterday", value: <?= piwikRequest('3','VisitsSummary.getVisits','day','yesterday') ?>}, {label: "Today", value: <?= piwikRequest('3','VisitsSummary.getVisits','day','today' ) ?>}, ] }); Morris.Donut({ element: 'donut2', data: [ {label: "unique", value: <?= piwikRequest('3','Actions.get','year','yesterday',' ','nb_uniq_pageviews') ?>}, {label: "all", value: <?= piwikRequest('3','Actions.get','year','yesterday',' ','nb_pageviews') ?>} ] }); </script> We add 2 empty divs with some inline css. You could change this via a stylesheet. In this 2 divs the morris script will draw a donut with the grabbed data from piwik. Right under the divs we are calling our morris.js and provide data from our piwikRequest function. Thats all You could find all piwik methods, dates, periods and so on in the piwik api reference here: http://piwik.org/docs/analytics-api/reference/#toc-standard-api-parameters2 points
-
Just add php comments like this: <?php // this won't be in page source code ?> Edit: fixed, thanks diogo2 points
-
There are a couple of things I add: In additional settings I add: paste_text_sticky: true paste_text_sticky_default:true Which automatically takes all formatting away from pasting. I add H1 to my dropdown, spell checker and a few other bits. here is my settings (I dont use the all at once, but it gives me a good starter): buttons 1 formatselect,styleselect,fontsizeselect,|,bold,italic,justifyleft,justifycenter,justifyright,justifyfull,forecolorpicker,|,bullist,numlist,|,link,unlink,|,image,|,code,|,fullscreen,spellchecker block formats p,h1,h2,h3,h4,blockquote,pre,code Plugins inlinepopups,safari,table,media,paste,fullscreen,preelementfix,contextmenu Valid Elements - note, to enable things like font color, size and face, you must use span and NOT font! @[id|class|style],a[href|target|name],strong/b,em/i,br,img[src|id|class|width|height|alt],ul,ol,li,p[class],h1,h2,h3,h4,blockquote,-p,span[face|size|color],-table[border=0|cellspacing|cellpadding|width|frame|rules|height|align|summary|bgcolor|background|bordercolor],-tr[rowspan|width|height|align|valign|bgcolor|background|bordercolor],tbody,thead,tfoot,#td[colspan|rowspan|width|height|align|valign|bgcolor|background|bordercolor|scope],#th[colspan|rowspan|width|height|align|valign|scope],pre,code Content CSS /site/templates/css/editor.css Additional Settings paste_text_sticky: true paste_text_sticky_default:true theme_advanced_styles:Lead=lead;IconCell=iconcell;Blueheader=blueheader Third party plugins spellchecker : /site/tinymce/myplugins/spellchecker2 points
-
You guys probably already know this, but those permissions assigned at the template level are inherited through the page tree unless you choose "Yes" for defines access in your template settings. Meaning, you only have to define access on templates where you want to change something about the access. For example, lets say you've got a /members/ page that requires a login. You would define access for the template used by the /members/ page. But you wouldn't need to define it on any other templates used on pages below that. Meaning the templates used by /members/cool-stuff/ and /members/great/content/ do not need to define access, because they inherit it from /members/. This is a simple example, but the same rule applies for page editing permissions and such.2 points
-
hello, everyone! been an active reader in the processwire community but never felt like i had anything to contribute. ufortunately, i still don't feel up to speed to contribute much to the community but i thought i'd share a new site. i used ryan's blog profile as a base. it's still not 100% finished (probably at about 90% on the dev side) and the blog hasn't been posted to yet. any opinions/critiques, good or bad, are appreciated. http://revengeofthecakeball.com/ many thanks! alex1 point
-
Eureka! It would be nice if there was a more direct way to do this using PW, and perhaps there is, but I eventually succeeded by dumping the repeater fields I needed into a separate array and then performing a sort on that array. Here's the code with some additional commenting: <?php $peaklist = $pages->find("template=report"); // returns relevant page IDs $dest = array(); foreach($peaklist as $location) { $mountain = $pages->get("id=$location"); // grabs pages to allow access to fields foreach($mountain->mountains as $peak){ if ($peak->stats_mtnName){ // pages create 4 blank repeater "value sets" by default, this is a test to grab only populated ones $maxElevft = number_format(round($peak->stats_maxElev * 3.28084)); // to convert a field value in metres to feet; using number_format() to add thousands separators (ie. 3200 -> 3,200) ++$i; $dest[$i]->url = $mountain->url; // field from page $dest[$i]->name = $peak->stats_mtnName; // field from repeater $dest[$i]->maxElevM = $peak->stats_maxElev; // field from repeater $dest[$i]->maxElevF = $maxElevft; } } } usort($dest, function($a, $b) { return $b->maxElevM - $a->maxElevM; // sorts in descending order, reverse A & B for ascending order }); echo '<ul class="blocklist">'; foreach($dest as $item) { echo '<li><p class="tabular"><a href="'.$item->url.'">'.$item->name.' '.number_format($item->maxElevM).'m / '.$item->maxElevF.' ft.</a></p></li>'; } echo '</ul>'; ?>1 point
-
Okay, committed. Thanks a lot, Manfred. Haven't really gotten around to spending much time on the translation lately. Then again, I always meant for it to be a community effort.1 point
-
Great find diogo. And in case you guys don't know about it, there's very useful extension named WhatFont that I use all the time to know what fonts are used on the pages I'm browsing.1 point
-
1 point
-
I beg to differ. First of all, I would set that “Processwire-Seite”, but I really prefer “Webseite” or “Website” (untranslated). (Honestly, I don't really care as long as it's not “Homepage”.)1 point
-
<?php // this is a single line comment $somevar = 'somevalue': // you can add one after a line of code /* Or you can span multiple lines */ ?>1 point
-
1 point
-
Just reading Soma's post on delegation and thinking about how I am using functions more and more, I am wondering if I can sort of mix and match. Basically, it more or less follows what Soma is doing, but in addition, using the template name to define additional includes or functions (however you are working). So, you would perhaps have a template that you called category-news-headlines Exploding the name gives you three parameters - category, news and headlines Category would be the name for this particular template for purposes of differentiation but also may be defining that this is listing something by category. News might be the general theme you are calling in, a wrapper theme with a certain layout style or something Headlines would be something more specific, perhaps - some way of laying out the actual articles that has a big main article, is looking for featured content or something. Another variation would be a template called category-news-list which does the same thing, except the news would just appear as a list. On the actual template file, you split up the template name and use the parameters to call in the right elements. The advantage here is that you can create more variations without actually having to create more than a basic set of included files or functions. You are simply mixing and matching. This only works on a site (or a sections of a site) where you are using identical fields for all the templates. Of course, there is a rather valid argument that it would be better (and a lot easier) just to define the additional parameters with select/pages fields, but it is an idea that might have other uses.1 point
-
This is very clever, I would never have been able to figure it out. Many Thanks Wanze!1 point
-
With a little addition: $class = ($page === $child || $page->parents->has($child)) ? " class='on'" : ''; $page->parents returns a WireArray with all the parents and ->has checks if the current Nav-Item is in there.1 point
-
I have updated the german language files (depending on the latest cz files). Hope I found/changed all entries. Best will be, if yellowled makes a diff? BTW: the file 'wire--modules--sessionloginthrottle-module.json' seems to be obsolete now, and was replaced by 'wire--modules--session--sessionloginthrottle--sessionloginthrottle-module.json'? pw-lang-de.zip1 point
-
1 point
-
What kind of forum you need is all based on the needs of the community. My "built in three hours" discussions module runs nicely on www.martat.fi with almost 100 000 posts (most migrated from old system). Only features people there are missing are quotes and simple writer profiles - both things that I will implement there at some point. But adding 100 000 posts/replies as pages did add little overhead for the site. Especially for some kind of searches (grab a section and find pages under that with full text search). Ryan quickly provided tweaks to core selector engine and the selectors run nicely now. But if I ever rebuild the Discussion module, I probably make it use own tables instead of using pages. Although it is super nice to query the forum posts with the awesome PW api.1 point
-
Current method with template based access control works very well in most of the sites and apps. But if you have lots of "horizontal" needs, then it gets complicated. What I mean with horizontal needs is things like: we need to have 15 news sections with different editors and readers. Each of those news sections are in different parts of the site tree. Template based access control just falls short here, since we don't want to duplicate those 15 news templates (and create new duplicate each time we need new news section). News section is just an example, it could be also things like "workgroup section", "blog" or "private room" etc. CustomPageRoles module definitely helps here and I have been able to do all the things with it. But our sites usually are dynamic in a way that client themselves need to create those sections. Since CustomPageRoles build upon the template access control, it still needs quite a clicking on template access tabs etc. I have also made some tweaks to that module that I need to share. I like the idea of "global" and "local" - you could add "local" access control that will be inherited from some part of the site. See this: Home (home) -- services (basic-page) -- news (news) -- -- news item 1 (news-item) -- -- news item 2 (news-item) -- -- office intranet (intranet) * -- -- -- our rules (basic-page) -- -- -- office news (news) -- -- -- -- office news item 1 (news-item) -- -- -- -- office news item 2 (news-item) I would have defined my global template access like this: home guest role - view access office-member role - edit access * Then I would have added local template access to page "office intranet" and have defined there these rules: intranet guest role - no view access office-member role - view access office-admin - edit access news guest role - no view access office-member role - view access office-news-editor - edit access office-admin - edit access Not sure how complicated this would get, but I still find the current way a little bit cumbersome for our sites (with lots of "horizontal needs").1 point
-
Your assumption is correct. Images are downloaded during import process.1 point
-
I usually listen to a lot of rock/punk/metal (with a touch of rap / electro) but my hardcore programming music is this: https://youtu.be/YL6AU8bxm2g?t=37s I know.1 point
-
foreach($mountain->->mountains->sort('maxElev') as $peak){ should do it.1 point
-
if you are checking for roles in your templates, you can maybe get away with checking something like if: $user->hasRole($sanitizer->name($page->title)) //for the section page or $user->hasRole($sanitizer->name($page->parent->title)) //for the news, etc... if they are sub pages then make your roles called ParishCouncil and CricketClub1 point
-
Admittedly I don't use a treeMenu type function all that often myself. I think it just depends on the sites you are building. But I really like the solutions you've mentioned here--very elegant. Perhaps we should have some kind of visit() function like this in the core. Though unless it would be something most people would use, it may belong as a module or library. I'd be curious what other people think. Btw, I thought you might like the planned roadmap for ProcessWire 2.4. I'm hoping to finally get started on the full transition to PHP 5.3 here in the next couple of weeks, after PW 2.3 is final. I'm also going to try and get that alternate module configuration method in there for you, if you don't beat me to it.1 point
-
Good! Now, go and do the tutorials so you can work out all about pages and templates and template files! http://processwire.com/talk/topic/693-small-project-walkthrough-planets/ and http://wiki.processwire.com/index.php/Basic_Website_Tutorial1 point
-
Thank you so much! It works now perfectly! Maybe this three lines are helpful for other "newbies" like me (this is what I've done): 1. find the line "# RewriteBase /" 2. delete the "#" 3. Important: put in the whole URL of your processwire-folder without the "http://" Example for 3.: - My website was http://www.mywebsite.com - Have installed processwire in the folder http://mywebsite.com/test/process - So I've put the following line into the .htaccess file: " RewriteBase /test/process/ " (without the annotations, of course) Again, thank you, nik!1 point
-
The problem I think is that for the individual page permissions you might not always want it to inherit so it can't make that assumption. It could do with an additional option for it though of course - not sure how easy that would be though as whilst it sounds like it would be a case of recursively applying it to children, grandchildren etc, if you create a new child page it wouldn't inherit the parent's permission so it's not that straightforward. I always do it with templates in the end as there's more control that way. For news I have a news_home and news_article template and approach each section this way as you would usually want different things in different templates for those sections anyway. Even if you don't it's possible to clone a template in the admin and you just rename it and you're sorted1 point
-
The trick with counters is to remove yourself from skewing the count. I find that when writing blog posts I load the page several times and this would increase the count several times. You could go a step further with diogo's code and do this to exclude your account (superuser) from increasing the count: if (!$user->isSuperuser()) { $page->counter += 1; $page->of(false); $page->save('counter'); $page->of(true); } echo $page->counter; Or you could do the same for multiple roles if you have different editors for your site (my example has some fake ones named "news" and "sports" below): if (!$user->hasRole('news') && !$user->hasRole('sports')) { $page->counter += 1; $page->of(false); $page->save('counter'); $page->of(true); } echo $page->counter; Just a thought1 point
-
Hey Joss, I am thinking along these lines as well. Maybe we can work together on a neat system. I'll have some time to work on things like this soon... For the moment, I just could not resist your comment about Joomla's rights system. I am sharing some images so everyone here can sympathize with what you and I had to deal with before coming to ProcessWire... WARNING: THESE IMAGES ARE NOT FOR ANYONE WITH NERVOUS OR ANXIOUS TENDENCIES. http://docs.joomla.org/File:Screenshot_acl_tutorial_20110111-07.png http://docs.joomla.org/File:Screenshot_acl_tutorial_20110111-16.png http://docs.joomla.org/File:Acl_example_diagram1_20091018.png Thanks, Matthew1 point
-
Create a field "counter" with type "integer" and set it as "hidden, not shown in the editor" or "always collapsed, requiring a click to open", as you prefer. Put this code on your template: $page->counter += 1; $page->of(false); $page->save('counter'); $page->of(true); echo $page->counter; voilá1 point
-
$nightmares = $pages->get("/no/bloody/sleep/")->bad_dreams; foreach($nightmares as $nightmare) { if($nightmare->solution){ echo $nightmare->solution; }else{ echo "<em>Wake up and make coffee</em>"; }1 point
-
Yep I get a lot of errors though. My dreams appear to be missing a debugger. Working on it.1 point
-
1 point
-
I like that idea, being able to swap in a larger chunk of markup like that. I need to give this a try. I really like this thread, you guys have some great ideas.1 point