Jump to content

MatthewSchenker

PW-Moderators
  • Posts

    677
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by MatthewSchenker

  1. 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

    • Like 5
  2. 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

    • Like 5
  3. I'd have to say the auto saving of drafts is rather huge for me, specifically. My whole crew writes directly within the CMS and I can't count how many full articles I've lost due to not clicking save and keep unpublished. It's a huge pain.

    I'm curious: how are articles being lost? Are people navigating to another page without saving? It seems to me there is a minimum of responsibility for anyone creating content, which would include saving your work. Or is there another problem here?

    Thanks,

    Matthew

  4. Greetings,

    Nice work! The site works fast and is easy to navigate. You really packed a lot of information into the site, while keeping the navigation clear and logical!

    One minor issue: on an iPad running Safari, some footer text colides (see attached screen shot).

    Congratulations on the successful launch. Thanks for sharing!

    Matthew

    post-802-0-77584100-1384171525_thumb.jpg

  5. I just watched "Cloudy With a Chance of Meatballs" with my kids and now I'm dreading this job a bit--can't recommend watching that film before doing batch operations. :-)

    Greetings,

    Very funny! But I dare you to try coding while your kid listens to "Fox in Socks" (as I did this morning). You will temporarily abandon all hope of OO or MVC.

    Back on topic: the importing ideas in this discussion are great!

    Thanks,

    Matthew

  6. Greetings Larry,

    Excellent discussion!  Coming from the world of PHP frameworks, I am also very curious about the most "MVCish" way of working in ProcessWire.

    An interesting challenge is that a lot of the "M" and "C" necessities in frameworks are handled differently (I would say better) in ProcessWire.  And yet, as we develop more complex sites, the templates can get quite involved with material that properly should be abstracted into some sort of classes/functions/controllers.

    What's great about ProcessWire is that we have the best aspects of frameworks, with the freedom to be creative in how we structure views and functions/classes, and it takes care of many crucial database elements in efficient ways.  We then have the potential to develop interesting structures, without being forced to worry about too many conventions.

    I'd love to see a discussion here where we share creative ideas for structuring ProcessWire sites in MVC ways.

    Thanks,

    Matthew

    • Like 4
  7. Greetings,

    When I was still using Joomla, SEBLOD CCK was the component that helped me move my sites to a more flexible system.

    To give credit where it is due, SEBLOD did bring some flexibility to Joomla, providing custom fields and a semi-clean API.  But the issue is that SEBLOD serves almost as a separate CMS piggybacked on top of the core Joomla installation.  For example, rather than replacing the core Joomla template scheme, it adds another template layer.  SEBLOD alters core Joomla in significant ways, and every time there is a new Joomla release, it breaks important pieces of SEBLOD.

    I've always said that the only reason that SEBLOD (and other Joomla "CCKs") exists at all is because Joomla does not have custom fields built in by default.  In this regard, Drupal is a much stronger general-purpose CMS (if you can stand dealing with its template requirements).

    Very interesting that the YouTheme team built a Symfony-based CMS.  YouTheme's Zoo CCK was (I believe) the closest competitor to SEBLOD.  The YouTheme developers are very skilled, and I always wondered what made them stick with Joomla when they clearly had the ability and viewpoint to develop something better on their own.

    Thanks,

    Matthew

    • Like 1
  8. Greetings,

    One other point to make here, which I hope would make the client think very carefully...

    It's far more difficult to re-make a site than to make it right the first time. I always emphasize just how frustrating it is to take a site from Joomla to another proper system like ProcessWire after it has already been built up significantly.

    Earlier this year, I moved a large site from Joomla to ProcessWire, replicating existing plugin functionality and data, and it was a horror. Right now, I am working on a project where the client has an existing Joomla site, but they let me start with a clean slate in ProcessWire. The second one is developing far more rapidly, even though it appears to be more work to start over from scratch.

    Making this kind of "do it right the first time" argument can be a good entry point to your discussion with the client, for two reasons:

    1. The client's natural follow-up question will be, "Why would it be a mistake to use Joomla?" That gives you an opening to explain the specifics.

    2. You can argue on the level of time, money, and efficiency -- rather than preference.

    Just some more thoughts to consider. Again, more specifics about the project can help!

    Thanks,

    Matthew

    • Like 2
  9. Greetings,

    This is a discussion I am glad to get into...  I'd want to know more details about what the client needs and expects to accomplish, because that would definitely help make stronger arguments against Joomla.

    But up front, my main arguments are...

    1. Joomla does not support custom fields in its core.  The only way to be able to have custom fields in Joomla is to add what is known as a "CCK" (Content Construction Kit), and that essentially grafts what I call a sub-CMS onto the main CMS.  Without a CCK, you are stuck with the basic fields that Joomla assumes you will use for all your pages ("articles").
    2. It is extremely tricky to implement what we think of as routine JS and PHP elements in Joomla sites.  You cannot properly work directly inside your page code, as everything in Joomla is done inside "module positions" for your pages.
    3. Speaking of templates, the templating structure of Joomla is extremely limiting.  Everything in your site must be placed inside those "module positions," you must define everything that goes into those module positions using a convoluted back-end, and your templates inherit all sorts of core Joomla styling and layout assumptions.  In other words, you cannot simply create various layouts and name them according to specific content types.
    4. Joomla core makes numerous assumptions about how things should look and behave.  If you want to change how a blog list looks, for example, you must hack core settings of either your core Joomla install or your templates.  If you simply want to say "See Full Story..." instead of "Read More..." at the end of your intro pages, you have to hack the core code.
    5. Joomla makes it extremely difficult to manipulate URLs in any kind of creative fashion.  Because it assumes you must always insert an "article ID" into your URLs, you cannot go very far with dynamic pages because you cannot know the ID of your "articles" before they are created.
    6. The core installation of Joomla has a convoluted directory structure: 15 main directories and an arrangement of sub-directories that are a major challenge to follow.  Often, sub-directories are literally repeated and material of the same type (such as plugins) can end up in several different directories.  This is because Joomla is designed to be built completely in the GUI, which gets us back to the problem described above in #2.

    These are just a few of the problems that plagued my work with Joomla.  But again, the real power comes when the client says, "I want this..." and you can show how much better and easier it is to do it in ProcessWire.

    Can you follow up with some of the specific requirements of the client?  Then I can give you more particular arguments.

    Thanks,

    Matthew

    EDIT:

    onjegolders: yes, indeed... Looking back, I think I have actually posted a few "Joomla rants" here in the ProcessWire forums:
    http://processwire.com/talk/topic/2129-justifying-diy-coding-vs-installing-modules/?p=20438

    http://processwire.com/talk/topic/4143-wordpress-dominates-19-of-the-web/?p=40964

    http://processwire.com/talk/topic/3952-reservations-for-hotel-rooms-and-restaurant/?p=38742

    • Like 7
  10. Greetings,

    Thanks diogo for bringing this to our attention. The people at about.com should be embarrassed to have something like this tarnishing their domain. Even if the subject was restaurants and not CMSs, the thinking that is revealed here is atrocious.

    The author's logic goes like this: I know there are many choices out there, and I haven't tried them all, but I already decided that they are not as good as this one.

    Generally, I really dislike using the number of plugins as an argument in support of a CMS. Joomla constantly boasts about having 7500+ plugins, and it is meaningless.

    Thanks,

    Matthew

    • Like 2
  11. Well said, this resonates with me and I suspect if you told me why these things are important to you I may share some of your values. I think this statement could be further developed into a very effective personal branding statement. Your branding statement will help connect to the types of clients you are looking for.

    I learned to appreciate PHP via frameworks (mostly CodeIgniter, but also some time with Yii, Laravel, and Symfony).  More recently, I've come to appreciate CakePHP.  All of those frameworks provide great power for making complex apps.  But the syntax can sometimes be a bit opaque.  At the same time, I was also using Joomla (with a thing called Seblod, which promises to turn Joomla into an app builder).  I could not wait to drop Joomla.

    Then I discovered ProcessWire last fall, and right away it seemed to me that it offered the same power as the PHP frameworks, but with crystal-clear syntax.  At first, I thought for sure there had to be a lack of depth for ProcessWire to be that clear, but at every turn I've found that ProcessWire provides depth very close to what's needed for most apps, while maintaining clear syntax (or to borrow a word thrown around in Laravel circles, "expressive" syntax).

    To me, ProcessWire immediately felt like a framework, because it makes no assumptions about how "themes" need to be constructed, and because it has nicely defined API methods for doing everything in code.  Having also come from the Joomla world, and having also spent a bit of time with Drupal and WordPress, I was curious about ProcessWire positioning itself as a "CMS."  As I said, it seemed to be more comparable to frameworks.

    Back to your point: people who just want drag-and-drop site building won't use ProcessWire very much.  ProcessWire is not equivalent to that kind of system.  But ProcessWire can pull in people from Drupal, WordPress, and Joomla who want to customize those "big three" CMSs and are frustrated by assumptions those systems make.  I know there are a good number of people in this position in all three big CMSs.  They can use ProcessWire like a framework, and get the CMS capabilities they look for.  I don't know exactly what segment of the big three is represented by this description, but I know from experience they are there.

    Thanks,

    Matthew

    • Like 6
  12. Greetings,

    Well, one of the ideas of using ProcessWire (in my mind) is to try and talk to people about the benefits of this system over "the big three."  I actually think that's important, because ProcessWire is a terrific system and deserves to be used in place of the big three as much as possible.

    As we all know, there are many different categories of clients.

    There are clients who essentially ask us to develop their plan and use whatever system we want.  They don't even care or know anything about different systems. They just know results.  In those cases, ProcessWire is the easy path.

    There are clients who are already tied into another system (like Drupal or WordPress) but they let us know up front they are open to moving to a new and more flexible platform.  These are also easy ProcessWire projects.

    Then there are those clients who are sort of "fishing around" and don't quite know what they want.  They talk to us, and get pretty far in the discussion, then make decisions about a system.  This is the category I was referring to earlier.  To summarize: these are clients who are sort of learning in the process of discussing things with you.  My problem is, I get excited about a project too early.  Now, I totally agree with one of sshaw's comments above that I should streamline my early discussions so I don't invest too much time with these sorts of clients.

    Thanks,

    Matthew

    • Like 1
  13. Greetings,

    WillyC: I disagree. The potential clients who say this are not developers. True, they start off asking to do this or that, but then they poke around and Google about websites. When they do that, WordPress makes a dominant appearance.

    Developers would know better once I showed them ProcessWire!

    Thanks,

    Matthew

  14. Greetings,

    sshaw: your last post is interesting and I am glad we can share experiences on what works and what doesn't work.

    The only spot where I would correct you is where you say this: "I think you lost the gigs, because you didn't provide a service that your clients wanted."

    This definitely has happened. But I have put such experiences to rest long ago. It used to be, if a client came to me with a WP or a Drupal site I would try to convince them to make a switch to the framework I was using. It often worked, and I successfully moved some people from one system to another. But in the past couple of years, I have stopped that approach. These days, I am more likely to say that "this is the system I use, so if you want Drupal or WordPress, you should call someone else."

    The only time I still get caught in this is when the client is open to new ideas and listens to proposals, completely agnostic about one system over another. Then at some point they come to me asking about WordPress. Often, but not always, they choose to go with WordPress. If they had said that up front, there would be no discussion. This just happens to be a bad couple of weeks!

    The issue is, people start off the discussion about building a website without knowing much, then in the process they start doing some research. Of course, most Google searches they do on building websites are going to point them to WordPress. As I said, it then becomes a matter of explaining that bulk does not equal better.

    Thanks,

    Matthew

  15. Greetings,

    This is a sore topic because -- for some crazy reason -- two potential jobs in the past week slipped away from me: one to Drupal and one to WordPress.  In both cases, the client was ready to move forward and I had the scheme for the sites laid out.  Then they got ideas about the "other" CMSs and just did not believe that sites could be created more rapidly and better in ProcessWire, with more design and administrative customization now and in the future, and with better security.  The sheer bulk of Drupal and WordPress became their overpowering argument.

    It hurts...

    I think this question becomes easier for those of us in the following two scenarios:

    1. You already have a successful independent career as a developer and your portfolio convinces clients to use your system of choice

    2. You work for an agency and have successfully convinced your bosses to use ProcessWire instead of one of the "other" CMSs

    For those of us who are in the middle (you're an independent, still building your clientele) it can be very frustrating to lose jobs to systems that you just know are inferior.  I'm not going back to Joomla/Drupal/WordPress.  But I'm not sure what the solution is for this dilemma.

    As a side-note: the more I use ProcessWire, the more I am convinced that the comparison we should promote is NOT ProcessWire vs "The Big Three." I think the comparison we need to make is ProcessWire vs PHP frameworks like CodeIgniter, Cake, and Yii.  Of course, this would mean re-structuring the messages from the site and what gets presented first (API or admin back end).  This is probably a separate discussion, which I would really like to have!

    Thanks,

    Matthew

    • Like 1
  16. Greetings.

    Thanks diogo for answering! Yes -- video.js.

    To answer your other question: the videos are hosted on my server. The client wanted to control where the videos are housed and seen, and there are some copyright demands.

    In the future, I may store videos on an Amazon S3 directory.

    I'm in the process of expanding this site. Will post again on this.

    Let me know if you have other questions and I'll be happy to share!

    Thanks,

    Matthew

    • Like 1
  17. Greetings,

    Assuming you have your users logging in before they try to access the page in question, you could use something like this:

    <?php
    if ($user->isSuperuser() OR $user->hasRole("admin"))  // If user has one of these roles, he/she sees the page.
    { 
    	if ($input->get->project == 14) // Test if the query string has this value.
    	{ ?>
    		<div class="private">
    			Do Whatever You Need Here
    		</div>	
    	<?php
    	}
    } ?>
    

    Everything that can only be seen by authenticated users goes into the "private" div.

    Thanks,

    Matthew

  18. Greetings,

    Sparrow: doing front-end work is great and ProcessWire allows for really nice custom elements.

    Keep in mind that there are multiple goals here:

    1. Enter the material via forms (as discussed above)

    2. Editing and/or deleting existing pages

    3. Checking for existing pages when creating and/or editing to prevent two pages with the same title/name

    4. Different page views depending on user roles (can consolidate certain views with actions mentioned in step 2)

    This is fairly standard app development stuff, of course.  The point is, ProcessWire makes it pretty easy to implement.  You just need to focus on each part, one at a time.

    Follow up with questions on particular parts and you'll get answers!

    Thanks,

    Matthew

    • Like 1
  19. Greetings Sparrow,

    A lot of what you say is a great way to use ProcessWire.  I'll address your questions on front-end forms (user submitted data).  I've been building a lot of ProcessWire sites with front-end forms.  In fact, the more I work the more I do this.  (I'm working now to package these activities into functions).

    With front-end forms, there are two major ways to set up your fields:

    1. Call ProcessWire "inputfields"

    2. Use HTML form fields

    Adrian gave you a link to a great post from Soma about the first method.

    I've done most of my work using the second method.  I posted something a while back on doing this, which you can find here:

    http://processwire.com/talk/topic/3105-create-pages-with-file-upload-field-via-api/

    Take a look at all this, then follow up with specific questions on your needs.

    Thanks,

    Matthew

    • Like 2
×
×
  • Create New...