Leaderboard
Popular Content
Showing content with the highest reputation on 11/22/2013 in all areas
-
You could definitely use PW to build Facebook (feature wise). There is absolutely no reason to worry about being biggest and most active website of all, before you haven't written a line of code for the project. I have build websites for over 15 years (8 of them professionally) and there have been very few scalability issues. But oh boy I have worried. The very same question that epreston asked: does it scale? After these 15 years I am pretty sure it is much harder to build service that will be so popular that actually needs to be scaled - than the actual scaling.3 points
-
Hi all, I've finally managed to set up my website where I intend to post ProcessWire tutorials. The site (lessons) is very much WIP. I have tried to make the site as responsive as possible. I have only tested in Chrome and FF. I'd rather write more lessons than test in IE to be honest so I won't pursue that... I will try to post regularly but can't make any promises as to the frequency . I intend to randomly post some pre-planned lessons. I will update this forum post everytime I post something new. If you have questions, pointers, etc about any lesson, or a request for a specific lesson, please post them here. This way, other forum members can assist in answering the questions . Thanks. /k ==================================================================== Edit: 28 August 2014 - Fist Tutorial is up (OK, it's Blog Module documentation ) Creating a Blog in ProcessWire (Blog Module how to) - 28 August 2014 [99% done] Next: 'All you ever wanted to know about ProcessWire Modules [and other cool things]' - COMING very SOON2 points
-
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.zip2 points
-
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, Matthew2 points
-
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.2 points
-
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/2 points
-
A quick tutorial how to create file downloads using pages You will be able to create a new page using template "PDF" (or any you setup), upload a pdf file. You then can select this page using page fields, or links in Wysiwyg. The url will be to the page and NOT the file itself. This will allow to keep a readable permanent unique url (as you define it), unlike /site/assets/files/1239/download-1.pdf, and you'll be able to update/replace the uploaded file without worring about its filename. Further more the file will also have an id, the one of the page where it lives. Clicking those links will download or open the file (when target="_blank") like it would be a real file on server with a path like /downloads/project/yourfile.pdf. You'll be also able to use the "view" action directly in the page list tree to view the file. Further more you'll be able to esaily track downloads simply by adding a counter integer field to the template and increase it every time the page is viewed. Since the file is basicly a page. This all works very well and requires only minimal setup, no modules and best of it it works in the same way for multi-language fields: Just create the language alternative fields like "pdf, pdf_de, pdf_es" and it will work without modifying any code! Still with me? ok PW setup Download folder: Create a template "folder" or "download-folder" with only a title needed. Create pages in the root like /downloads/project/ using this template. Setup the template for the pdf files 1. Create a new template in PW. Name it pdf 2. Goto template -> URLs tab and set the URL end with slash to no. (So we can have /path/myfile.pdf as the URL) 3. Create a new custom file field, name it pdf. Set its maximal count to 1 under -> Details tab. 4. Add the pdf field created to the pdf template. Easy. 5. Create a new "pdf" page using the pdf template under a download folder you created earlier. 6. Give it the title and in the name field add ".pdf" to the end (could also leave as is) Template PHP file for the pdf files 1. Create the template file pdf.php in your /site/templates folder 2. add the following code: <?php // pdf.php if($page->pdf){ wireSendFile($page->pdf->filename); } Done. To see the options you have with PW's wireSendFile() you can also overwrite defaults <?php // pdf.php if($page->pdf){ $options = array( // boolean: halt program execution after file send 'exit' => true, // boolean|null: whether file should force download (null=let content-type header decide) 'forceDownload' => false, // string: filename you want the download to show on the user's computer, or blank to use existing. 'downloadFilename' => '', ); wireSendFile($page->pdf->filename, $options); } Simple and powerful isn't it? Try it out. Some thoughts advanced Create as many file types as you like. It might also be possible to use one "filedownload" template that isn't restricted to one field type but evaluate it when being output using $page->file->ext, or save the file extension to the page name after uploading using a hook. One last thing. You can add other meta fields or preview images to the template and use those to create lists or detail pages. It's all open to goodness. Again all without "coding" and third-party modules. Further more you can use the excellent TemplateDecorator to add icons per template and have a nice pdf icon for those pages. This as a base one could also easily create a simple admin page for mass uploading files in a simple manner, and create the pages for the files automaticly. ImagesManager work in the same way. Cheers1 point
-
As some of you might have noticed recently there has been a large "Frontend Performance Talks Offensive" (not only) by Google Engineers. Here are some high quality (regarding content) Videos which i enjoyed very much and thought you also might be interested in. A Rendering Performance Guide for Developers by Paul Lewis: Performance Tooling by Paul Irish Your browser is talking behind your back by Jake Archibald Gone In 60fps – Making A Site Jank-Free by Addy Osmani http://addyosmani.com/blog/making-a-site-jank-free/ Any suggestions for more interesting performance related stuff are welcome!1 point
-
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 AWARE1 point
-
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
-
Hi Xeto, You can do this easily. Just create the categories in the backend and reference their id on the csv you are wanting to import. See Niks post http://processwire.com/talk/topic/383-module-import-pages-from-csv-file/?p=214761 point
-
Good point - it's closer to how PW is handling languages that way. I like the idea of a lang=all for my edge case though ;-)1 point
-
Just a quick one (on a mobile atm). If imageTags is a field on an image page then I guess the selector should be just "imageTags%=$q, limit=20". Does this (with the foreach RJay proposed) solve the issue?1 point
-
Hi, Here are a few links to get you started. Has example of a form built already http://processwire.com/talk/topic/59-module-want-form-builder/page-4#entry11639 A tutorial on building forms using PW fields. You should read through this and compare it to Ryan's post below. It will explain a lot. http://processwire.com/talk/topic/2089-create-simple-forms-using-api/ Ryan's simple contact form. I just used this the other day. All you really have to do is copy and paste his code. You would exclude the include("./main.php"); unless you have one of course and echo out the form as shown below. http://processwire.com/talk/topic/407-processing-contact-forms/?hl=%2Bcreate+%2Bsimple+%2Bcontact+%2Bform#entry3208 include("./head.inc"); echo $page->body; include("./foot.inc");1 point
-
There is a simple module that does this already http://modules.processwire.com/modules/form-template-processor/, the good thing is that it's a also a well commented starting point for something more complex. You might want to also have a look at this module http://modules.processwire.com/modules/form-template-processor-mailer/ that was already built from the previous one.1 point
-
Greetings Manaus, Then you can use the code I posted, but specify more fields. For example, where I have this, which specifies two fields in my template called "windsor_count" and "windsor_name": $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. You would have four fields: username, email, password, and project_code, and they would reference [0] through [3] in your variable storing the array ($objArr in my example). Thanks, Matthew1 point
-
1 point
-
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
-
1 point
-
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
-
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, Matthew1 point
-
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
-
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
-
[...] You may not use conversion or editing tools on the Licensed Web Fonts. [...] it say fonts not character font=all the characters make pw logo in font no diffrent thans pw logo in png or eps1 point
-
Updating the guide, rewrote the whole module. Still not reliable but I need some testing from other people too. Wrote the install instructions and will update this over the week.1 point
-
Mark, Thanks. As for posting a tutorial, I am afraid some other work has gotten in the way in the last couple of months :'(I hope to start writing during the xmas break (finger's crossed!). Thanks for your interest. Cheers, /k1 point
-
German is more straight and precise different from english. Some german text on neuwaerts from felix made me understand some things more clear. One good example of that is how felix uses the word "Strukturelement" to explain pages in processwire.1 point
-
This is awesome Ryan! I actually used your snippet below and modified it to do what I needed and it worked perfectly, Just took me longer to create the temp field .. foreach($mypages as $p) { $p->of(false); $p->image->description = $p->temp; $p->save(); } Your above snippet is definitely a time saver and has been added to my library. It works perfectly when I tested it. I just had to modify it slightly to meet my needs. I would just like to say your willingness to bend over backwards to assist others in this forum is a true judgement of your character. You and several others go above and beyond to help others learn with examples. One in particular I would like to mention who helped me way beyond my expectations was Nik. Just like you, he took the time to break things down with examples and even explanations. How you both manage to find the time, I do not know. To you, Nik and all the others who help us learn everyday, I thank you sincerely for helping us. I am confident I am speaking for others as well and say that ya'll truly make a difference to those of us following in your paths.1 point
-
Rest assured this will be added soon (along with Horst's updated ImageSizer stuff), and certainly before the version is bumped to 2.4. Thanks Soma for your updates here. There are a lot of people using dev in production, and there were just enough code changes/additions in this one that made me want to be sure I took the time go go through it thoroughly line-byline in the code, and then test thoroughly. It often takes me a couple hours to work through individual pull requests to feel like I've given them all the attention they deserve. So while I'm not good at being timely with it, I am generally good at being thorough with it. Also, as Soma mentioned, busy times (looming client project deadlines, which always seem to gravitate towards the final months of the year). But thankfully those busy times are just temporary, as ProcessWire is where I prefer to spend my time.1 point
-
Well. Even if no one seems to be interested i'll keep updating this if i stumble upon interesting links. Maybe this will help someone in the future Here we go. How to prioritize visible content: http://www.feedthebot.com/pagespeed/prioritize-visible-content.html1 point