Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 06/06/2014 in all areas

  1. This module adds a preview and zoom button to InputfieldTextarea for live previewing the content after being formatted by the text formatters assigned to that specific field. It's pretty alpha still but it already works. For now I was only playing with the Parsedown formatter, but it should work with every other formatter as well, even with Hanna Code, not sure though, haven't tested it. It's restricted to regular textareas, meaning TinyMCE et al are not supported yet, because they need specific change listeners. Will look into it though. The result is fetched via ajax from a process page, the default style sheet contains some Github-like styles but the style sheet is configurable, see module settings. Github: https://github.com/owzim/ProcessTextareaPreview Open for suggestions
    8 points
  2. Hi John. ProcessWire will be able to handle all of that rather well This is how I would think about doing it... Students and users If you want some projects to only be accessible to students, then certainly add students as users. You can extend the "user" system template with additional fields for your extra data. Create a new role "student" to add to these users and to control permissions. User title (For full name) name (permanent ProcessWire field - use this for student ID, perhaps?) programme (FieldtypePage, for programme of study) year (FieldtypePage or FieldtypeInteger) Projects title body (FieldtypeTextarea) images (FieldtypeImage. For images only) files (FieldtypeFile. For video or audio) students (FieldtypePage. Allow multiple. Use a custom selector value: template=user, roles=student) programme (same FieldtypePage as above) Each project would have their own page under a parent "Projects" page. For the Programme of Study, presumably this is just a simple lookup/dropdown list? A common way of doing this in ProcessWire is to create a settings or configuration template (with minimal fields - usually just title) and (hidden) page tree. E.g. /settings/programmes/ |-- Programme 1 |-- Programme 2 |-- ... You can then create a Page field which will use something like template=settings, parent=/settings/programmes/ to allow selection of the programmes of study for both users and projects. This makes it incredibly easy to generate a front-end filter for the programmes and build a page query selector string to find projects that belong to the programme of study. Depending on the way you want to format or structure your year of study you could use the same process. But if it's just going to be the year in numeric format (like 2014) then you could just use an Integer type rather than a Page. With that structure, there shouldn't be any performance issues.
    5 points
  3. The echo should be in "..." not '...'
    3 points
  4. I've been using DuckDuckGo(the search engine that doesn't track you) for a while now and they recently released a redesigned and much improved Version. I have to say it looks great. duckduckgo.com Also Apple is making DuckDuckGo a part of Safari in the next versions of Mac OS and iOS as private search option. Does anyone think that DuckDuckGo can actually take a chunk out of Google? I would love to see them succeed.
    2 points
  5. I think we are not really done yet. You mentioned that those fields are page fields? Well if the values all are page fields, this means you know the all the values ahead. There's simple ways to get the distinct count using this reference. After all it's like a field relation from one page to another and PW can use that in selectors to find pages matching a page in selected in a page field. But this can be done in different ways and direction depending on what you need this can make a big difference. Loop all values for a page field and filter then count pages that matches (maybe not ideal in your case), or loop all pages and collect and count the values of fields, kinda what we were doing above. And others. On the last one if you are using page fields, you somehow only need to know the ID of the page selected to be able to count (got it?), but its value(!) is, as we know it is a selected page (Page object), so you also need to know the field that makes the value, the one you usually output. This is usually the title, but can be also any other field on that selected pages. After all you could even have your fields array, you define previous to loop them through, specify the field name for the "value" this field is using as value. Uff, does this still make sense? I'm not sure how your setup is and how you'll go about to define what fields, so again just an example code. Assuming your page fields are all single value selects (they'd have to be for this to make sense). $somePages = $pages->find("template=child-templates, somefield=somevalue"); $fieldsArray = ("province" => "title", "network" => "count"); // "fieldname" => "fieldname_onselectedpage" $result = array(); foreach($fieldsArray as $field => $subfield){ foreach($somePages as $p) { if(isset($result[$field][$p->$field->$subfield])) $result[$field][$p->$field->$subfield]++; else $result[$field][$p->$field->$subfield] = 1; } } So $p->$field->$subfield would translate to $p->province->title $p->network->count Which is the selected page's "title" or for the network field "count" (maybe an integer field). Looping through all values of a field in your case, since those are pages would mean to maybe also loop values that are not used at all in those pages. So maybe not always desired depending on the pro and cons, and maybe also amount of pages you deal with. I think in this case just try and see what happens, there should be no very noticeable slowdown if you run this code until let's say 10 fields over 500 pages or 2-3 fields over 1000 pages. Hard to say out of the blue. If there's a lot more that need to be looped, I think you would need to consider some other direct sql queries ($db->query("SQLSTATEMENT"), $database->query("PDOSTATEMENT") On a sidenote I find it more and more very hard to commuicate such "complex" thing just for the terminology of all the things, like pages, selected pages, fields when having to deal with page arrays and page fields. I never know if the other person understands the same. Anyway.
    2 points
  6. This is great, just updated to the 2.4.3 dev version and it all seems to work fine now. Logging in with a test user account i can now add new users without any problem. And, as expected, i can not choose the superuser role, nor i can edit (and view) any accounts with superuser roles.
    2 points
  7. Raymond, have you set the proper rights on the user template as well for the editor/manager role?
    2 points
  8. Sorry I was a bit late to give you the details on benchmarking. Got busy with different stuffs. Here is the code that ran on around 701407 `some-page` and `different-page` of `1158` pages. There is more types of pages, so probably the total of pages will be more. <?php require dirname(__DIR__) . '/index.php'; $pages = wire('pages'); $t = Debug::timer(); $items = $pages->find("template=some-page, limit=1, get_total=count"); $total = $items->getTotal(); echo "<p>Found $total some-pages in " . Debug::timer($t) . " seconds using count</p>" . PHP_EOL; wire('pages')->uncacheAll(); // calculate total using calc method (default) $t = Debug::timer(); $items = $pages->find("template=some-page, limit=1, get_total=calc"); $total = $items->getTotal(); echo "<p>Found $total some-pages in " . Debug::timer($t) . " seconds using calc</p>" . PHP_EOL; wire('pages')->uncacheAll(); $t = Debug::timer(); $total = $pages->count("template=some-page"); echo "<p>Found $total some-pages using count() in " . Debug::timer($t) . " seconds using count</p>" . PHP_EOL; wire('pages')->uncacheAll(); $t = Debug::timer(); $items = $pages->find("template=different-page, limit=1, get_total=count"); $total = $items->getTotal(); echo "<p>Found $total different-pages in " . Debug::timer($t) . " seconds using count</p>" . PHP_EOL; wire('pages')->uncacheAll(); // calculate total using calc method (default) $t = Debug::timer(); $items = $pages->find("template=different-page, limit=1, get_total=calc"); $total = $items->getTotal(); echo "<p>Found $total different-pages in " . Debug::timer($t) . " seconds using calc</p>" . PHP_EOL; wire('pages')->uncacheAll(); $t = Debug::timer(); $total = $pages->count("template=different-page"); echo "<p>Found $total different-page count() in " . Debug::timer($t) . " seconds using count</p>" . PHP_EOL; wire('pages')->uncacheAll(); $t = Debug::timer(); $first = $pages->get("template=some-page, sort=-some-page_created"); echo "<p>Found {$first->title} in " . Debug::timer($t) . " seconds</p>" . PHP_EOL; wire('pages')->uncacheAll(); $t = Debug::timer(); $first = $pages->get("template=some-page, sort=-some-page_created, get_total=0"); echo "<p>Found {$first->title} with get_total=0 in " . Debug::timer($t) . " seconds</p>" . PHP_EOL; wire('pages')->uncacheAll(); Result <p>Found 701407 some-page in 2.4525 seconds using count</p> <p>Found 701407 some-page in 2.7801 seconds using calc</p> <p>Found 701407 some-page using count() in 2.6784 seconds using count</p> <p>Found 1158 different-page in 0.0328 seconds using count</p> <p>Found 1158 different-page in 0.0166 seconds using calc</p> <p>Found 1158 source count() in 0.0028 seconds using count</p> <p>Found some title in 3.5964 seconds</p> <p>Found some title with get_total=0 in 0.0188 seconds</p> Indeed the last one has shown a tremendous improvement when kept `get_total=0` . Thank you
    2 points
  9. Flavy, I wouldn't worry too much about quantity of queries. Instead, focus on the end results and how fast it performs. Quantity of queries means very little as you can have a 100 well optimized and/or simple queries that execute faster than a single complex one. So counting queries is more than often a waste of time, and trying to combine queries can even slow things down. The way that ProcessWire works is that it loads data on demand, as it is requested, using simple and well optimized and indexed queries that are very fast. That is, unless you check the box for "autojoin" in your field advanced settings. When checked, it will join that field's data with the original page query. For instance, we have the "title" field set to autojoin by default, since this is one field that is most likely to be accessed on any given page object. However, whether or not autojoin speeds up anything is debatable, so I would use it sparingly. It has potential to speed things up in some cases, but at the cost of memory, and cost of loading data unnecessarily. As a result, we only recommend it for fields that will always be accessed on every instance of a page. Beyond the obvious "title", examples might include a date or summary field used when outputting lists throughout a site. For the most part, I don't use the autojoin option at all anymore except for "title" fields because there is rarely a measurable benefit, but there is always a measurable drawback (loading stuff in memory that may or may not be used). You might also want to look at the "Cache" Fieldtype, which is included in the core. It's something that people rarely use, but it is directly applicable to your question. It caches all of your fields for a given page (or at least those you select) into one. It's more often used to combine several text fields together for searching purposes, but it can also be used to keep all your page data together in one chunk (and correspondingly, 1 query). Again, it may or may not result in faster performance in the end, but it's another tool worth knowing about and worth experimenting with. Other tools I recommend considering are MarkupCache (core module) and Template cache (a feature in any template settings). Or for the best performance, we also have ProCache, which makes your site perform as quickly as static HTML files. Most PW sites don't need much in the way of caching, but if you find you need it or want it, you've got some great options here. I agree with Antti that 100 fields will not be a problem. Many of us here regularly deal with more than that. But it also is good to think of fields as a finite resource and something that you want to conserve. While there is no technical limit on quantity of fields that you can have, it's possible for overhead to increase as the number of fields do. This isn't about page loading per se, but about overall system overhead and memory required to manage lots of fields at once. The ProFields package is specifically aimed at reducing the quantity of fields necessary to accommodate a site's data needs. Depending on what those needs are, it has the potential to drastically reduce the number of fields in your system. As a result, I think it makes a lot of sense for the needs you are talking about. You should also look into PageTable (on the dev branch) as a better option to repeaters.
    2 points
  10. If articles is your news listing page and a child of your home, why don't you just do: echo "<p>Return to: <a href='/articles/'>articles.</a></p>"; (Note: As Soma mentioned, whatch your use of quotes) It is shorter, no less customizable and uses the page tree structure. The API way of getting a url of a page is great for instance within a foreach loop where you are listing out the results from a query, but is not needed for a straight link. The API allows you to do things that are not straightforward; it is not intended as a replacement for ordinary actions.
    2 points
  11. Introducing ProcessWire ProFields: Table – it lets you literally define your own Fieldtype! This is one of the most exciting ProFields and it's something very different than any other Fieldtypes. I think it is best described by this screencast (be sure your sound is on): Special thanks to Joss for his great voiceover on this screencast. Please view the video at 720p and full screen if possible. Read more about the Table Field Table is part of the ProcessWire ProFields package now available for purchase in the ProcessWire store.
    1 point
  12. What does autojoin do? Using the 'autojoin' optimization can increase performance on fields that get used a lot. Not using it can reduce the page's memory footprint. What is more desirable in each instance depends on your situation. What sites should use autojoin? Autojoin is most applicable with larger sites. On smaller sites, there may be no benefit to using it or not using it. But it's good to know what it's for regardless. Where do you control autojoin? Autojoin is controlled per-field. You can turn it on by editing each field under Setup > Fields > [your field], and you'll see it under the 'Advanced' heading. When should you use autojoin? Autojoin causes the field's data to be loaded automatically with the page, whether you use it or not. This is an optimization for fields that you know will be used most of the time. Fields having their data loaded with the page can increase performance because ProcessWire grabs that data in the same query that it grabs the Page. Autojoin is a benefit for fields that are always used with the Page. This is best explained by an example. Lets say that you have a template for individual news stories called news_story. The news_story template has these fields: title date summary body sidebar We'll assume that when you view a page using the news_story template, all of the fields above are displayed. Fields that should have autojoin ON: Now consider a separate news_index template that displays ALL of the news stories together and links to them. But it only displays these fields from each news story: title* date summary In this case, the 3 fields above would be good to autojoin since they are used on both the news_index and news_story templates. If your title, date and summary fields didn't have autojoin turned on, then ProcessWire wouldn't go retrieve the value from the database until you asked for it it (via $page->summary, for example). Because the news_index template displays all the stories at once, and always uses the title, date and summary fields, it will perform better with title, date and summary having autojoin ON than with it OFF. In this case, it reduces the query load of the news_index template by 3 for each news story. To take that further, if it were displaying 20 news stories, that would mean 60 fewer queries, which could be significant. Fields that should have autojoin OFF: Now lets consider the body and sidebar fields, which are only used on the news_story template: body sidebar It would be desirable to leave autojoin OFF on those fields because there is no reason for the body and sidebar to be taking up space in memory when they are never used on the news_index template. While it might mean 2 fewer queries to view a news story, that is not significant and certainly not a worthwhile tradeoff for the increased memory footprint on the news_index template. Keeping autojoin OFF reduces a page's memory footprint. Conclusion Using the 'autojoin' optimization can increase performance on fields that get used a lot. Not using it can reduce the page's memory footprint. What is more desirable in each instance depends on your situation. But if your situation doesn't involve lots of pages or data, then you don't need to consider autojoin at all (and can generally just leave it off). Additional Notes Not all fields have autojoin capability. You won't see the option listed on fields that don't have the capability. *The title field has autojoin on by default, so you don't need to consider that one. It was included in the examples above because I thought it's omission might cause more confusion than it's inclusion. Be careful with multi-value fields that offer autojoin capability (page references and images, for example). Because MySQL limits the combined length of multiple values returned from a group in 1 query, autojoin will fail on multi-value fields that contain lots of values (combined length exceeding 1024 characters). If you experience strange behavior from a multi-value field that has autojoin ON, turn it OFF. If you want to play it safe, then don't use autojoin on multi-value fields like page references and images.
    1 point
  13. Very useful module, just got a chance to play around with this module on the project I am working on
    1 point
  14. Thanks for all your help. After uninstalling and reinstalling it all worked well. Plus, I've uploaded the rest of the videos and the previously mentioned error didn't show. Awesome looking video gallery thanks to this module.
    1 point
  15. Thanks Soma I had a look in the /site/modules directory and removed the newly installed module. After that, the site started functioning again properly. I have a suspicion this is something to do with something that Adrian mentioned. He said that when i downloaded the module from git hub it added -master to the module name. When i used the autoupgrade service for the module it installed it without this suffix on. I didn't know about the debug mode so thanks. I'll move this topic back to the module forum for further advice on how to upgrade the module. Thanks
    1 point
  16. davo, I agree with Soma that we should continue this conversation back in the module thread.
    1 point
  17. ProcessGetVideoThumbs - it looks like this module is the cause and should be in the thread title. Maybe first enable debug mode in site/config.php and look what error it throws, or ask the ProcessGetVideoThumbs module thread.
    1 point
  18. ID is ok, but hard coded somewhere in the code isn't that good. Because you display code for the public and at least you should comment that for users that are not familiar with PW or module code (starters?).
    1 point
  19. The module is not limited to markdown/parsedown, you can use any formatter. I just used it as an example. Markdown: http://daringfireball.net/projects/markdown/ Parsedown: http://parsedown.org/ Parsedown formatter: https://processwire.com/talk/topic/6576-module-textformatterparsedown/
    1 point
  20. It also depends if output formatting for the pages is on or off. If it's OFF a $page->field may be an object or array but when ON the same might be a string or a single object instead of an array. Good luck.
    1 point
  21. A lot of things have been simplified in the latest dev. You no longer need to set any user template permissions at all. Simply giving the role "Administer Users" permission is enough. Here is Ryan's explanation:
    1 point
  22. There's a little more to it. A seperate cron launches every minute, checks for auctions that are close (within 5 minutes) of closing, and launches this script in the background for each one. while(true) allows this script to poll the PW page for last minute bids, etc. and when the auction closes it breaks the loop, emails the winner, etc. and exits. So this script isn't actually a cron, it's launched by a cron to watch a specific page for a while, then exits.
    1 point
  23. hi Martijn - i'm pretty sure the value is not stored; i ran a quick selector and the field is showing as empty...
    1 point
  24. This should be fixed in the latest dev: https://github.com/ryancramerdesign/ProcessWire/issues/493
    1 point
  25. Since the introduction of "Show in the add-page shortcut menu?" i'm disabling this feature for almost every template. And sometimes I forget to disable it, so I have to go back to the template settings to solve it. For one site I even disabled the button with display: none; (hacky hacky) It's starts to annoy me more then I would benefit from it. I thinks it's better to invert this behaviour, defaulting to No.
    1 point
  26. We talked about this in the office, just letting know i agree with Martijn. In 9 out of 10 templates (maybe even more in the past projects i'm working on) it doesnt need to be displayed in the shortcut menu.
    1 point
  27. So, with your last code, I can't count the occurrence of a field VALUE, but can count the occurrence of the field NAME. Which, from my latest example is not what I am after, since all my fields are required and always occur. Because this code will give me the pagenames that have the array's field 'provincie' present: foreach($someFields as $field) { $resultArray[$field] = array_count_values($somePages->explode('name')); } echo "<pre>".print_r($resultArray)."</pre>"; But I will continue. You already helped a great deal and made me learn more. Thanks so far !
    1 point
  28. Are you sure your page fields belonging to the layout entries are set to single page (see the details tab of the fields). If so you should be able to directly do: // assuming that you actually want to output the title of the page that holds the single image echo $entry->image_full->title; So if($entry->image_full) echo "<div class='full'>$entry->image_full->title</div>";
    1 point
  29. @itsberni: sounds like you're using jQuery 1.9 (or newer) on your site, with .live() already removed. Backend is still using 1.8.3, which has .live() in place. Possible solutions would be either updating the module JS (replace .live() with .on() and make any other related changes) or using an older version of jQuery in your site's frontend.
    1 point
  30. Hi schlagi, no bug But you have to activate these particular URL segments on the template first. See screenshot:
    1 point
  31. My main headache (and this applies to both Mac and Windows) is that I feel as a desktop user that I am slowly being sidelined. As a writer, I use an ergonomic keyboard (not an extreme one, but I like the slight split) so I find laptop keyboards a pain. As a composer I use huge amounts of file space - my main work machine has 4 TB of storage for library files for VST instruments, half of that on SSD, that need to have as fast access as possible. I eat processing power for breakfast - I can melt an underpowered chip at 30 paces if I am in an OTT creative mood. I have no use for touch screens as I need large screens with workspace in front of them, so I would have to stretch forward to use them - it is important to me to see a lot of things all at the same time to work efficiently as I do this professionally and not as a game. I have no use for gesturing as my arms would start aching if I had to flap them around in front of me all day - a mouse is STILL the most versatile interface device I use, despite also having a large wacom tablet. From the GUI point of view, I am probably a potential Linux user since there are loads of simple, straightforward desktops available, but other than as a server, Linux is no good for the rest of my work at all .... it is highly unlikely that the professional tools I use will ever be ported to it as the market is just not there. In the long term my fear is that my hardware costs are going to spiral as my side of the user market contracts to business users only.
    1 point
  32. Hi Nico, UrlSegments are something we haven't yet really considered for the framework - purely because we haven't had to use them yet! You were on the right track, but the name of the function wasn't outputting correctly with your modification - call() allows you to define a function based on a particular path. You'd have to loop through all urlSegments, until you get to an empty one, and then append a string of all the segments to the name of the page in call(). In your controller you would then have: // tasks_controller.php ... // handle requests to tasks/action/update function page_tasks_action_update() { return $this->render('some-template', array( 'some_var' => 'some_value' )); } ... I've made an update to core/controller.php: https://github.com/fixate/pw-mvc-boilerplate/blob/master/core/controller.php#L80-L97 to handle urlSegments
    1 point
  33. Sorry to hijack this thread, but if you are working with HTML5 video, have you seen my draft video fieldtype module: https://processwire.com/talk/topic/4580-video-fieldtype/
    1 point
  34. Ah and just remembered that since PW 2.4 the simplest way to count values of certain keys/fields within a PageArray/WireArray is using the new WireAarray::explode() - combined with using PHP's array_count_values(array) you already used, it's down to this: $someFields = array("province", "network"); $somePages = $pages->find("template=child-template, category=xxx"); $resultArray = array(); foreach($someFields as $field) { $resultArray[$field] = array_count_values($somePages->explode($field)); } // that's it show array result foreach($resultArray as $field => $values) { foreach($values as $value => $count) { echo "<p>$field - $value: $count</p>"; } }
    1 point
  35. Kongondo. I am in awe! WOW, WOW, WOW!!! My mouth has dropped to the floor and my prayers have been answered! This has been designed so beautifully, logically, and intuitively :'(You are super talented my friend. This is something that has been needed for quite some time. Thank you so much for this!!! I'm speechless.
    1 point
  36. If you have the LanguageSupportPageNames module (looks like) installed, you can configure the /en/ part on the root page name for each language.
    1 point
  37. That worked!!!!!!! OMG - THANK YOU @3fingers! Thanks for all the other replies as well guys. It's so nice to have this forum where people are so willing to help each other. In all my experience using other "forums" across various websites, this one has proven to be the most helpful, friendly, and open. The fact, that we all use Processwire makes it even better. Now I can finally get back to working on this site.
    1 point
  38. nice ajaxcrawler . Trying to use historyApi on my site aswell.
    1 point
  39. Here is the code for module that sends email to page creator, once the page is moved from one parent to another. <?php require_once("/site/templates/phpmailer/class.phpmailer.php"); class sendMail extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'Notify module', 'version' => 101, 'summary' => 'Send email after pages is moved to another parent', 'singular' => true, 'autoload' => true ); } public function init() { $this->pages->addHookAfter('Pages::saveReady', $this, 'sendMailOnChange'); } public function sendMailOnChange($event) { $page = $event->arguments[0]; if(!$page->parentPrevious) return; // if page is not being moved then stop now // When page is moved outside its parent but not trash if(($page->parent->id != 1286 && $page->parent->id != 7) && $page->parentPrevious->id == 1286) { //Email address of user that created page $userEmail = $page->createdUser->email; //Message that appears after page is moved $this->message("Mail was sent to :{$page->createdUser->name} at his email address: {$userEmail}"); $mail = new PHPMailer(); $mail->IsHTML(true); $mail->isSMTP(); $mail->Debugoutput = 'html'; $mail->Host = "YOUR HOST"; $mail->Port = 25; $mail->SMTPAuth = true; $mail->CharSet = "UTF-8"; $mail->Username = "EMAIL ADDRESS OF MAILBOX U WANT TO SEND MESSAGE FROM"; $mail->SetFrom("I USE SAME AS ABOVE $mail->Username"); $mail->Password = "PWD TO YOUR MAILBOX"; $mail->FromName = "STRING FROM"; $mail->AddAddress($userEmail); $mail->Subject = __("YOUR MESSAGE IS MOVED"); $mail->Body = "Hello: {$page->createdUser->name} <br />". __("your post has been moved !!"). "<br />". "You can find it here: <a href='{$config->httpHost}{$page->url}'>{$config->httpHost}{$page->url}</a>"; ; $mail->send(); } } } ?> I used phpmailer since im using it from the begining of project. If u can please show how would same function look with wireMail(); Cheers !
    1 point
  40. Thank you @Ryan for sharing the information and test scripts you did. I will try to benchmark on the coming days with the same. I have more than 50K pages .
    1 point
  41. I also ran into this issue and, in case someone else does too, it might be worth pointing out once again that this is not the value to change. At the end of the php.ini-file (that you find under the wamp-icon in the task-bar and then by in the menu picking PHP - php.ini) you have the xdebug lines. Just add the line... xdebug.max_nesting_level = 200 ...directly under the [xdebug]-line. After that, things should run smoothly.
    1 point
  42. one of users asked me how to do counting comments with reply. for countuin comments with reply do next steps: open /wire/core/FieldtypeMulti.php file and find this change it to: then in this file add function: then in this file add function: to print result in your template file type this:
    1 point
  43. You are on the right track Here's an example that does everything. It lists all the categories, and then lists all the entries within each category. This may not be something you actually want to do, but I'm putting it here as an example that can be translated to different contexts. It assumes your blog entries have a page reference field names "categories" and a date field named "date". $cats = $pages->get("/blog-categories/")->children(); echo "<ul>"; foreach($cats as $cat) { echo "<li><a href='{$cat->url}'>{$cat->title}</a>"; $entries = $pages->find("parent=/blog/, categories=$cat, sort=-date"); if(count($entries)) { echo "<ul>"; foreach($entries as $entry) { echo "<li><a href='{$entry->url}'>{$entry->title}</a> {$entry->date}</li>"; } echo "</ul>"; } echo "</li>" } echo "</ul>";
    1 point
×
×
  • Create New...