Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/16/2017 in all areas

  1. I've added Mailchimp support A few more screenshots: Subscription Lists - Services New Subscription List - Mailchimp Module Configuration - Service Selection
    5 points
  2. If it's one page meant to be used site-wide, you might consider creating a template file (let's say styles.php) for it that outputs the css (in the Files tab, set content-type to text/css and tick the box to not append the standard file). Then you can link to that page just like you do with every other stylesheet, and you can even use template cache. That way, your regular templates are kept tidy and you don't send unnecessary styles over the wire with each request. To be able to select the text/css content type, you need to add the following to your site/config.php first: $config->contentTypes = array( 'html' => 'text/html', 'txt' => 'text/plain', 'json' => 'application/json', 'xml' => 'application/xml', 'css' => 'text/css' );
    4 points
  3. Here's a screenie of the front end:
    4 points
  4. Hi @rst You can find a lot of recommendations from Ryan how to optimize such cases https://processwire.com/blog/posts/optimizing-404s-in-processwire/
    3 points
  5. @DaveP, I've found this useful over the past week on a client project, so a big thank-you! I think you should change the filename & classname of the module from "TextFormatterInsertDummyContent" to "TextformatterInsertDummyContent" though. At the moment, this module does not appear in the modules list grouped with all the other Textformatters but it is in its own, lonely, "Text" group. Unfortunately, this does require making a breaking change to the module, as the filename and class name (plus internal path names etc) all need to change. The upshot of which is that the module can't be simply upgraded (at least, I think not.) Anyway, I've forked your repo (here) and made some changes. I've also added code to randomise the output on each call. There is also a corporate branch that sources its 50 paragraphs from Corporate Ipsum.
    3 points
  6. Hi @louisstephens. I do not know if your input to upload pictures looks like this: <input type="file" name='images[]' multiple="multiple" accept=".png, .jpg, .jpeg, .gif"> Important images[] must be array ... And im set images $p->set("images",$file); My code looks like this: // GET NAME $name = $input->post->name; $p_name = $sanitizer->pageName(time() . '-' . $name); // START CREATING PAGE $p = new Page(); // TEMPLATE TO SAVE ITEM $p->template = "contact-item"; // Parent Page $p->parent = $pages->get("/contact/"); // TURN OFF OUTPUT FORMATTING, IF IT'S ON $p->of(false); // START SAVING INPUT FIELDS $p->title = $name; $p->name = $p_name; // Page Save $p->save(); // UPLOAD IMAGES ( If input images was submitted ) if ($_FILES['images']['name'][0] == true) { // Set Maximum Files $max_files = 3; // Find Created Page id $get_id = pages()->get("name=$p_name"); // Final destination Folder $upload_path = $pages->get($get_id->id)->images->path; // Instantiate the class and give it the name of the HTML field $p_images = new WireUpload('images'); // Tell it to only accept 3 file $p_images->setMaxFiles($max_files); // Set Max File Size to 1MB or 2MB => (1024*1024*2) $p_images->setMaxFileSize(1024*1024); // Tell it to rename rather than overwrite existing files $p_images->setOverwrite(false); // have it put the files in their final destination. this should be okay since // The WireUpload class will only create PW compatible filenames $p_images->setDestinationPath($upload_path); // Tell it what extensions to expect $p_images->setValidExtensions(array('jpg', 'jpeg', 'png', 'gif')); // Execute upload and check for errors $files = $p_images->execute(); // Run a count($files) test to make sure there are actually files; if so, proceed; if not, generate getErrors() if(!count($files)) { $err = __("Sorry, but you need to add a Photo File like ( 'jpg', 'jpeg', 'png', 'gif' ) !!! ... Max Size ( 1MB ) !!!"); // ADD SOME SESSION MESSAGE $session->info = "<div class='alert-d'><h1>{$err}</h1></div>"; // TRASH OR DELETE FILE IF NOT EXSIST IMG FILE // $pages->delete($get_id); // Or Only Trash $pages->trash($get_id); // Redirect $session->redirect('./'); } // Check If To Many Files if( count($_FILES['images']['name']) > $max_files ) { $err = __("To Many Images ( MAX 3 Image ) !!! "); // ADD SOME SESSION MESSAGE $session->info = "<div class='alert-d'><h1>{$err}</h1></div>"; // TRASH OR DELETE FILE IF NOT EXSIST IMG FILE // $pages->delete($get_id); // OR Only Trash $pages->trash($get_id); // Redirect $session->redirect('./'); } // turn off output formatting, if it's on $p->of(false); // SET IMAGES VALUE foreach ($files as $file) { // $item .= $upload_path.$file . ','; // SET IMAGES FIELD $p->set("images",$file); } // SAVE IMAGE **************** / $p->save(); // SUCCESS MESSAGE $success = __("Congratulations, you've added Pictures"); // ADD SOME SESSION MESSAGE $session->info = "<div class='succes-m'><h1>{$success}</h1></div>"; // Redirect $session->redirect('./'); }
    3 points
  7. Yeah, slightly strange argument. My argument is if UIKit is the right way to go all together. I'm going to say something crazy, but I think it should be built with little to no dependencies. I feel like these bugs are appearing due to all these dependencies and different systems trying to work together jQuery UI, UIKit both have JS that do the same thing. Some things are using jQuery UI some things are using UIKit. Often there are strange bugs with repeater AJAX like fields having a slightly different design when loaded through AJAX. Like the Page Reference field using AMS for example. Personally, I see the ultimate admin panel is from the ground up, following a guideline with every single tiny element considered. Like how should things collapse when next to another element. But so far I'm loving the UIKit version, it's looking great. Just I think a future goal should be it's own system.
    3 points
  8. Just a quick FYI - you can get Tracy's debug bar when logged out two different ways. If you are on a local dev machine, check the "Force Guest Users into Development Mode on Localhost" option. The other way if you are on a live server is to use the User Switcher to logout. Hope that helps you get data you may want while logged out.
    3 points
  9. Call ProcessWire API Functions Inside STRING Github Repo Current status : BETA Each called method must return string value ! I added all functions, but not tested all. I focused page(), page()->render and field properties (label, description and notes). I also tested some basic pages() api calls. Your API calls must start with { and must end with }. For use multiple arguments inside functions, separate arguments with ~ char. NOTE If you pass directly arguments to api {page(title)}, this call will check for requestedApiCall()->get(arguments). USAGE processString(string, page, language); Get page title <?php $str = "You are here : {page:title}"; echo processString($str); ?> Get page children render result <?php $str = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.<hr>{page:render:children}"; echo processString($str); ?> Get homepage title <?php $str = "You can visit our <a hre='{pages(1):url}'>{pages:get(1):title}</a>"; echo processString($str); ?> Get title field label, description or notes <?php $str = "Our title field properties are : label: {label(title)} - description: {description(title)} - notes: {notes(title)}"; echo processString($str); ?> Multiple examples <?php $str = " <ul class='uk-list uk-list-striped'> <li><b>01: GET FIELD LABEL</b> <code>&#123;label(title)&#125;</code> <b>RESULT :</b> <code>{label(title)}</code></li> <li><b>02: GET FIELD LABEL WITH PREFIX</b> <code>&#123;label(title~=> )&#125;</code> <b>RESULT :</b> <code>{label(title~=> )}</code></li> <li><b>03: GET FIELD LABEL WITH SUFFIX</b> <code>&#123;label(title~~ <=)&#125;</code> <b>RESULT :</b> <code>{label(title~~ <=)}</code></li> <li><b>04: GET FIELD DESCRIPTION</b> <code>&#123;description(title)&#125;</code> <b>RESULT :</b> <code>{description(title)}</code><br> <li><b>05: GET FIELD DESCRIPTION WITH PREFIX</b> <code>&#123;description(title~=> )&#125;</code> <b>RESULT :</b> <code>{description(title~=> )}</code></li> <li><b>06: GET FIELD DESCRIPTION WITH SUFFIX</b> <code>&#123;description(title~~ <=)&#125;</code> <b>RESULT :</b> <code>{description(title~~ <=)}</code></li> <li><b>07: GET FIELD NOTES</b> <code>&#123;notes(title)&#125;</code> <b>RESULT :</b> <code>{notes(title)}</code><br> <li><b>08: GET FIELD NOTES WITH PREFIX</b> <code>&#123;notes(title~=> )&#125;</code> <b>RESULT :</b> <code>{notes(title~=> )}</code></li> <li><b>09: GET FIELD NOTES WITH SUFFIX</b> <code>&#123;notes(title~~ <=)&#125;</code> <b>RESULT :</b> <code>{notes(title~~ <=)}</code></li> <li><b>10: GET PAGE TITLE</b> <code>&#123;page(title)&#125;</code> <b>RESULT :</b> <code>{page(title)}</code></li> <li><b>11: GET PAGE TITLE</b> <code>&#123;page:title&#125;</code> <b>RESULT :</b> <code>{page:title}</code></li> <li><b>12: GET PAGE RENDER TITLE</b> <code>&#123;page:render:title&#125;</code> <b>RESULT :</b> <code>{page:render:title}</code></li> <li><b>12: GET HOMEPAGE TITLE</b> <code>&#123;pages:get(template=home):title&#125;</code> <b>RESULT :</b> <code>{pages:get(template=home):title}</code></li> <li><b>13: GET HOMEPAGE TEMPLATE ID</b> <code>&#123;pages:get(template=home):template:id&#125;</code> <b>RESULT :</b> <code>{pages:get(template=home):template:id}</code></li> </ul> "; echo processString($str); ?>
    2 points
  10. The solution from @abdus works well - you just need to change... $img = $page->randomImages[$page->randomIndex]; ...to... $img = $page->randomImages->eq($page->randomIndex); ...because Pageimages are indexed by basename not integer. This must be the result of some efficiency optimising in Hanna Code. To get around this, just add some attribute to each tag - you don't need to use this attribute anywhere in your tag code. So lets say the attribute is called "seed" (just so it looks kinda legit to the user - this attribute is not actually used to seed anything): [[random_image seed="546458"]] ...some content... [[random_image seed="afdasfd"]] So this attribute's value can be anything so long as it's not the same as another tag on the same page.
    2 points
  11. Thanks! I'm hands-off for the moment so I don't lose anything in the account switch to allow for PHP-FPM. Then I'll take a peek at that module. You guys have saved me hundreds of hours of beating my head against my desk, and probably added a few years back to my life by alleviating stress. I can't thank you enough. With the update to PHP 7 the server is already running far faster. I was able to put back in those feat_icon_imgs that I yanked out yesterday, even! Now it's just a wait to see if there's fallout from the next step, and then I'm in the home stretch!
    2 points
  12. Filecompiler should have taken care of that Add namespace to the first line: <?php namespace ProcessWire;
    2 points
  13. It usually happens to me when there are a lot of errors, or when there's an endless recursion in my code
    2 points
  14. Regarding "33554432 bytes exhausted": 32MB is not too much. Since you are on VPS, you should be able to enable more for your site.
    2 points
  15. Try removing static keyword from method signature, or change _() to __() or $this->_() or prepend _() with backslash \_().
    2 points
  16. Hi @ukyo - thanks for sharing this, but I must admit I am little confused. I am honestly not really sure what you are trying to achieve - no offense intended - I am probably just missing something here Can you please explain how: <?php $str = "You can visit our <a hre='{pages(1):url}'>{pages:get(1):title}</a>"; echo processString($str); ?> is any better than using the API variables in a string like this: <?php $str = "You can visit our <a hre='{$pages(1)->url}'>{$pages->get(1)->title}</a>"; echo $str; ?> BTW, pages(1) and pages->get(1) are the same thing. The other thing you might want to take a look at is the tag compiler: https://processwire.com/blog/posts/processwire-3.0-alpha-2-and-2.6.22-rc1/#new-module-file-compiler-tags which is not really what you are doing, but it's sort of related.
    2 points
  17. Definitely make the switch to PHP 7.0 or 7.1
    2 points
  18. Not tested, but you can store any information inside $page (or any class that extends WireData), and do something like this: <?php // Hanna Code template if (!$page->randomImages) { $page->randomImages = $page->images->findTag('inline-body')->shuffle(); $page->randomIndex = $page->randomImages->count; } if (--$page->randomIndex >= 0) { // as per @Robin S's suggestion: // $img = $page->randomImages[$page->randomIndex]; $img = $page->randomImages->eq($page->randomIndex); echo "<img src='$img->url'/>"; } Keep in mind, this will stop showing images after all images have been used.
    2 points
  19. Hi, "How I could avoid to duplicate data in case 2 (since address details are already found in organizer's page)?" You can create an Address template and assign addresses to both Organizers and Locations via PageReference Fields. I do not really follow your second question. Can you give us a step-by-step example?
    2 points
  20. I'm in the process of learning vue, webpack, etc, and thought this might be a good thing to work on. So I'm building a new generator. At the moment, I'm simply replicating the functionality that already exists, and I have an operational front-end working. As I dive into the back-end, I'll work on the changes mentioned above. Quick question: Currently, selecting Process as the type of module enforces it to extend Process. Should I provide the ability to extend other Process modules?
    2 points
  21. Also, check out the Performance Panel in Tracy to show the time between named breakpoints. https://processwire.com/blog/posts/introducing-tracy-debugger/#performance-panel
    2 points
  22. @tpr's AdminOnSteroids can fix it along with a useful related tweak: https://github.com/rolandtoth/AdminOnSteroids/wiki#filefieldtweaks "Disable filename truncation for File fields: filenames displayed are cut to 20 characters by default. This tweak removes this limitation and shows the full name. If enabled, the delete button is not positioned to the right but right after the filename to avoid display issues when the filename spans to multiple rows."
    2 points
  23. Hmm. looking at your selector, you seem to be using `blog-entries` template for category pages. The exact solution will depend on how you configured your tagging system, but assuming you've used a Page Reference field called `category` limited to categories with `blog-entries` template, then you can use: // inside category template file // $page will point to a page with category template $categorized = $pages->find("template=blog-post, category=$page"); // ^ this will give you all pages with template blog-post whose category field include current page, (current category) // i.e. all posts under current category foreach($categorized as $post) { echo $post->title . '<br>'; } There's a tutorial by @kongondo which covers multiple scenarios and strategies for categorization, it's a must read for beginners.
    1 point
  24. Soma's module is what I normally use to clear cache: https://github.com/somatonic/ClearCacheAdmin It works well.
    1 point
  25. Add this to your .htaccess file # ----------------------------------------------------------------------------------------------- # 12. Access Restrictions: Keep web users out of dirs that begin with a period, # but let services like Lets Encrypt use the webroot authentication method. # ----------------------------------------------------------------------------------------------- RewriteRule "(^|/)\.(?!well-known)" - [F] # Block all requests to WP specific files starting with wp- RewriteRule wp-.*\.php$ - [F]
    1 point
  26. Okay... things are starting to look stable for the moment. Someone with godlike powers is just having a good tug on me today.
    1 point
  27. I recommend showing us the errors to track things down more easily. If you have long error output strings, you might want to use the forum's "spoiler" feature to make your post shorter.
    1 point
  28. I recommend looking into template engines instead, eg. my Latte module uses a similar {$page->field} syntax. There's a lot of additional filters/macros I've made in the last 1-2 years that allows quickly building up a site (getting config strings from a textarea field, generating srcset/breadcrumb/paginator markup, truncate strings/html, add active class, etc). Plus you can use php functions also if you need. But of course other template engines could do the job too. https://github.com/rolandtoth/TemplateLatteReplace/wiki
    1 point
  29. Great to see that you pick up this project. Nice teaser too! I will definitely give it a try.
    1 point
  30. Update: Jquery File Upload Version 0.0.6. Changelog Added support for SVGs (to be recognised as images, etc).
    1 point
  31. @szabesz i disagree about that suggestion. i think it could open more room for bugs and overcomplicate things than it is useful... things are already a little "buggy" when having multiple non-fullwidth fields with showif-dependencies. @ryan it would have been nice to get some feedback about the problems with the forum that occured over the last days:
    1 point
  32. One very easy and effective solution is to use honeypots. Ryan also uses this technique for Formbuilder and has (like me) very good results. Just remember to turn off the autofill option for the input to prevent the browser from filling your hidden field and marking it as spam.
    1 point
  33. Thanks for the efficiency! Come back of my preferred panel! ;-)
    1 point
  34. Thanks @mel47 - can you please test the latest version and let me know how it goes for you?
    1 point
  35. My gut feeling is that the Page Reference fields, repeaters, foreach nesting is not what is causing this slowness. For a listing of only 37 product pages there should not be that much of a delay. (How long is "abysmally slow", by the way?) I'm doing similar things for with page-per-image setups (although with PageTable rather than repeater) with much larger numbers of pages and there isn't a significant impact on speed. And for pages in the ProCache cache there should be no impact whatsoever. So I think you have some other issue going on. Not sure what though, sorry. If you're developing locally, try testing the site on a remote server and see if you experience the same slowness. Or vice-versa if you are developing remotely. Also: start commenting/cutting out blocks of your template code to try and isolate if one area is responsible.
    1 point
  36. I've implemented subscriber list feature for Sendgrid, Mailgun and Sparkpost. One small complication with Sparkpost is that it doesn't really support addition of individual subscribers. It requires posting a complete list of subscribers with each update, which may not be ideal for large lists. For extensibility, I've created a base module and each service extends and overrides methods for creating and handling subscription and list forms, API calls etc, this is because each service has different requirements and parameters for every operation. This is the subscriber list form for Mailgun For SparkPost: and for SendGrid: This is how subscribers lists view look
    1 point
  37. Welcome to the forums @Henner7, The link @abdus gave is actually for bug reports. Feature requests go here: https://github.com/processwire/processwire-requests/issues There is already a request to remove the default truncation: https://github.com/processwire/processwire-requests/issues/83 Besides the solution from BitPoet that you'll find in the feature request, you can disable truncation for all File inputfields by adding a hook in /site/ready.php: $wire->addHookBefore('InputfieldFile::render', function(HookEvent $event) { $inputfield = $event->object; $inputfield->noShortName = true; });
    1 point
  38. https://github.com/processwire/processwire-issues/issues
    1 point
  39. I'm thinking of integrating mailing services like Mailgun, SparkPost, SendGrid (currently working on Mailgun), and their `Mailing List` features via their APIs, because it's much easier to delegate potentially difficult points to a service experienced in this kind of work, instead of using regular SMTP to send emails (not to say I'm discarding SMTP option) Using a mailing service also brings an easier way to add/remove subscribers to a list. With a method like $modules->ProcessMailer->getSubscriptionForm($options), I can return an instance of InputfieldForm, and developers can modify and render it as they see fit. Then I can issue a call to their API and add subscriber to a list.
    1 point
  40. Hi, I don't understand why request info panel is not displaying correctly. If I remove server request and Input cookie, there is nothing in the panel, so I guess it kind of working correctly. Thanks PW 3.0.48 Tracy 4.6.12
    1 point
  41. I've encountered the same problem with many people specifying that any bids for a web site must be Wordpress. I come from a database development background, mostly doing Microsoft Access desktop apps, but also some web development, and even made my own CMS way back when Wordpress was only a dream waiting to happen. I'd describe Processwire as being data driven, whereas Wordpress is content driven. By that I mean that Wordpress revolves around posts and pages, whereas although Processwire calls them Pages, Processwire pages are really totally different beasts to Wordpress pages, and are really a less nerdy name for what are really objects, which can have any properties you like, and may not even be 'pages' in the publishing sense at all. If you want a blog using an existing theme, Wordpress is the way to go. If you want a web site that has to deal with pretty much any data structures you want to throw at it, Processwire is the way to go. Wordpress needs a plugin to do custom field types, and plugins to do lots of other things, and those plugins don't necessarily peacefully coexist or have consistent UIs. With Processwire, you start off bare-bones but can build anything you like quickly and efficiently. The development process for me is far more like building something with Microsoft Access, in that you design you data structures (fields, and I believe with Profields, you can actually do tables, but I haven't had enough work to justify that yet) and then add them to templates which are like forms or reports in Access. Site profiles are a bit like predefined Access templates for specific tasks. Perhaps it would be good to work towards a wider range of free and premium site templates available, but rather than modelling them on Wordpress themes, model them on Access templates, then people will see that Processwire is more of an app platform than just a web site CMS. Processwire can't really have 'themes' in the Wordpress sense, because those rely on assumptions about what data structures you have, whereas with Processwire, a site profile has to define data structures as well as presentation, as Processwire doesn't have any inherent data structures like posts or pages in a Wordpress sense. The reason Access was, and still is so wildly popular amongst a small group of developers is that it is the quickest way to develop a desktop front end for pretty much any kind of database app you might want to build, even if it has some inherent issues that IT departments don't always like. There are a few things I wish Processwire did differently, eg I'd like referential integrity at the database level, and I'd like to be able to use other database systems other than mySQL/MariaDB, (eg PostgreSQL, SQL Server) , but the reality is it's the most efficient tool I've found for quickly defining and presenting any kind of data on the web. With Wordpress, structured data is an afterthought, with Processwire it's core.
    1 point
  42. 1 point
  43. Note: 100% Honesty no Bias I would say it takes much more to develop in WordPress than in Processwire, I will backup my claim with code examples and also various scenarios, before I came into Processwire, I was developing WordPress and really with minimal code , you can do alot in Processwire. Let's look at this now Scenario 1 Fetch Images for a specific Post This is how to do this in WordPress $thumb_ID = get_post_thumbnail_id( $post->ID ); if ( $images = get_posts(array( 'post_parent' => $post->ID, 'post_type' => 'attachment', 'numberposts' => -1, 'orderby' => 'title', 'order' => 'ASC', 'post_mime_type' => 'image', 'exclude' => $thumb_ID, ))) { foreach( $images as $image ) { and this is the equivalent in Processwire foreach($page->images as $image){ } You see the concept in Processwire is that everything is a page, so when you are in a Page, you get the neccessary information required for that page, However WordPress has a "Post Concept" and images are tied to the Media Library which is why you have to supply a post to fetch images. Scenario 2 List all Pages on the Site Now imagine you are looking to create a list of all your pages, this is what you will do in WordPress <?php /*pass your search string here example like this ( 's'=>'test' ) */ $args=array('s'=>'test','order'=> 'DESC', 'posts_per_page'=>get_option('posts_per_page')); $query=new WP_Query($args); if( $query->have_posts()): while( $query->have_posts()): $query->the_post(); { echo $post->post_title; echo $post->post_content; } endwhile; else: endif; ?> Now this is the same result in Processwire $pagesList= $pages->get("/"); foreach($pagesList as $page){ } Minimal PHP Knowledge and beautiful design, I can guarantee you within a week's practice you will be able to deliver something quicker, however some tasks might require additional time, but Processwire has been carefully designed to appeal to people, at a point I wasn't happy when it wasn't adopting Advanced concepts (FIG,PSR) but as I evolved i realized there's more to coding and that user adoption is important. Now let's forget the code let's look at Content management Now you want to create Website and let's assume in your case, it's a website about selling Boats (sorry that's what to mind), Out of the box for WordPress, unless you are creating a custom type, you can't fit that logic into WordPress as it's built around Posts and taxonomy, so you have to create a custom type and this involves codes, or install a plugin, whereas in Processwire you simply create a Page which holds Boat informations and create fields to accept relevant information. This is much more intuitive than WordPress, because in WordPress you might have to add it as a custom field which obviously involves coding again, or as usual checking to see if such a plugin exists, or the last option is to pray that someone builds a theme that involves selling of boats. Now this is the custom field in WordPress, however by default most of the custom fields in WordPress are Text input, during my previous experience creating a custom field other than text involves coding and obviously you know what comes next; installing a plugin again for another need. WordPress takes a lot of time, money and also very nerve wrecking, updating WordPress or the plugin is like russian roulette to me, I have to backup, and pray for the best, It's moments like this that I become very religious. And if something breaks I either have to fix the issue or revert, and sometimes the reason you are updating is because of security issues, so it's either breaking the site or getting hacked. Which means additional money for consultancy and it gets messier from there. I've been there and done that and I simply decided to migrate to another platform as WP wasn't worth my sanity. Processwire is good and the modules built are easy to use and configure, my favourite is the DatabaseBackUp without thinking too much you can easily understand your way around. In conclusion Processwire is good and easy to grasp, it might not be perfect and that's a good thing because it means there's room for improvement, and we are even lucky to have you around, as you can share how we can make Processwire more user centric and easy to use and also features can be created in modules to make PW a more robust system. I will link @Joss article TLDR: Processwire is easy to learn.
    1 point
  44. Websites often provide content not only as on list of stuff, but with some sort of category. The most flexible way in ProcessWire to manage such a categorization are with PageFields. Form example with a structure like this. - Magazine (magazine) - Articles - Article 1 (article) - Article 2 - Article 3 - … - Categories - Category 1 (category) - Category 2 - … Templatenames in parentheses Now all articles have a url structure like: "…/magazine/articles/articlename/" The categories are looking like: "…/magazine/categories/categoryname/" But it can be useful to also provide the articles as part of the categories like this: "…/magazine/categories/categoryname/articlename/" Because ProcessWire doesn't provide such functionality by default, we'll use urlSegments. These have to be enabled in the template-settings for the category template. This template therefore fulfills two different jobs. Displaying a list of containing articles, as well as rendering the articles which are linked by the list. A simple example of a existing category.php could be: <?php // category.php $articles = $pages->find("template=article, category=$page"); // This example uses a deligated template approach. // Feel free to use your own way of templating, // but this is also a simple way to explain this. $content = renderArticleList($articles); include("./_main.php"); Now we need to include the logic to seperate the default rendered article-list to the now added rendering of the called article. <?php // category.php // Throw a 404 Error if more than one segment is provided if($input->urlSegment2) throw new Wire404Exception(); if($input->urlSegment1){ // Show the called article // Sanitize the input for pageNames $name = $sanitizer->pageName($input->urlSegment1); // Search for the article with this name $article = $pages->get("template=article, name=$name"); // Throw an 404 error if no article is found if(!$article->id) throw new Wire404Exception(); // Explicitly set the original url of the article for the <link type="canonical" href=""> tag $article->canonical = $article->url; // Render the page, like if it was normally called. // $page->url will not updated to the "categorized" url for the rendering-part // so you need to have that in mind if you provide some sort of breadcrumb echo $article->render(); }else{ // Show the list of articles of the current category $articles = $pages->find("template=article, category=$page"); // The generateCategoryUrls() function is new, because // $page->url would provide the wrong urls. // Details are provided later $content = renderArticleList( generateCategoryUrls($articles, $page) ); include("./_main.php"); } Now if we call this "…/magazine/categories/categoryname/articlename/" we'll get the right article rendered out instead of the article-list. Now we need to talk about the article-list, which would - without changes - still render the "wrong" urls to all those articles. Therefore I added the generateCategoryUrls() function. This function iterates over the pageArray and adds a second url to all those articles. <?php // part of _func.php function generateCategoryUrls($list, $category){ foreach($list as $item){ $item->categoryUrl = $category->url.$item->name."/"; } return $list; } The last thing missing is the actual template which gets rendered by renderArticleList(). This would normally call for $article->url to get the url to the article. We want this to render our second url if we are on a category site. To let the template still be useable by non category sites, we just change the parts, where to url is used form the current $article->url to $article->get("categoryUrl|url"). Only if the additional urls are provided they get rendered or it falls back to the normal urls of the articles. There we go, with such a setup all categorized articles are reachable via both urls. A small addition to explain the $article->canonical I used in the category.php. For SEO it's not good to provide the same content on multiple pages without explicitly declaring which of the duplicated ones should be the original / indexed one. By providing the following link tag we provide this declaration. The extra field I use isn't really necessary, because $page->url still is the standart ProcessWire url of the shown article. But I like this to be visibile in the code, that this is a dublicate. <link rel="canonical" href="<?php echo $page->get("canonical|url") ?>"/> Hope you like the explanation. Feel free to give feedback on this. Based on the example shown in the wiki: http://wiki.processwire.com/index.php/URL_Segments_in_category_tree_example
    1 point
  45. So I created a little python script. https://gist.github.com/anonymous/10001724 create a new file and give it execute permissions chmod +x ./pw You can fetch the lastest PW code from git an start a new project. ./pw <new-project-name> Also if you want a specific version ./pw <new-project-name> dev 2.4.0 Will create a new folder with your project name if you need help ./pw help Tested in my Linux machine.
    1 point
  46. Yes, works like a charm. But also I discovered 2 issues. 1.- the csv have not \n line endings. 2.- the sql export have all the sessions. that was the main reason it was a very huge sql file (near 12 megas) after the truncate only was 140 kb. wow. Thanks folks!
    1 point
  47. so I gave up and use a command line script like this http://processwire.com/talk/topic/18-how-do-i-import-lots-of-data-into-pages/?hl=%2Bskyscrapers+%2Bsite
    1 point
  48. Widgets like they are in WordPress are an entirely different animal than they would be in something like PW. In WordPress, you aren't dealing with anything-goes templates and instead you are dealing with themes. The theme follows an expected format an typically has an area built to contain widgets, among other things. Drupal is the same with blocks. These CMSs are markup generation engines because it's assumed that the various elements (widgets, blocks, modules, plugins) are generating their own markup. In these CMSs you are typically designing the theme for the CMS, rather than having the CMS accommodate your design. You are styling the output of someone else's markup. There are plusses and minuses to this approach. A plus is that you can make assumptions about things like widgets. Another plus is that you can make a lot happen without development (like dragging widgets in WordPress). A minus is that you are locked in by the needs of the theme and you have far less flexibility and control over your output. PW is a very different tool from WP and Drupal. PW's approach is to provide you with the tools to get to your data easily, and let you decide what you want to do with it in terms of output. With a few exceptions, it isn't going to generate the markup for you, and that's the point. I personally dislike working with tools that generate the markup for me because it always feels like I'm cleaning up someone else's mess rather than creating my own. Most Designer/Developers prefer to create their own markup because it lets you use your skills to accomplish whatever you want to. ExpressionEngine is another tool that operates on this same principle. Given the above, I prefer to keep PW out of markup generation at it's core. Meaning, I wouldn't ever want widgets/blocks to be a required element of the software, or part of it's base architecture (like WP or Drupal). But I also think that this is a great use of plugin modules, as well as your own development processes. The methods described by Antti and Adam are great ways to make widgets part of your site. And as was described earlier, you can turn any Page into a widget simply by rendering it (and you'd want to make sure your page's template is producing the appropriate output): echo $pages->get("/widgets/latest-news-list/")->render(); Still, something like the above really isn't much different than this (with less overhead too): include("./widgets/latest-news-list.php"); That's how you might make your own widgets. But I like the approach of using modules for widgets too, as they are easier to share for people that want them. I wouldn't ever want to start including built-in widgets in the core since that would be directing how you should build your site. But I'm not opposed to at least supporting it in the core for modules. So if you guys think it makes sense to add a base Widget module class in the core (like the Pyro example) that's good with me. In fact, we already do to an extent so I'm not sure it would be much more than this: abstract class Widget extends ModuleJS { abstract public function render(); } Still, good to have a known starting point even if not much to it. The way you would call it would be the same way you already do for other modules: echo $modules->get("MyWidget")->render(); or maybe something simpler: echo $widgets->MyWidget->render(); Almonk is this along the lines of what you were thinking, or something different?
    1 point
×
×
  • Create New...