Jump to content

ryan

Administrators
  • Posts

    16,715
  • Joined

  • Last visited

  • Days Won

    1,517

Everything posted by ryan

  1. It's not clear to me whether you are intending to get 'FieldtypeModules' (as your code says) or 'FieldtypeTemplates' (as your text says), but I don't think that either is what you want. Though you are probably getting the error because those are 3rd party modules that aren't installed by default. If your module needed a 3rd party module installed, then you'd want to have it called out in the 'requires' section of your getModuleInfo() function. But don't think about that much now, because FieldtypeModules/FieldtypeTemplates is not what you want here. Fieldtypes are only applicable to handling data with pages. In this case, you are building a collection of Inputfields to hold your module's configuration data. So what I think you are wanting is something like this: if(!isset($data['mailChimpTemplates'])) $data['mailChimpTemplates'] = array(); // default value $field = $modules->get('InputfieldAsmSelect'); // or InputfieldCheckboxes? $field->name = 'mailChimpTemplates'; $field->label = 'Select what templates to use'; foreach(wire('templates') as $template) { $field->addOption($template->id, $template->name); } $field->value = $data['mailChimpTemplates']; $inputfields->add($field); During your module's regular execution, when you want to access your mailChipTemplates variable, you'll just want to remember that it is holding template IDs rather than template objects. If you wanted to make it hold template objects instead, you could put this in your init() function: $templates = $this->mailChimpTemplates; foreach($templates as $key => $id) { $templates[$key] = wire('templates')->get($id); } $this->mailChimpTemplates = $templates;
  2. Thanks for testing guys. I merged all the dev stuff into the master branch yesterday and it's now 2.2.5
  3. Based on what I'm understanding from your last message, I think you should skip keeping the separate table. It just sounds like extra, unnecessary work, unless there's something more to this project that I don't yet understand. Instead, I think you should have your cron job execute a script that bootstraps ProcessWire and takes care of all the adding, updating and deleting of records consistent with the web service you are reading from. This is something that I think ProcessWire is particularly good at, because it's been designed for this from the beginning (it's something I have to do with a lot of my client work). Whether XML or JSON doesn't matter much, as PHP includes the ability to read from either type quite easily. Though like the other guys here, I generally prefer JSON just because it's less verbose and less fuss. If JSON, you'll pull the feed and use PHP's json_decode() to convert it to an array. If XML, you'll use PHP's SimpleXML to convert it to an array. Once you've got the array of raw data, you'll iterate through it and add, update, or delete pages in ProcessWire to make it consistent with the data you are pulling from the web service. Live, working example I think that the best way to demonstrate it is with a live, working example. This one uses the existing modules.processwire.com/export-json/ feed. You might also want to see the feed in human-readable mode to get a better look at the format. Below is a shell script that bootstraps ProcessWire, reads from that feed and maintains a mini "modules directory" site, on your own site. I made this feed so that it can be tested and used on a brand new installation using the basic profile (included with PW). If left how it is, it'll create a mini modules directory site below the '/about/what/' page and use the template 'basic-page' for any pages it adds. But you can run this on any ProcessWire installation by just editing the script and changing the parent from '/about/what/' to something else, and changing the template from 'basic-page' to something else, if necessary. This script assumes that the template used has 3 fields: title, body, and summary. The 'basic-page' template in PW's default profile already has these. If you adapt this for your own use, you'd probably want to change it to use more specific fields consistent with what you need to store on your pages. In this example, I'm just building a 'body' field with some combined data in it, but that's just to minimize the amount of setup necessary for you or others to test this… The purpose is that this is something you can easily run in the default profile without adding any new templates, fields, pages, etc. 1. Paste the following script into the file import-json.php (or download the attachment below). For testing purposes, just put it in the same directory where you have ProcessWire installed. (If you place it elsewhere, update the include("./index.php"); line at the top to load ProcessWire's index.php file). 2. Edit the import-json.php file and update the first line: "#!/usr/bin/php", to point to where you have PHP installed (if not /usr/bin/php). Save. 3. Make the file executable as a shell script: chmod +x ./import-json.php 4. Run the file at the command line by typing "./import-json.php" and hit enter. It should create about 95 or so pages under /about/what/. Take a look at them. Run it again, and you'll find it reports no changes. Try making some changes to the text on 1 or 2 of the pages it added and run it again, it should update them. Try deleting some of it's pages, and it should add them back. Try adding some pages below /about/what/ on your own, run it again, and it should delete them. import-json.php #!/usr/bin/php <?php // replace the path in the shabang line above with the path to your PHP // bootstrap ProcessWire. Update the path in the include if this script is not in the same dir include("./index.php"); // if you want to run this as a PW page/template instead, remove everything above (except the PHP tag) // save our start time, so we can find which pages should be removed $started = time(); // keep track of how many changes we've made so we can report at the end $numChanged = 0; $numAdded = 0; $numTrashed = 0; // URL to our web service data $url = 'http://modules.processwire.com/export-json/?apikey=pw223&limit=100'; // get the data and decode it to an array $data = json_decode(file_get_contents($url), true); // if we couldn't load the data, then abort if(!$data || $data['status'] != 'success') throw new WireException("Can't load data from $url"); // the parent page of our items: /about/what/ is a page from the basic profile // update this to be whatever parent you want it to populate... $parent = wire('pages')->get('/about/what/'); if(!$parent->id) throw new WireException("Parent page does not exist"); // iterate each item in the feed and create or update pages with the data foreach($data['items'] as $item) { // see if we already have this item $page = $parent->child("name=$item[name]"); // if we don't have this item already then create it if(!$page->id) { $page = new Page(); $page->parent = $parent; $page->template = 'basic-page'; // template new pages should use $page->name = $item['name']; echo "\nAdding new page: $item[name]"; $numAdded++; } // now populate our page fields from data in the feed $page->of(false); // ensure output formatting is off $page->title = $item['title']; $page->summary = $item['summary']; // To keep it simple, we'll just populate our $page->body field with some combined // data from the feed. Outside of this example context, you'd probably want to // populate separate fields that you'd created on the page's template. $body = "<h2>$item[summary]</h2>"; $body .= "<p>Version: $item[module_version]</p>"; foreach($item['categories'] as $category) $body .= "<p>Category: $category[title]</p>"; $body .= "<p><a href='$item[download_url]'>Download</a> / <a href='$item[url]'>More Details</a></p>"; $page->body = $body; // print what changed $changes = $page->getChanges(); if(count($changes)) { $numChanged++; foreach($changes as $change) echo "\nUpdated '$change' on page: $page->name"; } // save the page $page->save(); } // now find pages that were not updated above, which indicates they // weren't in the feed and should probably be trashed $expired = $parent->children("modified<$started"); foreach($expired as $page) { echo "\nTrashing expired page: $page->name"; $page->trash(); // move to trash $numTrashed++; } echo "\n\n$numAdded page(s) were added"; echo "\n$numChanged page(s) were changed"; echo "\n$numTrashed page(s) were trashed\n"; import-json.php.txt Running the script as a cron job: You can instruct your cron job to run the script and it should be ready to go. You may want to move it to a non web accessible location for more permanent use. You'll also want to update your bootstrap "include()" line at the top to have the full path to your ProcessWire index.php file, as your cron job probably isn't executing it from the web root dir like you were manually. Running the script as a template file: You can run this script as a template file on a page by removing the include() line and everything above it with this line: <pre><?php Place it in your /site/templates/ directory, add the template from PW admin, and create a page that uses it, then view it.
  4. When you get a chance, and when you feel its ready, it'd be great to get it posted in the modules directory too: http://modules.processwire.com/add/
  5. How much SEO value to photos have anyway? I would think the SEO value would come from the descriptions of those photos, not the photos themselves. So by alternate links and/or sitemap, I was thinking something like this: <li><a href='/path/to/photo.jpg'>Description of photo</a></li> or <li><a href='/path/to/page/photo-jpg'>Description of photo</a></li> In the second example, 'photo-jpg' would be a URL segment and it would instruct the page's template to just display the 1 photo having that name, and with description (in alt tag and/or in the content area).
  6. This sounds like a fun project! Does the data need to stay in this external table, or can it live in ProcessWire instead? If the data can live in ProcessWire, your cron job could very easily update the data by just bootstrapping ProcessWire. Bootstrapping is as simple as: include("/path/to/pw/index.php"); One-time importing data from an external source is also very easy to do via the API. So if you can do it, I would just let the data live in ProcessWire instead of an external database, and it'll make the whole job a piece of cake. But if that data needs to stay external, then Sinnut's solution is a good way to go. You would use the DB's primary key (or some other unique column) to serve as the urlSegment that loads the page. You'd setup one page/template to handle all that data, and it would find it like this: $key = (int) $input->urlSegment1; if(!$key) throw new Wire404Exception(); $result = $yourDB->query("SELECT make, model, year FROM your_table WHERE id=$key"); if(!$item->num_rows) throw new Wire404Exception(); list($make, $model, $year) = $result->fetch_row(); echo "<ul>"; echo "<li>Make: $make</li>"; echo "<li>Model: $model</li>"; echo "<li>Year: $year</li>"; echo "</ul>"; Note: enable URL segments on the template where this code is (on the URLs tab), as URL segments are not enabled by default. This is another reason why it may make a lot of sense to keep all the data in ProcessWire. But if you can't do that, it won't be a problem: all you need is for your pages to contain a reference to the primary key of row they map to in your external table. I would suggest using the built-in "name" field for those pages to map to the primary key in your external table, because you know it'll be unique and relevant. But you could always create a separate integer or text field in ProcessWire do handle it too. But lets say you use 'name', then your page templates could load the data like this: $result = $yourDB->query("SELECT make, model,year FROM your_table WHERE id='{$page->name}'");
  7. That's correct, if you want to find pages by a field called cats, then you'd use "cats=" instead of "id=". To find pages matching all the categories, specify multiple "cats=" statements (rather than 1 split by "|" OR bars). So the code example you posted is correct.
  8. Nested repeaters may be technically possible, but the potential overhead would be huge and it seems like all sorts of possible complications could arise. So definitely not recommended. You are right that I should remove the capability to do it--I've just made this change and will be committed shortly.
  9. You might want to look at using a repeater for this, as it would enable you to do this pretty easily. Though cloning and modifying the existing images fieldtype would enable you to do all this too (with a little more work).
  10. Thanks Geniestreiche! Nice site you've put together there. Thanks for posting and welcome to the forums!
  11. Thanks Biotech, I have fixed this now and it's in the current source. Turns out it only does that in Firefox, but the fix was easy (CSS: clear: both;)
  12. Good find, I have updated it to be 7 characters. (we didn't use to have a character limit when this was originally written)
  13. Are you talking about copying/cloning an entire page? If so, install the ProcessPageClone module, which is included with the core (just click install from the Modules screen. But if you are talking about cutting/copying a block of text and putting it somewhere else, then of course nothing can beat your browser's built-in copy/paste.
  14. There are so many great ways to present photos that it'd be hard to narrow it down. Soma linked to a really cool one recently, but now I can't seem to find that link. Most of these solutions use jQuery/Javascript to take a semantic (SEO friendly) list of images and convert them to some kind of interesting presentation. Given that your client doesn't like thumbnails, I'm thinking you are probably looking at some sort of image slider. There are lots of these out there, but this one (Zurb Orbit) is the one I've already got open so figured I'd link it. You (or your selected gallery script) will probably want to use javascript to assist in the loading of images, so that you need not load them all in the initial request. This is where you start running into search engines not being able to see them. But so long as you are providing an alternate path by linking to them or linking to page(s) containing them, that's what you need. If necessary, you can use your JS initialization to hide those links once your JS takes over responsibility of presentation for them. But disable JS in your browser to test your alternate paths and make sure you can still get to all the images one way or another. It also doesn't hurt to get a site map in the mix.
  15. The other good thing about MailChimp is that they are very pro-PHP and they use it for everything.
  16. What are the settings on that page reference field? Usually when you've got a timeout, there is some circular reference. For example, a repeater referencing a category page that in turn somehow references back to the original page. Or a page reference in a repeater that references back to the parent page or repeater items. ProcessWire detects and prevents most of this, but the question becomes more complex when a repeater is involved. What were the last edits you made before the timeout started occurring? I don't think it's an issue of quantity, I really think there must be some kind of circular reference in there, especially given that a Page reference in the repeater. You may be able to track it down by editing the repeater pages directly: Page List > Admin > Repeaters > drill down to it from there.
  17. Looking good Arjen! I've not used MailChimp so can't get too deep into it since I don't have the platform to run it, but a quick look at the code and it seems like you are on the right path. Actually I probably should use Mailchimp since they are just a few miles from my house, and they gave me a nice t-shirt. Having some nice PW integration makes it very enticing! I think that you had it right the first time with $this->config->urls->NewsletterMailChimpSync (rather than paths, which represent server disc paths, not relevant to stylesheet links). However, if you add parent::init(); to your init() function, and name your CSS file (or JS file) the same as your module name, then ProcessWire will load them for you automatically--this is the preferred way to do it.
  18. For safety, good to sanitize the categories before putting them in the selector too: $selector = "id="; foreach($input->post->categorylist as $value) { $selector .= ((int) $value) . '|'; } $pages->find(rtrim($selector, '|'));
  19. Can you describe more about the repeater? Maybe a screenshot of what it looks like and/or what fields are in it. Does the front-end of your site iterate these repeater items?
  20. I agree, I do this sometimes too (or something like it)
  21. Thanks for the follow-up, glad that you were able to find a fix for this. That rewrite rule you came across is just one to keep everything closed off in /site-default/, since that holds pre-installation files and generally doesn't exist after the site has been installed.
  22. I'm not sure that I understand the question 100%, but am thinking you might be thinking of "hidden" as a type of field (like it would be in HTML), as opposed to a status that any field can have. In ProcessWire, setting the visibility to hidden can be done with any field and it's not related to the field type. That field will still be present in all of your API usage… it just won't be rendered in the page editor. So it's great for fields that you want to store things in from the API side, while excluding it from the interactive side.
  23. This module installs a page on your Setup menu in the admin where you can manage comments (assuming you have a comments field installed). Download from the modules directory at: http://modules.processwire.com/modules/process-latest-comments/ Features include: Easily find the latest comments needing approval or moderation. Shows comments from all pages on 1 screen, paginated and in chronological order. Enables you to change the status of any comment, edit the text or delete. Filtering by status/type, cite, email or IP address Screenshot: I've been wanting to build this for a long time, and something like this should have been there from the beginning, as it's a bit tedious to keep track of all your comments on a large site without this. So this module may be moved into the core for version 2.3, in which case it'll be renamed to ProcessComments, so as not to conflict with those that may have this installed.
  24. Soma is correct that you can set the "visibility" to "hidden" in the field settings, and then the field can exist on the page but won't appear in the page editor.
  25. Which module did you try to install? Do the errors persist even after restoring the default admin theme? What admin theme did the errors occur in? I'm not sure I've got enough understanding of the problem to know what solution to offer, so the more you can post about it the better (screenshots of the error messages might even help). But since you mentioned an issue that started as the result of installing a module, you've got me curious about what module could do this. One thing you might try is to go to the Admin > Modules and click "Check for new modules" as that will reset the cached module information. If you can't access that screen, let me know and I can tell you how to do it manually too.
×
×
  • Create New...