Jump to content

SteveB

Members
  • Posts

    214
  • Joined

  • Last visited

Everything posted by SteveB

  1. Kongodo summed it up well. I would suggest gathering your data from the outside world into conventional database table(s) outside of PW. Set them up so they are easy for you to fill and check over. Then write a module based on Ryan Cramer's module for importing from CSV files. Make it read from your table(s) instead of a file. You can put all your code for massaging the content right in the module. With liberal use of the UI modules have for settings you can use the same tool to make various kinds of pages from input data. Working with an external database can be pretty simple: protected function externalDbConnect(){ $this->extDb = new mysqli('localhost', 'xxxx', 'yyyy', 'zzzz'); } protected function queryCount($qry){ $result = $this->extDb->query($qry); return $result->num_rows; } protected function queryForFields($table){ $a = array(); $result = $this->extDb->query('SHOW COLUMNS FROM '.$table); while($row = $result->fetch_array(MYSQLI_ASSOC)) $a[] = $row['Field']; return $a; }
  2. I get validation errors from w3.orgs's HTML5 Conformance Checker when I build forms with the API. If I put more than one form on a page it complains because the id "_post_token" is repeated Also, hidden fields are not supposed to have labels. "The for attribute of the label element must refer to a form control." Theseare minor complaints and there are of course ways to repair the markup but perhaps these could be added to a To Do list. Thanks,
  3. Make a page and a template. Put the ajax handling code in the template file and post the data to the page's URL. You can use page fields to store settings if you need any or your code.
  4. That will be handy. A year or so ago I did an API interface using PayPal to send payments to people. Don't imagine it comes up very often but if anybody wants to do that let me know.
  5. Yes, that would be great. FYI, the first thing I had done was to simply modify ___execute() so I could pass it a page id and it would return the $data array of revisions. Then I wrote the snapshot function. Then I got the idea to hook it to pages. A couple more thoughts... Normally the revision data will be limited by data_max_age or data_row_limit settings. If you give the snapshot method a timestamp older than the oldest revision data you get current Page data and don't know whether that's really what the page was like at the specified time or not. The simple change below helps but doesn't tell you the difference between a Page which never changed and a Page with changes that are no longer in the database. public function pagesnapshot($event) { $page = $event->data['object']; if ($data = $this->snapshot($page, $event->arguments(0))) foreach($data as $k=>$v) $page->$k = $v; else return false; //ADDED THIS } Is there a simple way to have the snapshot capability automatically hooked into pages which have tracked fields? I'm wondering if the VersionControlForTextFields gather method could set that up. I noticed after I deleted a page that the version info for it did not go away. If data_max_age hasn't been set it won't age out and get cleaned up.
  6. I've been experimenting with an addition to VersionControlForTextFields. Let's say we have a Page with some revision data. $soup = wire('pages')->get('/specials/soup/'); echo "<br/>Current soup: " . $soup->title; //Doing this gives Page a new method wire('modules')->get('ProcessRevisionHistoryForTextFields'); //What kind of soup were we serving last week? $soup->snapshot('-1 week'); echo "<br/>Old soup: " . $soup->title; After the call to snapshot() any version controlled fields of the Page will have the values they had at the time specified. The changes to make this work are made to the ProcessRevisionHistoryForTextFields.module file. Add one line to the init() public function init() { parent::init(); $this->addHook('Page::snapshot', $this, 'pagesnapshot'); //add this line } Add these: public function pagesnapshot($event) { $page = $event->data['object']; if ($data = $this->snapshot($page, $event->arguments(0))) foreach($data as $k=>$v) $page->$k = $v; } public function snapshot($page, $time='') { $id = $page->id; if (!$id) throw new WireException("Missing required param id"); if (!is_integer($time)) $time = strtotime($time); if (empty($time)) $time = time(); // how many of this page's fields do we keep history for? (configured for each template) $ct = count($page->template->versionControlFields); // find values $sql = " SELECT m.fields_id, m.pages_id, d.* FROM " . self::TABLE_NAME . " AS m, " . self::DATA_TABLE_NAME . " AS d WHERE m.pages_id = $id AND d." . self::TABLE_NAME . "_id = m.id AND m.timestamp <= FROM_UNIXTIME($time) ORDER BY m.timestamp DESC "; $result = $this->db->query($sql); // generate data (associative array) $data = array(); if ($result->num_rows) { while ($row = mysqli_fetch_assoc($result)) { $field = $this->fields->get($row['fields_id']); if (!array_key_exists($field->name, $data)) $data[$field->name] = $row['data']; if (count($data) >= $ct) break; } } return $data; }
  7. Pete, the standard template cache and markup cache are pretty easy to figure out and modify. I ended up writing a module with a caching mechanism similar to template cache (stores markup by page number in a subfolder of /sites/assets/cache/). That module does other things too but my point is that in template files for a site like you describe, this lets you prepare dynamic and cachable chunks of markup separately. The majority of the page content would be cached and the template file only has to make the dynamic part and combine the two. Usually, it's the top of the page that's dynamic (user status, links for logout, profile, etc.) and the rest is appended to that. If you also want to use AJAX this method gives you a chance to insert Javascript for that as you put together the page. The little bit of work that doesn't get cached tends to be very simple/fast.
  8. I agree that payment should be handled offsite by a service (for security etc) and that if a third party system matches up well with what the client wants it makes sense to use it. Often clients have very idiosyncratic ideas about shipping and discounts or are otherwise unsatisfied by off the shelf solutions. What's worked for me in the past is to have my own very flexible catalog, shopping cart and checkout system, usually with with import/export processes on either end (products in, orders out). Then my hands aren't tied by a third party system who's mission is more about doing what most people want. ProcessWire is well suited to an approach like that where the overall architecture is in place but the level of detail can be dialed up or down for a particular project.
  9. I've done shopping sites and there is endless variety and obsession over ways of doing discounts, taxes, additional charges, pre-orders, etc. Recoding my shopping cart logic in a way that makes sense for ProcessWire is a lot to think about in terms of how best to utilize PW, what's handled as a page, etc. My approach leans towards flexibility rather than simple/easy so it may not appeal to everybody. I'll post something when my thoughts are more settled. Would like to hear people's requirements.
  10. What a coincidence that this thread turns up now. I've just finished a system for managing users and was wondering how best to share it. It consists of five template files, one stylesheet and a slightly modified InputfieldPassword module (I changed the validation and some text). You setup a page for each template, all of them children of a hidden /access/ page. The various forms are made with InputfieldForm. Each template sets $page->body and then includes a basic-page.php template file, like we see in many of the processwire profiles. /access/login/ /access/profile/ (for changing your password, username or email address) /access/logout/ /access/register/ (for creating a new user account) /access/reset/ (for when you've forgotten your password) Each user acount must have a unique username. An email address is collected for each user but does not need to be unique (it's okay for someone to have more than one account). When setting an email address we verify it by emailing a message to that address. Confirm by clicking a link or pasting a code into a form (an 'email-confirmed' role is added). Requests to reset a forgotten password are verified by emailing a message to the account's email address. Confirm by clicking a link or pasting a code into a form. To close the registration process set the /access/register/ page status to Hidden. For my own purposes, this is a convenient parts kit I can quickly add to a project. Seems like the easiest way to share it is as a profile. I suppose I could bundle up the files and create a module which installs everything for you but doesn't that seem just a bit overdone? Any suggestions? Good points were made above about coding standards, translatable text strings, etc. I'd have to do some work on that. I value the multi-language capabilities in PW but hardly ever need them in my work so if the community insisted on it being standard would that encourage me to get over my aversion to the syntactic baggage it requires or would it discourage me from sharing? For modules the Proof of Concept category works pretty well. It's nice to share unfinished work. Often the author's intent is easier to grasp in these less filled out implementations. Often there will never be a final version because every project is different. Framework add-ons can actually suffer from too much completeness. Do you want to transplant a seedling or a mature plant? Perhaps coding standards for modules could be expressed as a checklist and implemented as tags in the Modules section of this site. Likewise for profiles and any other kind of package we may come up with. Thanks to the many generous and thoughtful coders here.
  11. Made some changes to the demo files (CSS, template, readme) having to do with an unfortunate iOS7 discovery. Apple in their way has decided that we must not be allowed to affect volume via Javascript. I've not found a cure. The demo template and CSS are now set to omit audio controls if the user agent string looks like something from an iOS7 device. "On iOS devices, the audio level is always under the user’s physical control. The volume property is not settable in JavaScript." This is unfortunate for web based kiosk applications where you can't expect users to know how to find the iOS volume control and you don't want them using the physical buttons. Any suggestions?
  12. I just put this on GitHub. It's still a little raw. Tell me if anything should be tweaked before submitting it to the module list. The AudioMP3jplayer module uses FieldtypeFilePlusData. You need both. I have look into setting that up as a dependency. https://github.com/sb3d Nov. 26: There are now some demo files in the AudioMP3jplayer repo. You get a template file, an image showing PW's Edit Template screen for the template, a stylesheet for the player. With that and a little imagination you can probably make it work. If you grabbed copy yesterday, check again because I also made a small fix to AudioMP3jplayer module.
  13. Sneak preview and invitation to request feature-creep This module helps you put MP3-Players in your pages. Based on: Audio_MP3 module by Christoph Thelen Like Chris's module this one sets up an 'audio' field and generates markup for a player. Using: getID3() by James Heinrich, getid3.org jPlayer Plugin for jQuery JavaScript Library, jplayer.org FieldtypeFilePlusData module (new) Uses jPlayer Gets by nicely with just mp3 files on lots of browsers. Module methods generate the player markup and javascript to setup the track list and activate the controls. Pretty easy to manage appearance through CSS. I'm finding that the same markup works fine for single and multi track applications. Extracts ID3 info Gets track info ('artist', 'album', 'title', 'genre', 'publisher', 'year') Extracted images (minus dupes) are added to page's image field Caches ID3 info The 'audio' field uses FieldtypeFilePlusData which provides json encode/decode and storage. Module automatically populates this when files are added. ProcesssWire clears it when they get deleted. Finishing up: There are hardly any configurable options at this point. I don't think it needs much but there are a few things. Requests? Comments?
  14. True but not the same thing. Static files are not the answer either. I want to bring a laptop (web server) and an ipad (browser) to a meeting and make it work. No "network" other than those two devices. It's supposed to be possible by setting up an "adhoc" network but seems very hit or miss. Hard to search for advice as 99% people writing about connecting an ipad via wifi are trying to share an internet connection (WAN). The iPhone I'm testing with sort of connects. It puts a checkmark next to the connection and on the laptop I see words like "identifying" but in the end the iPhone complains that "(network name) is not connected to the internet." Connecting to the internet is not my goal. I only need it to browse pages hosted on the laptop. So I suspect the problem is not about the establishing the communications link but more about what what the devices think the connection is for. Perhaps somebody has proper terminology for this? Sorry for this tedious digression. May have to trot down to the Apple store and see if they know. EDIT: Apparently the old spare router I was using for this test was the problem. If I use my normal LAN it works fine just using the default connection settings, nothing tricky. There's no hosts file to edit on these iOS devices and I'm not running a local DNS so I have to use the IP as the web address and setup Apache config accordingly. Should be fine.
  15. Anybody happen to know how I can use an iPad to browse a site hosted on my laptop (a Win7 PC with LAMP stack and wifi)? I'd like to be able to go to a meeting and show people a site on the iPad and on the laptop without depending on availability of an internet connection. All self contained. I have a iPhone here to test with but couldn't get anything working. Tried adding (on laptop) an ad-hoc network with no security. The iPhone sees it and apparently connects (check mark is shown) but then what? Putting laptop's ipaddress into safari (that's what a 2nd PC on the LAN would do) doesn't work. Thanks.
  16. Diogo's right of course, there's already front end stuff in the admin but it's fairly conservative. Separation of duties between the core admin and a more frontend focused fancy tool could allow the core admin to be even less dependent on third party tools, the ebb and flow of UI trends, etc. I'm not taking a Luddite stance, I'm just thinking that anything so cutting edge as to be like Felix said, "applying all possible developing and design good practices" will forever be in Beta but we'll always need a stable, solid, easy to support and troubleshoot admin tool. These are two different requirement sets. Felix, it sounds great and I don't have anything against the tools. I brought up the observation about PW leaving frontend out of the framework (which we both like) to support my reasoning which goes something like... Admin pages with state of the art bells and whistles have lots of frontend. Frontend is not baked into PW, for good reason. Therefore this new cutting edge admin thing should not replace the standard PW admin system we depend on. Having it separate would take some feature creep pressure off of Ryan. Standard admin could be as "pure" and failure proof as possible. By separating these two admin interfaces they are each freed from having to meet criteria which pull in opposite directions. (fixed a typo)
  17. Felix, thanks for taking the time. Tools, devices and standards are such a moving target that it's easy to fall into analysis paralysis. One of my favorite things about PW is that it doesn't assume you will use a particular frontend solution so I'd say the "perfect frontend for the backend" is one which can be replaced. For being able to work at a wide range of scale and withstand changes in the web environment simplicity often wins out. If we throw enough problem solving tools at a problem don't we create a new problem? Will Bower, for example, be your favorite front-end package manager six months or a year from now? Will it be a pain to change it out? I think Ryan's been smart to leave frontend up to the developer and to strive for admin pages that support anything you can come up with in PW, even if that means less then optimal user friendliness. Yes, I'd love to have slicker admin tools. That would make my work more pleasant and with some tuning and configuring could be great for clients to use. If we're going in that direction perhaps the goal should be to have PW core stick to having a spartan (I mean that in a good way) but robust and scalable admin interface, which supports but does not require the modernized, design-oriented, slick, next-generation, fun to use thing we all seem to want. Contributed modules and themes extend the present PW admin and I think we should retain that option but perhaps what Felix and others are getting at is a third thing. Not the public face of a site and not the nuts-and-bolts technician's access panel, but something with aspects of both. A third thing, which depends heavily on frontend which in PW is an application specific developer decision, not something baked into the framework. That's a strength of PW. The admin pages are an exception but let's not drag too much decor into that toolbox. How about doing this third thing as regular pages hidden and protected by roles and permissions? Sealed with a KeepItSimpleStupid.
  18. Adam, I agree about View. It just doesn't seem right for one of those tabs to be a link instead of another tool. Your killer page tree is great. I'd tighten up the vertical spacing a bit but to each his own.
  19. I don't quite get what's going on with Pure's css/js yet and was lazily looking for an example. Want to generate the navigation with the module but have it styled as a Pure menu. .............................................................................................................................................................. EDIT: It's a pretty active project and examples on the site are somewhat out of date, mentioning an otherwise unexplained Y.menu plugin I found this: Short answer: Yes. The Y.Menu source code lives here: https://github.com/smugmug/yui-gallery/tree/master/src/sm-menu Long answer: I recommend holding out on this until 0.4.0, because we are significantly refactoring menu for that release Along with refactoring the CSS, we're going to make the JS a lot simpler so that it just toggles classnames. We also plan on having documentation on the site, showing examples of how to use vanilla JS, jQuery, or YUI with the menu. When we do this, we'll also highlight the class names that need to be toggled to achieve specific effects. Here's a pull request with the new Menu CSS, but I'm still working on the dropdown stuff.
  20. Has anybody here figured out using this with Pure?
  21. Thanks Adiran. I hadn't thought about the clone module but that could work if I'm careful not to make a new clone unless something has changed. I could make a hash and append that to the clone's name. Groups have a PageArray of people so I'd have to make sure that clones of the people exist and then update the group clone's PageArray to point to them. Might actually work.
  22. I'm simplifying but imagine a site about people and groups. Every person and every group is a Page. We plan to do this for a long time and periodically update the people and groups. I'd like to be able to store a "snapshot" of a group, including the people in it, and be able to look at that at a later date. I could iterate through the properties of the group and the person pages associated with it and apply some variation on this page to array technique to store current values in a datastructure of some kind to be archived in a table or file. I think it's a reasonable simplification to assume the templates for these pages will not change. Later I'd like to reconstitue the XYZ group as it was on it's 10th anniversary when we stored a snapshot. In order to be able to display it using the same tools I use to display current info, I'll iterate through the archived data structure and create Pages, then render the reconstituted group page. Assuming many of these people are still current on the site we might also show links to their current selves or show comparisons. In the not too distant future we might have a built in capacity for versioning of Pages but for now I could certainly save changeable field data externally. I'm just not sure how to best manage the brief life cycle of these temporarily reconstituted pages. They have to coexist with the current data, but not clash (names, ids). They have to be deleted when we're done with them. Can we make a bunch of Pages on the fly, render them and never, actually have anything about them stored in the database? Anybody done anything like this? FYI, somewhat relevant thread: http://processwire.com/talk/topic/4420-page-list-migrator/ Thanks
  23. Get yourself a free account at SendGrid and use some of their PHP code
  24. It's easy to make a module just for the purpose of holding settings and that way you get a nice user interface for them in the admin area. Good clues in the wiki: http://wiki.processwire.com/index.php/Module_Creation#Example_of_a_configurable_module $settings = $modules->get("MySettings"); echo $settings->greeting;
  25. Earlier today I was thinking of a use/case situation where I might use parenting or page fields to tie together some related pages. The better approach was page fields and really the only reason I was even trying to make it work with parenting is that it would be easier to explain to a client how to set it up. This is a case where a client-oriented admin interface could make it easy to select the related pages and declare the relationship but hide the actual details of how that relationship is expressed in PW. In my pre-PW work I've done a lot of custom admin pages for clients to use. It really pays to keep these very focused on application-specific work flow, terminology, etc. I don't expect clients to accept the level of abstraction necessary to work directly with the PW data. The admin pages provided by core should be a tech tool, guaranteed to be scalable and capable of accessing anything any application might have. Sure, there's room for improvement but what about putting that effort into easing the task of constructing a more focused and mediated admin interface for clients to use. I haven't looked deeply at how the admin pages work now but given the modular way things tend to be done in PW I'd think we could do something to streamline the building of custom admin pages. Sort of an admin construction kit. Let the client deal with "skyscrapers" and "cities" rather than "pages" even though underneath, they are all PW pages. Reuse the basic underlying CRUD while adding application specific prompting and tools to help the user with the more focused task of working on a city, skyscraper, category, etc. Build a custom interface where clients can do their routine tasks easily. if they end up with an odbball situation beyond the scope of what you built for them you can always talk them through using the standard admin interface, and if that becomes a habit you extend their custom interface. Personally, I don't think a single admin interface is ever going to be optimal for both programmer and client. Those are different audiences with different needs. I'd be wary of anything that compromises the ability of the standard admin pages to deal with huge amounts of data etc.
×
×
  • Create New...