Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 11/27/2013 in all areas

  1. This module serves as an example of creating an editable table of data as a Fieldtype and Inputfield in ProcessWire. In this case, we create a simple table of events each with date, location and notes. This pattern can be adapted to nearly any table of information. Note that this module is intended as a proof-of-concept. If you find it useful for the example scenario (events) then great, but keep in mind it is not intended as a comprehensive events solution, where using ProcessWire pages may be a better fit. This is a pattern I've used for creating tables of data in ProcessWire for many different Fieldtypes/Inputfields and thought it would be good to setup a proof-of-concept example like this to share. Module Page / GitHub Page Install Copy the files for this module to /site/modules/FieldtypeEvents/ In admin: Modules > Check for new modules. Install Fieldtype > Events. Create a new field of type Events, and name it whatever you would like. In our examples we named it simply "events". Add the field to a template and edit a page using that template. Output A typical output case for this module would work like this: foreach($page->events as $event) { echo " <p> Date: $event->date<br /> Location: $event->location<br /> Notes: $event->notes </p> "; } This module provides a default rendering capability as well, so that you can also do this (below) and get about the same result as above: echo $page->events; ...or this: foreach($page->events as $event) { echo $event; } Finding events This fieldtype includes an indexed date field so that you can locate events by date or within a date range. // find all pages that have expired events $results = $pages->find("events.date<" . time()); // find all pages with events in January, 2014 $results = $pages->find("events.date>=2014-01-01, events.date<2014-02-01");
    12 points
  2. Hi everyone, I just want to share the good news, we launched a new website for a cafe in Melbourne, LuxBite. This is my first processwire website after years of experience using joomla and wordpress, this is by far one of the cms I enjoyed working with. Please visit the site http://Luxbite.com.au and leave your feedback! In short, I would like to thank all the community here - the forum is extremely useful and has a lot of information. This site is built on top of The amazing SimpleNavigationMarkup module by Soma - to be honest I am lazy to do foreach to output everything so utilizing this module is the way to go there are couple of outstanding issues and design changes that I need to work on but so far so good Extras: http://www.news.com.au/lifestyle/food/masterchef-cake-challenge-helps-revive-a-taste-for-flavours-of-the-past/story-fneuz8wn-1226666481357
    6 points
  3. Hi I recently finished my first ProcessWire website, and it's a gallery of black and white vintage erotica. Here's what I used: Default ProcessWire Installation. Bootstrap, jQuery (for the bootstrap carousel and MediaElement.js), MediaElement.js and Glyphicons (they come with Bootstrap.) Photos are sharing two templates (one is for single photo entries, and the other is for multiple photo entries and it uses Bootstrap's carousel.), Featurettes have their own template and there is only one. I also have a simple tagging system. It didn't really take me a while to figure ProcessWire out, it really was a piece of cake for someone without a lot of PHP knowledge. I had way more trouble getting a hang of WordPress than ProcessWire. It's a great piece of software. Before I forget, http://faysjoint.com Fay
    5 points
  4. If you need any help, just let us know. Everyone here teaches everyone else something at some point
    4 points
  5. Here you go: Events Fieldtype/Inputfield
    2 points
  6. you mean like this? if($product->sc_price_drop) { $out .= '<del>' . $product->sc_price . " €</del>"; $out .= number_format($product->sc_price_drop) . " €"; } else { $out .= ($product->sc_price ? number_format($product->sc_price) . " €" : $na); }
    2 points
  7. I just looked into this again and there's no argument for removeAll() just for remove($key). See here in source https://github.com/ryancramerdesign/ProcessWire/blob/dev/wire/core/WireArray.php#L790 removeAll() removes ALL pages from a Wire/PageArray (pages, images, POST vars etc). So I'm not sure about why it works for you because it shouldn't and also doesn't work for me. Assuming user_app is a page field allowing multiple pages to be selected. It's a WireArray/PageArray and you add pages to it like this from API: $user->of(false); $page1 = $pages->get("/somepage/"); $page2 = $pages->get("/someotherpage/"); $user->user_app->add($page1); $user->user_app->add($page2); $user->save(); Now we got 2 pages added to the page field. If you now do a $page->user_app->removeAll($page1) they all get removed so does $user->user_app->removeAll(); But if you do: $page2 = $pages->get("/someotherpage/"); $user->user_app->remove($page2); $user->of(false); $user->save(); Now only the $page2 which is in the array gets removed. It works all as expected and make sense.
    2 points
  8. Or in a cached template: <?php echo time(); ?> Then reload the page several times - the value should not change because the output is cached
    1 point
  9. Exactly, thank you Martijn.
    1 point
  10. I think you're searching this.
    1 point
  11. Hello, I'm working on my first project with PW. Working with PW is amazing so far. As I am coming over from the Joomla world I am used to adding scripts to individual pages with a Joomla built in method. Searching for the PW way of doing this, I came along that post where I found this snippet of code: $config->scripts->add($config->urls->templates . "scripts/lightbox.js"); Great, I thought. But using just that snippet wouldn't include the script. I had to add a second snippet foreach($config->scripts as $url) echo "<script type='text/javascript' src='$url'></script>"; (which I also found in that other post) to actually load the script wherever I wanted in my template file. Lets assume you are working with the default PW Profile on a fresh install and want to load the lightbox.js only on the homepage and the template file for your homepage is home.php. Then you would include the first snippet in your home.php. The second snippet goes either in your head.inc into the head section or in your foot.inc at the bottom (whereever you prefer to load your js). This is a quite generic way to include scripts. If you wanted to have another script loaded only, lets say, on a contact page with template file contact.php the you just need to add a snippet, e.g. $config->scripts->add($config->urls->templates . "scripts/contact.js"); to contact.php. The second snippet foreach($config->scripts as $url) echo "<script type='text/javascript' src='$url'></script>"; already sits in your head.inc or foot.inc where you put it before and it will take care of including also contact.js because of the foreach loop. I guess that most of you already know this. But for a newbie like me I had to write this down to properly digest it and maybe it is helpful to someone else. Cheers gerhard
    1 point
  12. This has been added in the latest commit. I also updated CKEditor to 4.3.0.
    1 point
  13. The $map->render() requires either a Page with a 'MapMarker' field or a PageArray with multiple pages, each containing a 'MapMarker' field. If you are giving it a PageArray of multiple pages, and it's only showing a marker for 1 of them, then chances are that only one of the pages you gave it has a 'MapMarker' field. Keep in mind the field must be named consistently with what you tell it. Meaning, if you are calling $map->render($features, 'MapMarker', $options); then every one of the pages in $features must literally have a map marker field named 'MapMarker'. If they don't, then chances are that $features is not the group of pages you really want to send to render(). But $placepage clearly isn't either, since that's just 1 page (which is only going to print 1 marker). Based on looking at your code, I'm guessing this might be what you want? $features = $pages->find("parent=/events/, bfd_day.name=$todayday, bfd_month.name=$todaymonth, sort=bfd_year"); $markers = new PageArray(); foreach($features as $feature) { $markers->add($feature->bfd_events_places_id_list); } $map = $modules->get('MarkupGoogleMap'); $options = array('width' => '100%', 'height' => '400px'); echo $map->render($markers, 'MapMarker', $options);
    1 point
  14. Dreaming of a field type called "flexField". Wet dreaming going on here
    1 point
  15. Good idea, I'll add that. I agree. It could be problematic with some scripts. Perhaps it should be a configurable option as to whether scripts should be minified or not. Or better yet, an extra attribute on the script tag: <script minify> so it knows it's fair game. True, but we're talking about inline scripts in this case. I'm too lazy to go and re-minify inline scripts every time I need to change something.
    1 point
  16. Oh and I gladly will accept any PR or help if anyone finds the time to implement those fixes. Currently short on bandwidth. No and I don't have any notices on php 5.3.
    1 point
  17. The dot concatenates the strings from left and right of the operator: $string = "Team"; // "Team" $string .= " Building"; // "Team Building" $string .= " Exercise"; // "Team Building Exercise" $string .= " '99"; // "Team Building Exercise '99" So, in your code you have to use the dot, except on the first $out assuming that the variable is empty. If the $out comes from previous code and is already populated, then you should keep also that dot.
    1 point
  18. RE: 3 - You need to install the core module - "Page Clone". Simply go to Admin > Modules > Process > Page Clone > install
    1 point
  19. Hi! On a bit of a rush here, just some short answers: Yes. PageArray, when treated as a string, should look like that. See PageArray->toString() for more details. You can access specific items with $pagearray->eq(0), $pagearray->eq(1), $pagearray->first(), $pagearray->last() etc. or iterate it with foreach. Through API or via admin UI? Both should be doable, admin UI has "copy" link and http://cheatsheet.processwire.com/ provides details for API side (tip: look for "clone" method from Pages or PageArrays.) No, created date tells when page was created, i.e. added
    1 point
  20. @soma ,your reply is very helpful... my fault: $app is a page id variable, not a $page object. $removepage = $pages->get($app); -> add this line $user->user_app->remove($removepage); ->change removeall to remove its working thank you very much!
    1 point
  21. Introduction Dear community. As some of you may know I've been busy creating a MVC Module for Processwire. I've finished quite a bit of it and I am now ready for a tutorial on a quick website to get you started! For this tutorial I am using a clean install of Processwire 2.3 and my Module 0.2.4 Get the module at Github http://github.com/hawiak/mvcmodule . Main focus of the module is to split logic from design without losing the flexibility of Processwire we all fell in love with. Alright lets get started. Installation Once you have the module downloaded we are going to install it, we need the MvcModule folder in the /site/modules folder. And we need the AppController in the /site/templates folder (You can find the AppController in the /site/templates folder) Once you've put the folder in there we are going to install the module, check for new modules and you'll see MvcModule Click on it and hit install to install the module. Once you've installed the module you'll see some configure settings and you'll notice a new tab on your admin. But click submit, dont forget this or all the paths WONT WORK! Setting up your home controller Ok we are ready to set up our first controller. To easily set up your template to enable MVC we are going to the MVC tab in your navbar. You'll notice a button saying " Create controller" Click on "Create controller" and for this tutorial we are going to use the home template, select the home and click "Create". If everything is correct you will see this: Now we are done in the process side of it and we'll get into the coding. Get your favourite code editor open and lets create our controller. Open the /site/templates/home.php file in your editor. Remove the code thats in there completely. And save it. For the module to work with the template file we need to create a class called HomeController and extend AppController. like so: <?php class HomeController extends AppController{ } Creating Views and layouts If you go to your websites homepage you'll see something along the lines of: Thats because by default you will need an Index method, a home method for your controller, so lets create one! <?php class HomeController extends AppController{ public function index(){ } } Lets try it again! Oops... Well it seems like we're missing a view, so lets create the view, we first need to create a folder with called Home (the same as the controller name but start with capital) And in that folder we'll create a file called index.tmpl Now of you run it you'll see that you are not quite done yet you'll see something like this: I promise after we create the layout we are done. So lets create a folder called layouts and a file called layout.php in there. Displaying data Now we're done with the setup and we can start coding, lets say you want to get the content fromt he field body on your page displayed? Well thats easy put this in your index method. $this->set('body', $this->page->body); What this does is that it sets a variable in the view we can use called body so all we need to do to display this is go to our view. And add {{body}} to the view. Now go and refresh your page! oh wait... nothing shows up...? Oh yes we use Twig template engine we need to add this to our layout.php {% block view %} {% endblock %} (Yes yes I know its complicated for just a simple task but trust me you'll love it later!) Refresh your page and check it out! You'll see that the text is displaying but the markup isn't really working, we need to use the |raw extension in order to make this work, so change the index.tmpl content to this {{ body|raw }} Use |raw for all the HTML markup, always. Styles, scripts and snippets Now this is quite boring, I know but lets start doing some interesting stuff, lets implement Bootstrap! go and download bootstrap at getbootstrap.com Once you've downloaded create a folder in /site/templates called "assets" the dist copy the bootstrap.min.css out of /dist/css to /site/templates/assets/styles and /dist/js/bootstrap.min.js to /site/templates/assets/scripts/ Now we want to use this, MvcModule has some great options for this! Change your HomeController to this <?php class HomeController extends AppController{ public $scripts = array( '1' => 'bootstrap.min.js'); public $styles = array( '1' => 'bootstrap.min.css'); public function index(){ $this->set('body', $this->page->body); } } Now go over to your layout and change the contents of your layout to this: <head> {{ this.render_headers()|raw }} </head> {% block view %} {% endblock %} You'll now see your style (If not try going to the MvcModule configure settings and remove the first / from /site/templates/assets) Now we forgot to include JQuery, so lets download jquery at jquery.com We need to put that in the /site/templates/assets/scripts And we need to put it in the array, you can just do that as follow: public $scripts = array( '2' => 'bootstrap.min.js', '1' => 'jquery.min.js'); The number in this array indecates the order on which the scripts will be loaded. Now you should see something like this! Now lets create a navbar with all the pages using the bootstrap navbar component. To do this we will create a snippet create a folder called snippets in /site/templates and a file called navbar.php Lets first create a variable with all the pages in the index method $this->set('menu', $this->pages->find('/')); Lets now create our snippet, lets just create this first in our snippet navbar.php <nav class="navbar navbar-default" role="navigation"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> <li class="active"><a href="#">Link</a></li> </ul> </div> </nav> We need to tell the controller to use this snippet we do that by using an array. Change your controller to the following: <?php class HomeController extends AppController{ public $scripts = array( '2' => 'bootstrap.min.js', '1' => 'jquery.min.js'); public $styles = array( '1' => 'bootstrap.min.css'); public $snippets = array( 'navbar' => 'navbar.php'); public function index(){ $this->set('body', $this->page->body); $this->set('menu', $this->pages->find('/')); } } And change your layout to this: <head> {{ this.render_headers()|raw }} </head> {% block navbar %} {% endblock %} {% block view %} {% endblock %} You see that I created a block here and called in Navbar. The snippets content (that we assigned to navbar => file_name) will be put in this block! So lets now use our variables and the Twig template engine to the fullest! Change the navbar.php snippet to: <nav class="navbar navbar-default" role="navigation"> <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> <ul class="nav navbar-nav"> {% for item in menu %} <li class=""><a href="{{ item.url }}">{{ item.title }}</a></li> {% endfor %} </ul> </div> </nav> You see we use a for loop here and use the PageArray menu here and generate the menu here. You can use the variables in the view as well. Setting a title Lets set a title, this is fairly easy, lets define a variable in our controller that will be the same for every view in this controller public $title = "Home controller"; Now go to your layout.php and do add this to the head: <title>{%block title %}{% endblock %} {{ this.controller.title }}</title> Now as you can see we created a block, what this allows us to do is create the same block in the view like this: {% block title %}Index{% endblock %} And you will see that your title is "Index Home controller". This is because the title block replaced the title block in the layout file. Views Inside views you still have access to processwire objects and even to the MvcModule as you've seen with render_headers(). The view template used is Twig, check out more here http://twig.sensiolabs.org/doc/templates.html This is a basic setup for a website with MvcModule. I will extend this tutorial and update it whenever needed!
    1 point
  22. good one I also wrote about in some thread... and for those being even more lazy can also use the even shorter $page->is(selector) if($page->is('template=template1|template2|template3|template4')){ edit: or if just for one template instead if($page->template == "basic-page"){ use if($page->is("basic-page")){
    1 point
  23. And for those that don't know, you can do this in ProcessWire if you want to match against multiple templates, like this: if ($page->matches('template=template1|template2|template3|template4')) { ... instead of this: if ($page->template == 'template1' || $page->template == 'template2' || $page->template == 'template3' || $page->template == 'template4') { ... Just thought that was worth sharing as I was typing it the long-hand PHP way just now and stopped myself before I wrote a lot of extra characters for no real reason! A shorter PHP alternative than above would be this: if (in_array($page->template, array('template1', 'template2', 'template3', 'template4')) { ... but I much prefer the ProcessWire version. $page->matches is a lovely thing that can be used to test the current page against any selector you can think of that makes sense in your situation.
    1 point
  24. This would be a good candidate for a simple custom field, nuff said.
    1 point
  25. Hi Niklas, i guess maybe when you say 'sites' you mean pages? this is something that can already be done pretty easily. for example i just did a site with 3 distinct types of data, classes (as in like an art class), sessions (as in the actual session that the class runs, start/end dates, instructor etc.) and events. For the classes, we setup a parent page called Class Database, and then a custom admin page for viewing the list of classes, and being able to click on one and edit it. the class database page used a template called class-database which only allows the page type class as a child. for sessions those are relational to classes and output on each class, the class is a page select on the session, and there is no template file for the session, so they won't show or be accessible on the front end. the classes are output using url segments and some url 'rewriting' logic that was demonstrated by Ryan's CMS Critic case study.
    1 point
  26. We already got through this guys .... Here http://processwire.com/talk/topic/4189-flexibility-in-page-design/?p=47083 and here above on this page http://processwire.com/talk/topic/4189-flexibility-in-page-design/?p=47085
    1 point
  27. There you go https://github.com/somatonic/TemplateNotes
    1 point
  28. Joss, you can get the page number with $input->pageNum, so: if ($input->pageNum < 2) { // Show the thing }
    1 point
  29. str_replace("", "smile.gif");
    1 point
  30. I see, your code needs braces & closing parentheses.
    1 point
  31. The notices comes from the all the 'roles' arrays. I don't see them anywhere in the helper text (weird that they're bugging me). These are: editRoles, addRoles, createRoles & roles. I changed the line 156 to this prevents the notices. if(is_array($data_value)) $data_value = implode(" ", $data_value); $settings_str .= "<h1>$data_key:</h1> $data_value<br/>";
    1 point
  32. If there was a way for us to make PW automatically reassign the $user variable after login, we'd do it. It's not technically possible for PW to do that (it's a matter of variable scope). That's why you'd have to do what Adrian suggested and assign the $user variable yourself from the result of login(). However, what Soma was getting at before he gave up was even better because it wouldn't trash the $user variable if the login failed. So something like this might be ideal: $u = $session->login($username, $pass); if($u) { $user = $u; echo "logged in"; }
    1 point
  33. I don't see any advantage in creating PHP in a browser. Can't remember how may times I pressed tab in a browser when I was editing inline on MODX sites. Or how many times spellchecking didn't like my function names and put spaces between it. etc. etc. I really prefer mounting a FTP disk or work local with a text editor of my choice. Mainly that's Sublime, or sometimes BBedit for heavy text manipulation. Ryan did a great Job with Hanna Code. (If I can avoid Hanna Code i will) But even with the nice ACE editor inside, I will use a text editor & paste the results back.
    1 point
  34. That's an easy one <?php echo $pages->get('/your/page/')->right; ?>
    1 point
  35. Thanks for sharing your approach Ryan. I think the xml feed is definitely the difference here. In my situation there was no feed submitted, just the url. After changing the structure to include the articles date, the articles appeared in Google News. It must be a case of this format or that format ...
    1 point
  36. @Ryan: not sure if you've included that in your version, but you might also want to avoid minifying content within pre tags. Personally I'd also leave script tags alone. The minifying solution I used as basis for example code in my hooks blog post didn't originally account for that, which is why it blew my site apart under certain specific conditions. Could've avoided this by altering embedded scripts, but it felt safer to simply skip them. If I really wanted to minify JS, I'd rather use a service built for that -- better results, fewer issues
    1 point
  37. This will need more work. Load audiojs: <script type="text/javascript" src="<?php echo $config->urls->templates; ?>scripts/audiojs/audio.min.js"></script> Create js for controling player <script> $(function() { //Setup the player to autoplay the next track var a = audiojs.createAll({ trackEnded: function() { var next = $('ol li.playing').next(); if (!next.length) next = $('ol li').first(); next.addClass('playing').siblings().removeClass('playing'); audio.load($('a', next).attr('data-src')); audio.play(); } }); //Load in the first track var audio = a[0]; first = $('ol a').attr('data-src'); $('ol li').first().addClass('playing'); audio.load(first); //Load in a track on click $('ol li').click(function(e) { e.preventDefault(); $(this).addClass('playing').siblings().removeClass('playing'); audio.load($('a', this).attr('data-src')); audio.play(); }); //Keyboard shortcuts $(document).keydown(function(e) { var unicode = e.charCode ? e.charCode : e.keyCode; //right arrow if (unicode == 39) { var next = $('li.playing').next(); if (!next.length) next = $('ol li').first(); next.click(); //back arrow } else if (unicode == 37) { var prev = $('li.playing').prev(); if (!prev.length) prev = $('ol li').last(); prev.click(); //spacebar } else if (unicode == 32) { audio.playPause(); } }) }); </script> In your template you can do something like this. if (count($page->audio) > 0 ){ $outAudio = "<audio preload></audio>"; $outAudio .= "<ol class='playlist'>"; foreach ($page->audio as $song) { if ($song->description != "") { $songName = $song->description; } else { $songName = $song->name; } $outAudio .= '<li><a href="#" data-src="'.$song->url.'">'.$songName.'</a></li>'; } $outAudio .= "</ol>"; } echo $outAudio;
    1 point
  38. Hi all, Just to let you know that Wanze and I are now working on this (or rather, he's doing most of the coding and am doing the talking ). We concluded it was best to (first) develop a PW Handsontable class that other modules can load, configure settings and use its methods to render CRUD tables. This way, the class can be integrated into other modules as required, e.g. Batcher and use all or only some of its methods, e.g. limited CRUD, readOnly, etc. At this stage, this means that the module is primarily for developers since there is no UI to configure it. However, once the class has been tested, a Process Module should follow. You can follow the project here: https://github.com/wanze/PwHandsontable. Suggestions welcome, thanks!
    1 point
  39. You are close on this. You can't actually give a field a different name. A field name is the same no matter what template you put it on. It is a constant. Though you can change the label or description according to the context of a template. Fields are not fieldtypes, they are variables on a page. There are fieldtypes in ProcessWire, and you can have as many of the same fieldtype on a template/page as you want. You do have to create the fields (of your chosen types), and assign them to your template. But just like you can't have two variables in PHP named $foo in the same namespace, you can't have two fields on the same page named 'foo'. If you need another field just like 'foo', then clone it and name it 'bar' or 'foo2' or whatever you want. You can create as many copies as you need. In the admin, Setup > Fields serves as your master directory of all fields in your site. To take the example further, some types in PHP can contain multiple values, i.e. arrays. The same goes for ProcessWire, as some fieldtypes are multi-value fieldtypes. Examples include page references, files, images, comments. There's also the 'repeater' fieldtype, which appears to throw all rules out the window, but that's in appearance only as it is technically mapping everything within the rules behind the scenes. Underneath it all, every field maps to a database table, ensuring that everything remains quickly selectable, searchable and consistent throughout the API.
    1 point
  40. Barry, using my MarkupSimpleNavigation module you could simply do: $nav = $modules->get("MarkupSimpleNavigation"); echo $nav->render(array( "max_levels" => 2, "show_root" => true, "current_class" => "on" )); Just in case. Edit: Ok the checkbox thing is not possible. But it would be possible using page "hidden" for page you don't want in mainnav. But your code is also nice and flexible if you need it.
    1 point
  41. Hi, Nichod and welcome to forums! This links can be helpful to start with. http://processwire.com/talk/index.php/topic,49.0.html http://processwire.com/talk/index.php/topic,76.msg405.html#msg405 http://processwire.com/talk/index.php/topic,307.0.html http://processwire.com/talk/index.php/topic,472.0.html http://processwire.com/talk/index.php/topic,80.0.html Also try to search forum. It contains lots of useful guidelines and snippets. Cheers
    1 point
×
×
  • Create New...