Leaderboard
Popular Content
Showing content with the highest reputation on 02/13/2013 in all areas
-
Soma, once we've got 2.3 as the current stable version out there, I'll go through the cheatsheet and figure out what needs to be added, etc.2 points
-
You can detect whether the current page was loaded from ajax by checking the value of $config->ajax from your template file: <?php if($config->ajax) { // page was requested from ajax } Following that, you will likely want to render the page differently to accommodate whatever you are doing from the javascript side. For instance, you might want do one of these: 1. Deliver alternate or reduced markup when loaded from ajax 2. Deliver a JSON or XML string for parsing from javascript Below are examples of each of these scenarios. 1. Deliver alternate or reduced markup when loaded from ajax You might find checking for ajax helpful when you want portions of pages to load in your site without re-rendering the entire page for each request. As a simple example, we'll use the default ProcessWire site and make it repopulate it's #bodycopy area when you click a page in the top navigation. (To use this example, you'll need the default ProcessWire site templates, though you can easily adapt the example to another situation.) To accomplish this, we'll update our main page template to only include the header and footer markup if the page is NOT being loaded from ajax: /site/templates/page.php <?php if(!$config->ajax) include("./head.inc"); echo $page->body; if(!$config->ajax) include("./foot.inc"); Next we'll update the top navigation to do ajax loads of the pages when the client has javascript (and leave as-is when they don't). Paste this javascript snippet before the closing </head> tag in the header markup file: /site/templates/head.inc: <script type="text/javascript"> $(document).ready(function() { $("#topnav a").click(function() { $("#topnav a.on").removeClass('on'); // unhighlight selected nav item... $(this).addClass('on'); // ...and highlight new nav item $("#bodycopy").html("<p>Loading...</p>"); $.get($(this).attr('href'), function(data) { $("#bodycopy").html(data); }); return false; }); }); </script> Now when you click on any page in the top navigation, it pops into the bodycopy area without a page load visible from your browser. And all pages remain accessible from their URL as well. Note that this is just a test scenario, and I probably wouldn't use this approach for the entire bodycopy area on a production site (it would make bookmarking difficult). But this approach can be very useful in the right places. 2. Deliver a JSON or XML string for parsing from javascript Lets say that you want pages in your site to return a JSON string with the page's id, title, and number of children when it is requested from ajax. When not requested from ajax, they will return their content as normal. To handle the ajax requests, you'd want to add something like this at the top of your template file before any other output. <?php if($config->ajax) { // this is an ajax request, return basic page information in a JSON string $json = array( 'id' => $page->id, 'title' => $page->title, 'numChildren' => $page->numChildren ); echo json_encode($json); return; } // not ajax, continue with regular page output And here is some markup and inline javascript you might use to test the ajax call on some other page (or the same one if you prefer). You would paste this snippet right in your site's markup where you want that info to appear. <ul id='info'></ul> <script type='text/javascript'> var url = '/'; // this is homepage, so replace '/' with page URL you want to load JSON from $(document).ready(function() { $.getJSON(url, function(data) { $.each(data, function(key, value) { $("#info").append("<li>" + key + ": " + value + "</li>"); }); }); }); </script> The above snippet would output something like this: • id: 1 • title: Home • numChildren: 5 To take this example further, you could build an ajax-driven sitemap or any number of web services. Conclusion Hope this helps you to see how simple it is to use ProcessWire to deliver output for ajax. These are just contrived examples, but hopefully examples that might lead to more ideas. In addition, much of what you see in these examples is also applicable to building web services in ProcessWire.1 point
-
(Note: Module name temporary and will change) As recently mentioned here I am recently working on a little module. This module gives you a new admin page under "Setup" to create pages in a "batch" mode. What does it do - You can select a parent page where you want to create your pages. Then it will give you a list of templates you can chose from. Those should be permission and template setting aware. Also only parents that really can have children will work, else it will give an alert. - Add as many pages you like by clicking "+add Page". You can set the pages published or hidden status. Sort or remove the pages. - After you entered a template and at least a title you'll be able to klick "create Pages". If successful it will append the list of pages you just created with an open in page tree or edit link, and also the parent. - You can add pages and repeat the process to add pages to the pages you created simply by changing the parent page in the field above the table and go on. It's all ajax and not page load. Also the links of the created pages that get appended below will stay in the document and only the form entries get cleared. This is still work in progress, but I thought enough to share and if you like you can try/test/use it. Download: ProcessTools.zip Screen:1 point
-
Greetings Everyone, Literally... I have been having code dreams lately. In the dreams, I get some new idea and I work out the logic. Then I actually see -- and hear -- the code. Of course, it always seems so brilliant in the dream! Anyone else have this kind of experience? Off to bed, Matthew1 point
-
Oh, I should add a couple of other bits! If you set your image file so it can only have one image, then you can treat it as a single result as I just did above. However, if you set it for more than one image (or any number by leaving it set at 0) then it will produce an array. So you will need to treat it as such and either loop through the images or just grab the first: Read this post by Ryan (or God, as we know him) http://processwire.com/talk/topic/81-images/1 point
-
Hi and welcome! $page->col1Image->url Is what you are after. That will come complete with the path. And you are welcome to keep asking questions here without feeling daft - every body does and everybody tries to answer them too! Joss1 point
-
This should all be sorted now and, although you won't spot any cosmetic changes, some of those bugs people were encountering should be gone as well (fingers crossed!).1 point
-
http://processwire.com/api/cheatsheet/#page 5th entry in that list. $page->url is something so basic and covered all over the place on processwire.com. It's all under API, as it's the only thing you need to know to build templates/pages http://processwire.com/api/what/ http://processwire.com/api/templates/ http://processwire.com/api/variables/page/ http://processwire.com/tutorials/quick-start/navigation/ Or of course http://wiki.processwire.com/index.php/Main_Page. If not, there's even a basic site when you install PW which also is something you want to study first when starting with PW and come ask question if you don't understand something here. I think that's quite good and there's many people think PW has exceptional documentation for a OS project. For some strange reason we still have to figure out why some people think the opposite. There's also the forum which has tons of examples (might use google search to search) and simple questions get answered here mostly immediately.1 point
-
It can be better explained with this: result = ifonething==something ? iftrue : iffalse;1 point
-
My code example would be if you have the categories as the navigation/page structure to display the products assigned to them. $page would be the category page and categories is the page field used to select the category on the products. So in simple this find find all products that have the current category page selected. I'm on category page: Boys Nightware show me all products that have Boys Nightware selected. The question you have to ask is do I need multiple categories or not.1 point
-
1 point
-
Hi arjen, the parent page will have the "has_children_class" and if it's the actual parent it will have the "parent_class", too. So it can be styled with CSS through: li.parent.has_children { color: #fff }1 point
-
hi Ryan you can add also the transliteration of greek language if you want it. there is also a drupal transliteration module with (i think) all languages, i do not know if this can help you http://drupal.org/project/transliteration thanks. 'α' => 'a', 'ά' => 'a', 'αι' => 'ai', 'αί' => 'ai', 'αϊ' => 'aï', 'αυ' => 'ay', 'αύ' => 'ay', 'β' => 'v', 'γ' => 'g', 'γγ' => 'gg', 'γκ' => 'gk', 'γχ' => 'gch', 'δ' => 'd', 'ε' => 'e', 'έ' => 'e', 'ει' => 'ei', 'εί' => 'ei', 'έι' => 'ei', 'ευ' => 'ef', 'εϊ' => 'eï', 'ζ' => 'z', 'η' => 'i', 'ή' => 'i', 'θ' => 'th', 'ι' => 'i', 'ί' => 'i', 'κ' => 'k', 'λ' => 'l', 'μ' => 'm', 'μπ' => 'mp', 'ν' => 'n', 'ντ' => 'nt', 'ξ' => 'x', 'ο' => 'o', 'ό' => 'o', 'οι' => 'oi', 'οϊ' => 'oi', 'οί' => 'oi', 'ου' => 'oy', 'οϋ' => 'oy', 'ού' => 'oy', 'π' => 'p', 'ρ' => 'r', 'σ' => 's', 'ς' => 's', 'τ' => 't', 'υ' => 'y', 'ύ' => 'y', 'φ' => 'f', 'χ' => 'ch', 'ψ' => 'ps', 'ω' => 'o', 'ώ' => 'o',1 point
-
Yep I get a lot of errors though. My dreams appear to be missing a debugger. Working on it.1 point
-
On the principle that I have just been doing a template for a site that has 12,000 categories (!), the way I would do this is to list categories as pages under the menu but then create products separately, probably listed under a hidden parent called "products" or something nice! Then create a page field for your product template called "category" and set it to only list pages that have the "category" template. Now, when you create a product you can link it to one of your category pages - at any level. In theory this means that each category can have both products and sub-categories. Now, with your category template file, you need to do two things: 1. Check to see whether there are any children to the page (and if so, list them) 2. Check to see if there are any product pages where their "category" page field = the current page. And if so, list them. Design wise, you could put products in the main area and shove sub-categories (children) in the side bar or something sweet like that. You could also add another grouping called Manufacturers (create those under a hidden page as with the products) And throw those into the mix too. I suggest a large piece of paper and a pencil! Joss1 point
-
Assuming I understand the need correctly, what I usually do add this to the <head> section of the main markup include: <head> <!-- all your typical <head> stuff --> <?php $file = "styles/$page->template.css"; if(is_file($config->paths->templates . $file)) { echo "<link rel='stylesheet' type='text/css' href='{$config->urls->templates}$file' />"; } $file = "scripts/$page->template.js"; if(is_file($config->paths->templates . $file)) { echo "<script src='{$config->urls->templates}$file'></script>"; } ?> </head> Using this method, if you have a template named 'product', then it could have dedicated CSS and JS files in /site/templates/styles/product.css and /site/templates/scripts/product.js, when you need it. The nice thing about this is that it's just a system rather than hard coded file. If you determine you need something unique for the CSS (or JS) on pages using some template, the you can just create the CSS (or JS) file and have it start working automatically. You can take this further too. For instance, you could use the same technique with page IDs to assign custom CSS/JS files to specific pages.1 point
-
1 point
-
WillyC's example actually works. Returns the 10 last updated files. But the shell commands it executes are pretty unix specific (though am guessing there is an equivalent in Windows). We might be able to just add a timestamp field to the file-based fieldtypes too. I kind of hate to duplicate info like that, but the reality is that disk space is cheap and making them queryable from the PW API would be nice.1 point
-
Maybe a useful addition: $sanitizer->entities() Cheers Btw the cheatsheet is the best API overview/explanation ever seen! Thanks for making this.1 point
-
$num = 10; // u.tell it how.manys file ob_start(); $path = rtrim(wire('config')->paths->files, '/'); passthru("find $path -type f -exec stat -f '%m %N %m' {} \; | sort -n | tail -$num | cut -f2- -d' '"); $data = explode("\n", trim(ob_get_contents())); ob_end_clean(); foreach($data as $line) { list($file, $ts) = explode(' ', $line); echo date('Y-m-d H:i:s', $ts) . " - $file<br />"; }1 point
-
You could accomplish the above in various ways. I'll cover two: Option 1: Structure -people --john ---organization 1, ceo, 2010-2012 ---organization 2, board member, 2009-current --mike --etc. The above would have child pages of each person that represents their organization connections. The fields on that template would be: organization (single page select to /organizations/) position or title (text, their position at the organization) start_year (integer) end_year (integer) Option 2: Repeater This is the option I would use, and it's perfect for this sort of thing. It's basically doing the same thing as option 1, but making it simpler and disconnecting it from the structure. You'd create a new field using ProcessWire's repeater fieldtype, perhaps naming it 'organizations' or 'person_organizations'. Then add the same fields mentioned in the bulleted list above. Add this new 'person_organizations' field to your 'person' template. Now you can define as much meta information for that person<->organization relationship as you want to. More on how to use ProcessWire's Repeater fieldtype1 point
-
I found Lemonstand is a bit easier to understand from a templating point of view, but with any of these systems it's bewildering as Joss says - especially compared to the E-commerce module Antti has made where you build your site as normal with the visitor in mind and then simply add one field to a page to make it a product. I know that's a shorter version of how it actually works, but it is MUCH easier and you're focusing on getting it right rather than wasting time on learning another system and wrapping your head around yet another templating system.1 point
-
why u.use add.whens you no take result u.try this? $u = wire('users')->add('testuser1'); $u->pass = 'test123'; $u->addRole('superuser'); $u->save(); or.this $u = new User(); $u->name = 'testuser1'; $u->pass = 'test123'; $u->save();1 point
-
Antti has been developing a Shop module for ProcessWire and it is in successful use already. I'm not sure how many other users might be using it, but I think he's done a very nice job with this. However we don't have plans for e-commerce to be part of ProcessWire's core product, at least not in the current roadmap. So any e-commerce solutions for ProcessWire will be 3rd party solutions, whether running on ProcessWire or on an external service. I've developed and run an online store for many years and have quite a bit of experience with several self-hosted e-commerce software products, and more recently, hosted e-commerce products. When a client asks me what to do for e-commerce, I like to point them towards services like Shopify (my favorite), Volusion, BigCommerce, etc. These services are targeted specifically towards the needs of e-commerce in a way that no self hosted product can touch (at least for what matters to me and my clients). Plus they are hookable (at least Shopify is) making it easy to perform actions in your PW site based on an order, in real time. Paid membership sites suddenly become a piece of cake. This makes nearly anything possible, and IMO more powerful even than dedicated products like Magento. Now with PCI compliance (at least in the US) I really dislike the hassle and time expense of self hosted solutions for my own needs. I don't think ProcessWire needs to be all things to all people, and I'd rather focus our energy on the things where we are and can be better than everyone else. For the same reason, I don't want us to invest time in creating forum software when something like IP.Board exists. We want to empower web developers with the best solutions out there. This is a much bigger question for proprietary and non-open source products. It's a good question, but doesn't have the same gravity when applied towards an open source product with hundreds (or thousands) of people around the world familiar with the system and code. At least in our case, when a bug turns up, many times the user submits a fix with the bug. Beyond these forums, I also do some support email. But very little comes to me anymore. The forums and community here have been better than I could have ever imagined. I should also note that a goal for 2013 is to provide commercial support options for those that want it. I'm not yet certain if the market is there for it, but it's something I would like to have available. We are on a path for growth and I see us continuing our current strategy of building and improving the software and resources around it. My 5-year goal has been for us to power 3% of the PHP open source CMS-driven sites in the world and/or be top 10 (open source) in terms of usage. I think that our growth comes from WordPress users looking for more, and front-end developers getting into content management without a previous allegiance. We'll also get our users from other CMSs. But WordPress is the one building the audience, and the developer and non-blog-portion of that audience is using the wrong software. With that audience, ProcessWire answers everything that WordPress can't, while being simpler to use and develop for. There are other CMSs that are also good stepping stones, but all are significantly more complex.1 point
-
You can't use any operator except '=' when querying path or url from the database (like when using $pages->find). This is because the path doesn't actually exist in the database, so there's nothing to perform comparisons on. It is generated at runtime based on a page combining its name with the names of its parents. It worked with '=' because we pulled a few tricks to convert a path into a big left join statement, in an attempt to match it. And this actually works very well. But it doesn't translate quite as well to other operators. I should have had the engine throw an exception when you used an operator it didn't support for that. Instead it just switched it to an '='. So I've updated it so that it now throws an exception instead. I've also added a new module to the core, called PagePaths. When you grab the latest dev branch, do a 'check for new modules' and you should see it. Once you install that, it goes and sets up a table with all the page paths and a means of querying them. This enables you to use any operator when querying path or url, including all the partial text matching ones like %=, *=, ~=, ^=, $=. As a side effect, this module also brings potential performance improvements to other queries, as it eliminates the need for the left join trick I mentioned above. (Though in my initial tests, it doesn't seem to be a measurable improvement). I will probably have this module installed by default for new installations of 2.3. But won't have it auto-install to existing installations. That's because it has to generate an index of all pages in your site--a potentially resource consuming process. For instance, Antti's 100k page site probably won't work with this, as it's no small task to go and build an index for 100k pages after the fact. But if you aren't running a massive site already, this module is one you probably want on most sites, so I went ahead and included it in the core.1 point