Jump to content

Leaderboard

Popular Content

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

  1. 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.
    4 points
  2. I see, your code needs braces & closing parentheses.
    3 points
  3. FormBuilder is also a good way to go for contact forms, especially if you want to set one up without doing any development and have a lot of pre-bundled options as to where the submitted data goes.
    3 points
  4. Markup Simple Navigation Module While there was a lot of people asking how to make navigation, and there were many examples around already (apeisa, ryan...) I took the chance to sit down 2-3 hours to make a simple navigation module. It has even some options you can control some aspects of the output. Installation: 1. Put this module's folder "MarkupSimpleNavigation" into your /site/modules folder. 2. Go to your module Install page and click "Check for new modules". It will appear under the section Markup. Click "install" button. Done. Technically you don't even need to install it, after the first load call ( $modules->get("MarkupSimpleNavigation") ) it will install automaticly on first request if it isn't already. But it feels better. However, it will not be "autoloaded" by Processwire unless you load it in one of your php templates. Documentation: https://github.com/somatonic/MarkupSimpleNavigation/blob/master/README.md Modules Repository processwire.com mods.pw/u Download on github https://github.com/somatonic/MarkupSimpleNavigation Advanced example with hooks creating a Bootstrap 2.3.2 Multilevel Navbar https://gist.github.com/somatonic/6258081 I use hooks to manipulate certain attributes and classes to li's and anchors. If you understand the concept you can do a lot with this Module.
    1 point
  5. Here is a new module for ProcessWire 2.1 that imports pages from a CSV file. By default it will create new pages from data in the CSV file, but you can also configure it to modify existing pages too (existing pages that have the same title). Please give it a try and let me know how it works for you and if you run into any issues with it. This module is something I've had in the works for awhile, and regularly use on various projects, so figured I should clean it up a bit and release it. Also attached are a couple screenshots from it. How to Install: 1. Download from: https://github.com/r.../ImportPagesCSV 2. Place the file ImportPagesCSV.module in your /site/modules/ directory. 3. In ProcessWire admin, click to 'Modules' and 'Check for new modules'. 4. Click 'install' next to the 'Import Pages CSV' module (under heading 'Import'). Following that, you'll see a new menu option for this module on your Admin > Setup menu. Supported field types for importing:* PageTitle Text Textarea (including normal or TinyMCE) Integer Float Email URL Checkbox (single) *I'll be adding support for multi-value, page-reference and file-based Fieldtypes in a future version.
    1 point
  6. CKEditor for ProcessWire CKEditor is a web text editor like TinyMCE. This module can be used anywhere TinyMCE can be used in ProcessWire and it is generally considered one of the best web text editors out there. TinyMCE and CKEditor have always been the two big leaders of web text editors, and they've been equals for many years. Though lately it seems like CKEditor might be a little ahead of TinyMCE in some areas, so I thought we should give people the option of using CKEditor with ProcessWire. CKEditor has a nice inline mode that is desirable in the page editor when you may have lots of rich text inputs. The reason for this is that the page editor loads a lot faster. If you have this need, this would be one reason why you might want to use CKEditor over TinyMCE. Some also prefer CKEditor for other reasons. For instance, @apeisa prefers the table controls in CKEditor to TinyMCE's. Here are a few notes about this module: You already know CKEditor–it's what this forum is using. Though the version included with ProcessWire's module is significantly newer. It is currently beta test. You are advised to test thoroughly before using it in production. You may very well run into bugs, in which case please let me know so that I can fix. It is tested and confirmed compatible with both repeaters and multi-language support. It is now fully hooked into our link and image systems, like TinyMCE. Thanks to Antti for helping with the image plugin. If you want to use the inline mode, you'll need to install the HTML Purifier module first. The toolbar is fully configurable. It is multi-language ready and all text in the module is translatable. Like with TinyMCE, the module optionally supports definition of custom plugins and content.css file. How to install Copy all the files from this module into: /site/modules/InputfieldCKEditor/ Login to your admin and go to Modules > Check for new modules. Click install for InputfieldCKEditor. Now go to Setup > Fields and locate a textarea field that you want to use CKEditor (or create a new textarea field). When editing the settings for a textarea field, click the Details tab. Change the Inputfield Type to CKEditor and save. While still editing the field settings, click to the Input tab for CKEditor-specific settings you may optionally configure. Download ProcessWire Modules page: http://modules.processwire.com/modules/inputfield-ckeditor/ GitHub Repo: https://github.com/ryancramerdesign/InputfieldCKEditor Screenshots Screenshot of regular mode: Screenshot of inline mode, combined with multi-language fields:
    1 point
  7. Two days ago, an idea about a new admin theme came to my mind. Some hours later, I've crafted a first concept in Adobe Fireworks.... The look and feel of the admin is important Two months ago, I've introduced some teachers into ProcessWire. They were none-technically people. At the end, they knew how to use the admin panel to create content or update a gallery on their new page. However at some points, they got confused with parts of the admin theme -beside the problems with our concept on how to use fields and templates for creating content. I think one factor why Wordpress became so large, was the great Adminpanel. It works well and easy (as long as you have a blog and not a twenty-plugins-for-text-pages-site). Editing content on a daily basis is the main task of my customer. I've to take this aspect serious. Problems I wanted to solve Have the page tree always visible. If I do not click the right link, it will be closed after I've finished editing my site More visuals like icons. Simplify some workflows. Creating 3 or 4 pages can result in multiple unnecessary clicks. More focus on important links like the tabs. Guide my customer through some action. Help them to repeat simple tasks. The concept First: Nothing is perfect and its not possible to find one single solution for everything. This was just done in a couple of hours and it's only the first iteration. Quick action button Next to the ProcessWire logo is the quick "Quick Actions" button. It should be possible, to configure it like: "Create a new Page with Template X with page Y as a parent". Use it for skyscrapers, news or galleries. (Yes i know, the arrow is pointing upwards. This is wrong) Two column layout The page tree is always visible (as long as we are in the pages view). It can be navigated as the normal page-tree. If you click "edit" it will become highlighted. Every action that would take you to a new page, would be displayed in the other half of the monitor. Speaking of a "half monitor" - I think that most people use a screen resolution of atleast 1300px. The sidebar should take up to 1/3 of this. On smaller screens, it will become hidden by default or we just simply step back to single pages for each view. If the content is to long, the sidebar becomes scrollable. Page tree I like the Template Decorator made by mindplay.dk. It fits the concept well with black outline icons for every type of template. The same icons could be used in the Quick action menu. I'm note sure what to do with the "move" action. To Do list Think more about the behavior of the elements. Design the modules view. Rework the search and the top menu. Options to "brand" the panel for agencies while keeping the ProcessWire logos. What happens if we are on mobile (small screen) devices? Listen to your feedback.
    1 point
  8. Hi guys, It's been a while that I've posted here on the forum, the reason was - I got a new job few months ago so I've been rather busy and haven't got time to post some new things. I've made a Yahoo! Weather module that connects to Yahoo weather API and pulls current forecast and forecast for next 4 days. The module is completely ready for translation, I've also made days and weather conditions translatable because Yahoo API doesn't offer localization (English only). The widget has normal mode and compact mode and you can easily customize it's appearance through included CSS. Edit 12.04.2015. This module is not longer supported, check out the new version at this link. I'll fix some errors that are currently in this module for those of you who like the old version better then the newer one. Screenshot Download https://github.com/nvidoni/MarkupWeather How to install Copy module directory to /site/modules/ directory. Click check for new modules in ProcessWire Admin Modules screen. Click *install* for the module labeled: "MarkupWeather". How to use Copy this line to template of your choice where you want the weather widget to be displayed: <?php echo $modules->get('MarkupWeather')->render(); ?> This module has the following options: Yahoo! Weather Woeid Woeid is a number located right beside the city name, e.g. http://weather.yahoo.com/croatia/grad-zagreb/zagreb-851128/ Set Locale sets PHP locale, needed for date display localization Date Format date formatted with PHP strftime function Show 5 day forecast below current weather forecast? turn this off if you want to display compact weather widget, shows only current weather Display temperature in Fahrenheit instead of Celsius? show weather conditions in Celsius or Fahrenheit scale Hope you'll like it.
    1 point
  9. WORK IN PROGRESS PLEASE BE AWARE Processwire MVC by Harmster A quick guide Introduction I am developing a MVC like module for Processwire. My goal is to split code login and design as much as possible. If you're familiar with CakePHP and or Zend you shouldn't have much trouble as those are the frameworks I loosely based this on. This module comes with Twig Template engine from Symfony 2 (see more here) Download Download PWMvc at github: https://github.com/Hawiak/MvcModule Configure 1) Drag/upload/add the /site/modules/MvcModule folder into your project's module folder. 2) Search for new Modules 3) Install MVC 4) Press "Submit", this is important, without the submit your paths are not saved. 5) Leave every textfield as it is for now, these are the defaults. 6) Create 3 folders in your /site/templates folder and call them assets, snippets and layouts 7) You are going to need a default layout file, just create a new php file in the folder layouts you just created called layout.php 8) Place the AppController.class in your /site/templates 9) Place the _create_mvc.php in your /site/templates 10) Edit your /site/config.php and add the following line $config->appendTemplateFile = '_create_mvc.php'; Files, Folders and Fields You might be wondering what you just installed. Here's a quickreference guide to the files: FILE: AppController.class This is actually just an empty class and it can be used for things that are all the same over your website, so not controller reliable. For example a title that you want to append on each one of the controllers, or scripts or stylesheets you want to have all over your website. FILE: _create_mvc.php This script sets up the MVC, it fetches the action, calls the methods. This script runs after EVERY template but only works if the template has an MVC field. FIELD: mvc If you've installed the MVC module you will notice you have an extra field installed called MVC. Add this field to every template you want to enable MVC on. FOLDER: assets In this folder there will be 2 folders called, scripts and styles by default but you can place any folders in here. By default MVC will look in these folders for scripts or styles you use using the $script or $styles property of the controller. FOLDER: layouts In this folder you will put your layout files, layout files is the structure of your website, think about a <head> and <body> tag, in general this is the same for most of your views, however you can set layouts per controller, even per action. Read about that later. FOLDER: snippets In this folder you will put your snippet files, snippets are piece of code that you re-use. The Controller The Controller is the Base provided by MvcModule. It has basic functionality and some properties (These will be extended if needed over time) For now the Controller class has these properties: layout - The "layout" property is used to set a file to be used as a layout file, this can be done in the method or the controller. view - The "view" property can be used to change the view for the action, by default the view will be the same as the action e.g. index.view for the index action and edit.view for the edit action. vars = array() - An array with all the variables that are being used in the controller and in the view, try and not use this variable but it is accesible in any controller or the AppController. Use the set() method instead. render_layout = 1 - This will be a switch to turn of the layout rendering, handy for ajax calls. layout_vars = array() - This is a array with all the vars being used in the layout, same applies here as for the vars, try and not use this variable but still it is accesible throughout your project. Use the set_layout_var instead. scripts = array() - An array with all the scripts for a project, use as follow: $scripts = array('1' => 'jquery.js'); The 1 is the sequence of which the scripts will be loaded, it is handy when you want to load jquery before you load foundation or bootstrap. The scripts need to be in the /site/templates/assets/scripts folder by default. styles = array() - An array with all the styles for a project, use as follow: $styles= array('1' => 'jquery.css'); The 1 is the sequence of which the styles will be loaded, it is handy when you want to bootstrap first before your theme The styles need to be in the /site/templates/assets/styles folder by default. And these methods: set($var, $val) - Will set a variable for your View set_layout_var($var, $val) - Will set a variable for your Layout The AppController The AppController is the class you want to extend when creating a controller, its basicly an empty class where you can put custom stuff in, this class extends the Controller inside the MvcModule folder. Make custimizations in this class to prevent issues while updating MvcModule. Setting up a controller To set up a controller you need to create a file in the root of the template folder (/site/template). Name it like you named the template. It needs to be the same name as the template. Then create a class in it with a capital at the beginning, and append it with the word Controller. This is an example for the Controller Test in /site/template/test.php: <?php class TestController extends AppController{ } ?> You'll then have to set up methods inside this class, lets say you have an edit, view, delete and a list view of a few pages. <?php class TestController extends AppController{ public $title; public function index(){ $this->set('list-view', $pages->find('/')); } public function view(){ $this->set('view', $pages->get($this->input->urlSegments[2])); } public function edit(){ $this->set('edit', $pages->get($this->input->urlSegments[2])); } public function delete(){ $page_id = $sanitizer->value($this->input->urlSegments[2]); $this->pages->get($page_id)->delete(); } } ?> The code here is just to demonstrate how different views work and far from efficiant. In order for the views to work you'll have to create views in the view folder, like index.view, view.view, edit.view and delete.view. Because the TestController extends AppController and AppController extends Controller and Controller extends Wire you can use ProcessWire function by using $this. Template variables The following variables should be available in your template/layout/snippet (Not all of them have been properly tested) user pages page sanitizer files input permissions roles templates session config controller wire this (mvc module) Using Layouts A layout is the markup of your website. Its most of the time the same on all the pages for every view. It goes like. A very simple example of a working layout is: <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/> {{ this.render_headers()|raw }} <title>{{ this.controller.title }}</title> </head> <body data-spy="scroll" data-target="#main-nav"> {{ this.render_snippet('navbar.php')|raw }} {{ this.render_view()|raw }} {{ this.render_snippet('login.php')|raw }} </body> </html> As you can see I used $this->controller->title you can set any variable you like and used it in here. Also, there is the $this->view_body. The view body is the result from the rendered view. And I use the method $this->render_headers() this renders the script and styles for your layout defined in your controller. You can define a layout for each controller or even for each method. Using $this->layout = 'yourlayout.php'; anywhere in your controller. Using Snippets A snippet can be used for a lot of stuff, like your navbar or your login, something you want to re use but not necessary on your layout. You can render a snippet using the {{ render_snippet(string $snippet_name, array $vars)|raw }} Just give the name e.g. login.php and an array of variables you want to use within the snippet, the variables are optional. The snippets can also access controller variables and/or wire variables objects. Using Views A view is where you will put your markup and all the stuff that your visitor will see. A simple basic page could just display a body A view that just displays the body that is set in the controller ($this->set('body', $this->pages->get('/'))) and then just echo $body on the view This is an example view: <div> {{ body }} </div> UPDATE Twig template engine has been implemented see the Twig documentation for more info TODO: Create more controller methods that make it easier to generate views Create an Error class for MVC enabled templates. Implementing Twig as a template engine for views and possible layouts, snippets. Implement feutures like extend in twig. May change the core. Advanced testing Write tutorial The module now features an admin panel. Create view files/folders from admin panel Create controllers from the admin panel Create new methods in the controller from the admin panel Changelog - 11/20/2013 - Updated whole module - 11/22/2013 - Implemented Twig, renamed views extension to .tmpl WORK IN PROGRESS PLEASE BE AWARE
    1 point
  10. Dear PW-ers. I would like to inform you that I’ve been in need of Tree View commenting system for a project being developed by me at the moment, thus, I’ve decided to make some additions to the commenting system developed by Ryan. Hereunder, I’d like to share the code with you for your kind information. You can also practice it in case of need. Some screenshots: Download link: FieldtypeComments.zip List of changed files: small change in main.css: Archive updated.
    1 point
  11. InlineEditor 0.0.3 A simple, inline editor that allows you to edit text based content directly in pages themselves. Only use this to experiment. Please do NOT use this on live sites. 0.0.3 Updates Refactored process module Editor now shows result sent by server rather than a generic message New in 0.0.2 Editing repeaters work (actually always did from the beginning) All editor bar colours are now configurable through the admin panel All editable areas are now given a dashed border Few other fixes! Module page: http://modules.processwire.com/modules/inline-editor/ GitHub page: https://github.com/Sinmok/InlineEditor-for-ProcessWire Credits: Big thank you to apeisa for Fredi - whos Module inspired me to make this. It also provided a solid foundation on how to make my own module Ryan - For the whole CMS and the HelloWorld module which taught me how to hook on to page::render! Screenshots:
    1 point
  12. 1 point
  13. str_replace("", "smile.gif");
    1 point
  14. You haven't seen my code.
    1 point
  15. Hi Harmster, This is looking pretty cool. I made a module that does some of the same things yours does, I was able to work around needing to set appendTemplateFile by taking advantage of a couple hooks, you might find what I did useful: https://github.com/jdart/Spex/blob/master/Spex.module#L62
    1 point
  16. 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
  17. there were a bunch of mistakes in the first code, with the wrong var names in the nested loops, that's why it wasn't working, and i moved one line; the comments should tell the story though
    1 point
  18. Thank you diogo for the insight. I was thinking top to bottom. Your solution looks more logical, though. But all roads lead to rome, as they say
    1 point
  19. 1 point
  20. Thanks for the bug report. I was really only testing on the latest dev version of PW. I have just pushed a new version to github that seems to work fine with 2.3. Please test and let me know how you go with it. I really should do some more tweaks on the css for this module, but am waiting till PW 2.4 and the new default admin theme are released as stable.
    1 point
  21. hey Joss - maybe see if this is better... still untested: <? function events() { // get all of the events $events = wire("page")->events; //gets the repeater field $years = array(); $out =""; // find the array of years for all events foreach ($events as $event) { $years[]= date("Y", $event->getUnformatted("event_start_time")); // add properties event_year and event_month to the $event object $event->event_year = date("Y", $event->getUnformatted("event_start_time")); $event->event_month = date("m", $event->getUnformatted("event_start_time")); } $years = array_unique($years); asort($years); // for testing // print_r($years); // print_r($events); foreach($years as $key => $year) { // Output the year $out .="<h2>{$year}</h2>"; // find the array of events this year and put into new array $year_events $year_events = $events->find("event_year=$year"); // print_r($year_events); // loop through the events for this year and add the months to the array $months = array(); foreach ($year_events as $year_event) { $months[]= date("m", $year_event->getUnformatted("event_start_time")); } $months = array_unique($months); asort($months); // print_r($months); // loop through the months and find events for the month foreach($months as $key => $month) { // Output the month as a number $out .="<h3>{$month}</h3>"; // filter only the events for this month, from the $year_events array. $month_events = $year_events->find("event_month=$month"); // print_r($month_events); foreach($month_events as $e) { $out .="<p>{$e->event_who}</p>"; } // end foreach events for this month } // end foreach months } // end foreach years echo $out; } ?> *maybe joss or a moderator could mark this as best answer?
    1 point
  22. I put back the download link with 3 more glyphs ... have fun
    1 point
  23. I've just been playing with upgrading the Foundation 4 profile to version 5. Here are my extensive steps for anyone that wants to attempt them: Overwrite all the .js and .css files Change <nav class="top-bar"> to <nav class="top-bar" data-topbar> in _main.php Fin! The Orbit slider works fine, and I wholly approve of the updated styles as they seem more refined in v5. I think it helps that the ProcessWire Foundation profile doesn't use much more than the grid, Top Bar and Orbit so upgrading wasn't too tricky.
    1 point
  24. randyj, You might want to create a page as a parent for these entries. For example: submissions -- entry1 -- entry2 -- etc... Once you have your entries saved to pages, you can access them using the API, just like any other page. So in the template you use to display entries you could do something like: $entries = $pages->get("/submissions/")->children(); foreach ($entries as $entry) : ?> <p><?=$entry->name_1;?></p> <p><?=$entry->description_1;?></p> <? endforeach; ?> This is written in the browser, so check it for errors.
    1 point
  25. Resurrecting this slightly, but I did something along these lines just now with help from this thread (actually approached it netcarver's suggested way from the first post). It's one where I wanted to skip the first page of adding a name (for events in a calendar) but didn't want to use a repeater - which would achieve the same, but I wanted separate pages. Code as follows: In init function: $this->pages->addHookBefore('ProcessPageAdd::execute', $this, 'generateName'); The function that does the work (specific to my case): public function generateName() { if ($this->input->get->parent_id == 1019) { // 1019 = some page where we want to auto-generate child page names $page = new Page(); $page->parent = $this->input->get->parent_id; $page->name = $this->pages->get($this->input->get->parent_id)->count()+1; $page->template = 'child-template-name'; $page->addStatus(Page::statusUnpublished); $page->save(); $this->session->redirect("../edit/?id=$page"); } } So it checks we're creating a page under a certain parent, sets the right template, creates a page using an integer as the name based on the count of pages under the parent page and then takes you to the edit form for that page. The beauty of it is that since there has been no title entered so far, the user has to fill out the page fields - well title at least - to continue. So why did I do something so convoluted here? Because for what I'm using the title field for I needed to allow duplicate titles, so different names is key to this. The individual pages themselves will never be visited - they're just being pulled into a table into the parent page. Of course I could have used repeaters, but on this occasion I didn't want to. I think that with a little work, and the addition of multiple config lines like in my ProcessEmailToPage module you could expand this to monitor certain parent pages, hook into new page creation and create the page with a specific child template nice and neatly instead of hardcoding it as above. When I get time I might just do that... which might not be any time soon For now the above code works though for anyone wanting to adapt it to do something similar.
    1 point
  26. Just tagged version 1.0.2 which adds an "any" template, documenting all available Fields - this may be useful if you're writing code that works with any type of Page.
    1 point
  27. Welcome to the forum randyj. There's no point and click option to do those things, if that's what you're asking, but there are some good ways of achieving them. For 1. have a look at Ryan's form builder http://store.di.net/products/processwire-form-builder that would be the easiest way of doing it. Rjay's suggestions would be the free (probably more flexible) way of doing it. 2. would be easy to achieve with a very easy to write date check on your template code: "$pages->find('template=form, created<$today-minus-time')"
    1 point
  28. I've updated the CKEditor plugin to work for multiple languages too. Embarassingly I've forgotten how to do a pull request for someone else's repo on Github, so here's the changed .js file - just put it in site\modules\InputfieldCKEditor\ckeditor-4.2.0\plugins\pwlink It's largely based on Soma's code but altered marginally for CKEditor. plugin.zip
    1 point
  29. Hi, Have you had a look through the forum? I think you will find your answer, but to answer your question, yes. With Processwire, the sky is the limit. Have a look (just a few) http://processwire.com/talk/topic/4925-is-it-possible-populate-site-pages-from-a-form-submission-adding-content-without-admin-access/?hl=%2Bsubmit+%2Bpage+%2Bthrough+%2Bforms#entry48121 http://processwire.com/talk/topic/3105-create-pages-with-file-upload-field-via-api/ http://processwire.com/talk/topic/2937-creating-a-front-end-admin/?hl=%2Bsubmit+%2Bpage+%2Bthrough+%2Bforms#entry28954
    1 point
  30. maybe better use $u and not $user if ($u = $session->login($username, $pass)) { echo "logged in $u->name"; } nm screw it
    1 point
  31. Try this instead: $user = $session->login($username, $pass); if ($user->isLoggedin()) { echo 'logged in'; } That should get the user's details into the user variable straight away.
    1 point
  32. What are your personal pet peeves, when it comes to general web / online / digital stuff? I'm gonna start with one of my most-hated "features": lazy loading technique taken too far (as in "load images / assets only when the user scrolls down") The general idea behind it was certainly fine and noble: Load + show additional content only if the user decides to scroll further down a page, otherwise hide that content. Avoid having to wait for content loading that I might - or might not - be interested in. Problem is, that some site-owners not just use, but abuse that method. Case in point: Flickr. It's almost impossible to reach the footer links / menu, because the page keeps loading new pics forever. You may see the footer for a split second, but it disappears again, when addtl. content loads. What's wrong with using pagination? Is that too "old-school"? Making it hard for visitors to reach a certain navigation section is certainly not "best practise", or user-friendly. Some sites have simply exaggerated it to the point, where I'd rather see a "skip intro" button (and that's saying something!). So, what's your favorite pet peeve, when it comes to websites, apps et al?
    1 point
  33. Greetings Manaus, As luck would have it, I just completed a project where the client needed to have a form on the front end where he can upload a CSV file and have it create pages. Using ProcessWire, I put together a system that does the following: 1. Presents the visitor with a simple form with a "title" and an "upload" field 2. Creates a parent page with the title = "title" 3. Uploads and saves the CSV file to the parent page 4. Opens the CSV file using PHP's native fopen 5. Reads the rows of the opened CSV file using PHP's native fgetcsv function; a simple counter skips the first row (which is assumed to be a header row) 6. Creates children of the "title" page, each with the name of the data in first column of each row 7. Presents a "success" message when it works. Your needs might be different, so just vary the code as needed, or post a follow-up question for more details. Here's the code (with my documentation added): <div class="chart_form_box"> <?php if ($input->post->title) // Confirm that a proper submission happened: if the form submission at least has a title, use the field entries to create a new parent page. { // Set a temporary upload location where the submitted "csv_import" file is stored during form processing (will be removed at the end of the process). $upload_path = $config->paths->assets . "files/csv_uploads/"; // This folder must exist in the directory structure. // New wire upload routine for the CSV file. $csv_upload = new WireUpload('csv_upload'); // Reference field name in HTML form that uploads the CSV file. $csv_upload->setMaxFiles(1); // Allow only 1 CSV file upload. $csv_upload->setOverwrite(false); // Rename any current files, instead of overwriting them. $csv_upload->setDestinationPath($upload_path); // Use the temporary location set above to place the CSV upload. $csv_upload->setValidExtensions(array('csv')); // Only allow CSV files. $csv_uploads = $csv_upload->execute(); // Execute CSV file upload. // First round of page creation (for the parent page, created from a title and a CSV file upload). // Set up submissions in the ProcessWire page tree. $np = new Page(); // create new page object. $np->template = $templates->get("windsor_parent"); // Set template for pages created from form submissions. $np->parent = $pages->get("/windsor-list/"); // Set parent for pages created from form submissions. $np->of(false); // Sanitize form submissions and store the submissions as values in the template fields for the new parent page. $np->title = $sanitizer->text($input->post->title); $np->name = $sanitizer->pageName($input->post->title, true); // Create a URL-friendly "name" based on the title. // Save/create the new parent page. $np->save(); // Run the file upload for "csv_upload." foreach($csv_uploads as $csv_upload) // Loop through the CSV uploads, even if there is just one. { $pathname = $upload_path . $csv_upload; // Store the temporary CSV file in the path dedicated to that purpose. $np->csv_upload->add($pathname); // Store the uploaded CSV file in the "csv_upload" field of the template. $np->message("Added file: $csv_upload"); // Include a message regarding the file that was uploaded. unlink($pathname); // Remove the file from the temporary folder since it is no longer needed after it is uploaded. } $np->save(); // Save page again after CSV file upload // Beginning of routine to save children of the page saved above: derived from the rows in the CSV file. if (($objCSV = fopen("http://www.pwplayground.com/site/assets/files/$np->id/$np->csv_upload", "r")) !== FALSE) // Open the uploaded CSV file that was saved above. { ?> <!-- Create a list of the rows in the CSV file --> <?php // Loop through the rows in the CSV file using PHP's fgetcsv function, with the goal of placing the data in each row of the CSV file into fields in our "windsor_child" template. $i = 0; // Set up a counter variable. This is used to keep track of iterations that will correspond to rows parsed in the CSV file. We will use this later to skip the first row, which is a header row. while (($objArr = fgetcsv($objCSV)) !== FALSE) // Instruct fgetcsv to add to the $objarr as long as there is a row to read. { if( $i >= 1 ) // Only run the process beginning with the 2nd row, thereby skipping the header row. { // Beginning of routine to save child pages based on the rows in the uploaded CSV file. $np2 = new Page(); // create new page object $np2->template = $templates->get("windsor_child"); // Set template for child pages. $np2->parent = $pages->get("/windsor-list/$np->name/"); // Set parent for child pages to be the page created above. $np2->of(false); // Set output formatting off during the page-creation process. // Sanitize the rows of the CSV files, just in case someone uploads something evil, then store the values in each row into the template fields for the new page. $np2->title = $sanitizer->text($objArr[1]); $np2->name = $sanitizer->pageName($np2->title, true); // Create a URL-friendly "name" based on the title. $np2->windsor_count = $sanitizer->text($objArr[0]); // Store the first column of each row in the "windsor_count" field of the template. $np2->windsor_name = $sanitizer->text($objArr[1]); // Store the second column of each row in the "windsor_name" field of the template. // Save/create the new child page. $np2->save(); // End of routine to save child pages based on the rows in the uploaded CSV file. } $i++; // Move the counter variable up one tick with each iteration. } ?> <?php } fclose($objCSV); // End of routine to save children of the page saved above. These are derived from the rows in the CSV file. ?> <!-- If uploading the CSV file, and creating the new parent chart page and children pages were all successful, then: (1) Confirming success; (2) Present option to jump to the newly created page; (3) Present option to create another new page. --> <div class="admin_success_box"> <p>SUCCESSFULLY CREATED A NEW CHART PAGE CALLED "<?php echo $np->title ?>"</p> <p><a href="<?php echo $np->url?>">VIEW THE NEW CHART PAGE </a>-- or --<a href="<?php echo $page->url ?>"> CREATE ANOTHER CHART PAGE</a></p> </div> <?php } // / if ($input->post->title) ?> <!-- Actual entry form that allows the user to set a title and upload a CSV file --> <h1>Use the Form Below to Create a New Parent and Children from a CSV</h1> <form action="<?php echo $page->url ?>" method="post" enctype="multipart/form-data"> <p><label class="create_chart_field_label" for="title">Title</label> <input type="text" class="create_chart_long1" name="title" value="<?php echo $input->post->title ?>"></p> <p>Upload 1 CSV File: <input type="file" class="create_chart_field1" name="csv_upload" /></p> <button class="admin_submit" type="submit" name="submit">CREATE CHART!</button> </form> </div> <!-- / chart_form_box --> My apologies for the formatting. (Also, the "chart" references are specific to my particular project.) As you can see, much of this involves using ProcessWire's API to create pages, but with a few extra steps for the CSV material. Thanks, Matthew
    1 point
  34. Hi Steve and welcome to PW. What you are looking for is the "TinyMCE Advanced Configuration Options" set of options on the Input tab of the field you are trying to set up (eg. body). You'll need to add "table" to the plugins field and then "tablecontrols" in one of the theme_advanced_buttons fields. Let us know how you make out with it.
    1 point
  35. Well, another way would be using a different template for the child pages ("child-template" in the following example). Then you'd be able to fetch the grandchildren like this: $grandchildren = $pages->find("has_parent=$cat, template=child-template, limit=$limit, sort=-date, sort=title"); This scales really well and has no issues with the length of the selector string. And who knows, maybe you already have things set up in a compatible way. Of course with "has_parent=$cat" you could also filter by some other property that gives you child pages only: "property_abc=only-child-pages-have-this-value". Or filter out the subchildren level with "template!=subchild-template" or "property_xyz!=only-subchild-pages-have-this-value". Those properties and values are naturally only placeholders to demonstrate possible solutions. The possibilities are more or less endless. Some options, like using different templates, are pretty general but often there are ways specific to the situation available as well.
    1 point
  36. This is very dangerous from a security point of view. Never store information coming from the user directly in the session without sanitizing and validating first. Plus, only store necessary informations, for example the e-mail or user-ID. Example: A bad guy can now alter the post data and include 10'000'000'000 new variables which you try to store in a file on the server. Maybe your server crashes Do you use ProcessWire users for the registrated users? I don't understand why you need to store stuff from a post request into the session. I mean, after the registration your system somehow needs to be able to log in users. And if a user is logged in without the "payed" flag, you show the link to PayPal. But in this case you already have a valid session for the user...? The first is true, because "normally" cookies get deleted by clearing the browser. But when leaving a page or closing the tab, the session remains. How long a session is valid, is defined in your php.ini.
    1 point
  37. Greetings, Thanks dragan for starting this discussion! I've been doing web design since... well, since there was such a thing as "web design," and so I guess I've accumulated some pet peeves. Violating Core Principles Generally speaking, I dislike anything that ignores core principles. It may at times seem that "everything has changed," but when you look at the whole history of the web, it's interesting that certain data/design principles have been constant. Failing the "Concept-First Test" Related to your point about lazy loading: my biggest peeve is applications that start with a visual/design standpoint instead of an information/content/conceptual standpoint. Take a look around, and you can easily find lots of apps that "look cool," but what is the underlying concept? As a test, I like to strip away all visuals and put into simple words what an application does. Then I add in visual/transitional effects, in service of what an application does. It seems to me that too many apps start with the visuals first. I call this the "concept-first test." Overloaded Visuals It feels to me that we are starting to overload our workflow with libraries that simply make superficial visuals work better. I know that Angular.js (for example) can do more than just make things look pretty, but it seems to me that a lot of the applications listed here fail the "concept-first test." I don't mean to pick on Angular.js. It's just an example. (I don't think this direction is sustainable, and we are in for some kind of revolution some point soon.) To make the subject more relevant, I think all this relates to ProcessWire. I have a lot of respect for Ryan and ProcessWire, specifically because Ryan clearly understands the idea of "core principles." CMSs come and go, but the reason Ryan's concept has been around so long and keeps going steady is because Ryan adheres to the principles that govern the ways in which the web works. As the web advances, ProcessWire will continue to be more relevant. I'd definitely like to hear what others here have to say! Thanks, Matthew
    1 point
  38. I'd try to clear the browser cache (and logout/login again), and/or update to latest stable version, and/or run some sort of browser dev tool to see possible JS errors / warnings. (and maybe even trying to access the backend with a different browser altogether)
    1 point
  39. In case you guys haven't seen it yet: http://ckeditor.com/demo#widgets New content blocks and captioned images etc. Might be a useful addition, although the default box is pretty ugly
    1 point
  40. Those two projects sound like great ideas to get stuck in to with ProcessWire. I think most people here would recommend using the development version now, and just keep updating as you go along. It's fairly stable right now, and updates are very simple to do (just replace the /wire/ directory, usually). I don't think there's a date scheduled for a 2.4 release - it will be ready when it's ready I started a website using the dev branch in August, and it's almost ready to launch. I've updated the work-in-progress site several times during development and it hasn't been a problem. So I would say go for it
    1 point
  41. You make some great points Ryan. I'll admit to being someone who is/has been in the past, enticed by some of the nice UI of systems like Craft (or SquareSpace) but more and more I see them as tools for the hobbyist, whereas Processwire has always been a tool for developers and designers. Thanks to Processwire we have far more control over the data and structure of the sites we create and this is one very important asset when competing with tools which make it easier and easier for people to "build their own" sites (and put us all out of business )
    1 point
  42. New site launched today: http://www.katonahartcenter.com/ Thanks to everyone in the forum who answered my posts over the last 8 weeks of developing this site, including adrian, teppo & ryan. modules so far that were essential: After Save Actions Color Picker Admin Custom Pages DataTable Redirects Template Decorator Form Save Reminder Hanna Code Hanna Code Helper Twitter Feed Version Control for Text Fields Form Builder ProCache Forum Threads that helped: http://processwire.com/talk/topic/4849-search-rar-and-tar-result-in-404/ http://processwire.com/talk/topic/4866-time-field/ http://processwire.com/talk/topic/3745-hanna-code/ http://processwire.com/talk/topic/4816-set-field-value-globally-if-null/ http://processwire.com/talk/topic/4602-flexible-downloads-using-pages/ http://processwire.com/talk/topic/1648-ok-to-change-page-name-path-after-save/ http://processwire.com/talk/topic/3987-cmscritic-development-case-study/?p=36867 http://processwire.com/talk/topic/3812-htaccess/?p=37295 using custom admin pages:
    1 point
  43. First of all, my examples were not right - not at all, sorry. Now they're fixed. The problem is that you're limiting pages under each "subchild" separately, not all grandchildren at once. Here's one way to get there: $limit = 4; $cats = $pages->get("/mypage/")->children; foreach ($cats as $cat) { $menu .= "<div>"; $menu .= "<h2 class='titlebg'>$cat->title</h2>"; $grandchildren = $pages->find("parent={$cat->children}, limit=$limit, sort=-date, sort=title"); if($grandchildren) { // if they have GRANDchildren $menu .= "<ul>"; foreach($grandchildren as $child) { $menu .= "<li><a href='{$child->url}'>$child->title</a></li>"; } $menu .= "</ul>"; if($grandchildren->getTotal() > $limit) $menu .= "<span><a href='{$cat->url}'>See More</a></span>"; } $menu .= "</div>"; } This would give (with the example structure again): cat1 cat2 child2.1.1 child2.1.2 child2.1.3 child2.2.1 See More cat3 child3.1.1 This trick to get grandchildren ("parent={$cat->children}") would not be the way to go if there were a lot of "subchild" pages under any "cat" page. This is because the selector expands to something like "parent=1234|1235|1236|1237|...|1507|1508" giving a too long selector string at one point. But assuming there aren't more than a couple of dozen of them, this would work just fine. I also added a little condition to show "See more" only if there are more grandchildren to see - just as an example.
    1 point
  44. I'm sure there's a better way - if only I knew what you're trying to achieve exactly . Here's an example of a page structure to demonstrate what's happening: With "limit=2" your code prints out: cat1 cat2 child2.1.1 child2.1.2 child2.2.1 child2.2.2 cat3 And with "limit=3": cat1 cat2 child2.1.1 child2.1.2 child2.1.3 child2.2.1 child2.2.2 cat3 Reading the code, it's pretty much expected output to me, but obviously not the one you're after . You're printing first two (or three) "child" pages under each "subchild" page found under children of "/mypage/" ("cat" pages). (Edit: and leaving all divs open.) So, what is the output you'd like to see with the page structure outlined above? (Edit 2: Fixed my examples...) (Edit 3: Really fixed my examples... It's not my day.)
    1 point
  45. I have used a lot of time with this issue. The bigger and more complex sites we build, the more "ad hoc" UA is needed. Defining access on "who can access/edit news" is not relevant when your site has 20 news archives for different groups. Or when you want to create new "workgroup" and choose who can access that. Of course all these can be build custom, but it is lots of work and PW doesn't provide anything as a base for that. I have module baking that solves this very issue. It has basic functionality already made and it for most parts bypass the template based UA totally. This is by intention very simple at this first stage: just view and edit rights and user that belong to groups (one user can belong to many groups). Not sure about the licensing yet, I might release this as a commercial module, but also happy to transform it to a open source project for community (if you guys feel this is promising). Ryan has seen the code and we did hit one core problem: circular reference. My module requires page field that many times references itself. This creates problems in certain situations: actually only when page is saved but no changes is made. It is not ready yet, but the basic functionality should be there. I have build this few times already and always from different angle. I believe this is the most simple one (see the find hook that has been the problem in those previous modules). Anyways, I know at least Teppo and Nik have been interested in this, so here we go: https://github.com/apeisa/UserGroups/
    1 point
  46. Tested a website with ProCache activated. I also did some other stuff like gzip compression and some tweak for the htaccess I've found around the net. Don't forget about a clean and lightweight html markup and compressed CSS/JS/Images. Got a 90/100 + 95/100 Google Page Speed. http://developers.google.com/speed/pagespeed/insights/?url=weg.conclurer.com I didn't add a JS loader or integrated CSS for the "above the fold" category. Here's a nice guide to do that http://www.feedthebot.com/pagespeed/prioritize-visible-content.html EDIT: It's funny, that google does critize its own Webfont CSS Loading...
    1 point
  47. Hi, maybe a bit OT but worth to mention I think: PHP has a nice function to create and open a pointer to a temporary file - but with the advantage that it first write to memory and only flush content to the disk if a specified amount of memory is reached: $mb5 = 5 * 1024 * 1024; $fp = fopen('php://temp/maxmemory:' . $mb5, 'rb+'); // then add content to the pointer ... fputs($fp, "hello\n"); // At the end rewind and echo out the content: rewind($fp); echo stream_get_contents($fp); The first 5 MB will kept in memory and if the content hits the limit it gets written into a temporary diskfile. see: http://www.php.net/manual/en/wrappers.php.php
    1 point
  48. Hey guys! I have to admit that I'm a huge fan of good design. Today P&T have released their Craft CMS 1.2 and .. woow! It looks good. I have tried that system as well but will stick to PW because it's the most powerful and flexible system in my opinion. But Craft just looks so much better. So, are there any plans to re-design the backend any time? I know the backend looks ok. And yes, it works. But design changes and for quite a lot of people, it's an important factor when it comes to choosing a CMS. (Please don't come up with some "they have no ideas about it then" kind of stuff) Why not stick to web design trends and update the backend from time to time? I'd like to see PW both, most powerful and best looking CMS Craft might really be a great inspiration, what do you think? And yes, re-designing might be some work. But finally it's part of the way you "sell" your product. Let PW be modern in the frontend as well
    1 point
  49. First of all, I'm a big fan of PW's current admin UI and also aware of other possible admin themes, but I'm also very happy about the discussion in that thread @kongondo linked above.. and thus also the opinions expressed here Common argument here and elsewhere seems to be that PW allows you to swap the default admin theme to something else, but I don't think that people saying this are really getting it. There's a very special position deserved for default theme. It's an entry point, first impressions are based on it, and it also plays an important role when defining PW's external image, ie. what kind of message it wants to send. I've evaluated a few CMS products myself and I must admit that for me first impressions are very important. I'm the kind of guy who first looks for screenshots and then reads the specs. That's just how my mind works and saying that it's "wrong" is, in my humble opinion, more than a bit arrogant. Current default admin theme is very usable and I myself like it's simplicity a lot, but that two-column layout @Philipp presented in aforementioned thread was simply jaw-dropping. Just because PW is a flexible framework for building awesome custom stuff doesn't mean that it can't be pretty and sexy out-of-the-box, especially if that's what many (otherwise very capable) web designers / developers are looking for. There are a lot of CMS products around that all claim to be flexible, extensible and usable. It's simply not an easy market to crack and thus I don't think that we should skip over any steps that can make PW's road less rocky.
    1 point
  50. Nice job Khan! Perhaps we should integrate this as an option into the main Comments fieldtype? Or should be be a separate fieldtype (under a different name)?
    1 point
×
×
  • Create New...