-
Posts
680 -
Joined
-
Last visited
-
Days Won
18
Everything posted by Jan Romero
-
Find all pages matching tag (using urlSegment)
Jan Romero replied to a-ok's topic in General Support
$variables are only resolved when inside "double quotes". With the 'single quotes', $pages->find() will always look for /tags/$tag/, never /tag/green-energy/, etc.. Might just be a typo in your post, but I thought I’d mention it. -
You can create a web-accessible php file anywhere on your server and bootstrap ProcessWire from there, without creating a page as far as PW is concerned. An example: <?php /* This file is nowhere in particular and not a template or anything. */ require_once("./cms/processwire/index.php"); $name = $wire->input->post->name; if ($wire->input->post->name == 'manol') { $m = $wire->modules->get('CoolModule') die($m->welcome($name)); } die('Hello anyway.'); I have no experience with this, so I can’t tell you about potential drawbacks, if there are any. Another way to avoid creating a “page” would be to allow urlSegments for your root page and handle the input there. It would look like any other page but it won’t disturb anyone’s aesthetic sensibilities in the admin backend.
-
No, although you could use the parent pages you already have: Bassisten, Fluitisten, and Trombonisten. In your example, the groups only go up to C. If you’re only dealing with a few items, it might be fine to do all filtering with Javascript. You could add an id attribute with the group’s name to your <ul> element, and simply hide all the others if the user selects a filter. Sorting could be implemented this way as well. However, that’s not a ProcessWire solution. To do the filtering server-side with PW, you will want to accept GET parameters in your page template. GET parameters are those values that sometimes appear at the end of URLs. On your page, it could look something like this: http://www.deliciousthoothpaste.nl/muzikanten/?filter=bassisten or http://www.deliciousthoothpaste.nl/muzikanten/?sort=descending or even http://www.deliciousthoothpaste.nl/muzikanten/?filter=bassisten&sort=descending Now the page /muzikanten/ has these variables built in and you can use them in your template. They are in the $input->get API variable. $sort = 'title'; if ($input->get->sort === 'descending') $sort = '-title'; //Put a - in front to sort Z-A $muzikanten = $item->children("sort=$sort, sort=id"); //always sort by id to break ties consistently foreach($muzikanten as $muzikant) { ... } Now you just need to get the user to visit your page with the GET parameter in the URL. As soon as he selects a sorting option, you send him to it using Javascript: window.location = '/?sort=' + selection; As you can see, Javascript is sort of required if you want the changes to apply (i. e. to reload the page) immediately. You can however avoid this by setting up a form with a submit button. The downside is, of course, that the user has to press the button in addition to selecting a value from your dropdown. <form method="GET"> <!-- If you leave out the action attribute, it will just reload the page, but with the added parameters --> <select name="sort"> <!-- this is the parameter name that will be in $input->get --> <option value="ascending">A-Z</option> <option value="descending">Z-A</option> </select> <input type="submit" value="Apply Filters" /> <!-- gotta click here to do stuff --> </form> (Not too firm on the HTML syntax here, best read up on it yourself)
-
Ah, good catch . The API key was a field setting before I put it into the module config. Wonder why I didn’t get that. I assume they’re only shown in debug mode? Thanks for the kind words everyone. I appreciate it :)
-
Sup. FieldtypeOpenWeatherMap [GitHub] This module fetches and stores current weather data from the OpenWeatherMap.org service and helps you manage icon markup. To limit requests, OpenWeatherMap.org’s JSON-response is cached in the database and only refreshed once the field is accessed and the cache has a certain age that you define. The fieldtype is sadly not multilingual, but you can configure the language of the weather descriptions OpenWeatherMap.org provides you with. It would not be hard to make the output multilingual by referencing weather codes and translating them with ProcessWire’s built in tools. You install FieldtypeOpenWeatherMap just like any other module, by placing the two files into ProcessWire’s modules directory. Once installed, you want to create a new field of the type OpenWeatherMap and assign it to a template. The template now has a text field that stores a city id. In the field settings, you may configure how and when the data is requested. That is, the requested language, units (eg. °C/°F/K) and the cache duration. The module does not provide you with built in icons or otherwise limits you to predefined markup (which I consider a good thing ). The icon in my example above is courtesy of Alessio Atzeni’s Meteocons (custom free license). To make generating icon markup a little easier, you can configure your own markup snippets in the module configuration: As you can see, in this example I’m using an icon font whose appearance is defined elsewhere in my CSS, but you’re free to put in image urls or just unicode entities or whatever. Rendering it is now quite simple. The following markup would result in something like the image above: <?php $w = $city->weather; $temp = round($w->temperature); ?> <p><?php echo "{$w->renderIcon()} {$w->description} at {$temp} °C"; ?></p> <h2><?php echo $city->title; ?> <span class="ico-rightarrow"></span></h2> <!-- irrelevant line --> The variable $w is now a WeatherData object that exposes the following properties: json //The raw JSON response from OWM timestamp //The time of the request city_id //The city id you entered in the admin sunrise //The time of sunrise sunset //The time of sunset main //The main weather name, e. g. “Rain”, in the configured language description //A slightly longer, more precise description like “occasional rain” iconcode //The internal icon code for this weather temperature //The temperature in the format you requested min_temperature //... max_temperature //… wind_speed //I believe the wind speed is also affected by the unit settings. As well as the method renderIcon(), which you already know. If you access a WeatherData object as a string, you will get the city id. This is so that the city id will correctly appear in the admin page edit form. I should mention that there is some more information in the JSON, such as wind direction. The module also exposes the method multiRequest(PageArray $pages, $fieldname). If you want to fetch data for a bunch of pages at the same time, you may want to use that so as to reduce unnecessary requests to the service. I haven’t really used this yet, so consider it experimental, I guess. As of now, this also disregards the cache freshness. If you’re still reading, there’s a chance you might be interested in using this. Allow me to clarify that right now there is no support for forecasts or historical data (yet?). Sorry :> Here’s the GitHub link: FieldtypeOpenWeatherMap.
- 17 replies
-
- 20
-
Check out the Hanna Code module if you don’t want to use a WYSIWYG editor. It’s perfect for this.
-
They aren’t. Although from the looks of it, it seems to be partly the repeaters’ fault?! Cloning a page also clones the repeater pages as expected, but for some reason they’re parented to page-id 0, so they don’t show up in the admin. Things quickly get sort of messy, but it shouldn’t be too hard to fix, actually.
-
On the Rabotheater page the DOM doesn’t change at all. The buttons just change the class of the list, thereby changing the CSS. I would recommend this technique unless you want your views to show different data. You can solve the different presentations either for the entire list, or for the individual films. I would probably go with the latter: You have three templates for a film page: film.php – Just your regular page template to display a specific film. This is the only film template that is represented in the Admin. film_list_image.php – Only the markup for a list item showing the film and perhaps some relevant info in the “collage” style. film_list_title.php – List item markup including the film title and perhaps release year, review score, or whatever. On the list page, you render films using the $page->render() method with the chosen template as the first argument: $film->render('film_list_image.php'); You can switch between styles by reloading the entire page with Post, Get or urlSegment input, and perhaps store the preference in $session or $user. You could also load the films with AJAX and call $film->render() with the template there, then return the new markup to the list page. Of course, it might be better to return the film information in JSON format and build the presentation markup of choice with JavaScript on the list page. As you can see, there isn’t one technique that fits all. The CSS option is definitely the fastest, simplest and arguably the best way, provided you can keep the markup the same between both list styles. Just have a look at the Rabotheater site in your Element Inspector. Wicked fast, no DOM changes except one class attribute, no additional server requests. You could even animate the change. I only go into the other stuff because it incorporates ProcessWire and because it answers your question about having two templates for one page.
-
So I suppose this is a somewhat pointless addition, seeing as drafts are about to come to the core, but I needed this right now and ProcessWire made it possible for me to implement over the last two days. An experience that convinced me once more that ProcessWire is absolutely amazing. GitHub link. So what does this do? This module allows you to create a draft version of (hopefully) any page, which can be edited while the public facing page remains in place and unchanged. Drafts are placed under a special Admin page, which also doubles as a rudimentary manager. It shows what pages have drafts assigned and lets you update the original page with its draft. I need all this mainly for front-end editing, so for me the focus is on the added API methods. I have added functionality to redirect every edit to a draft page for testing, and it can make sense to have that behavior of course, so it will probably become a config setting. How does it do that? Page cloning is very very handy for this purpose, so that’s mostly what I’m doing here. It’s elegant in that very little code is needed, but it is perhaps somewhat crude to delete pages, including their field data and files on the file system, so much. I needed some hacky-feeling tricks to convince PW to delete pages that have children and clone pages to my custom admin page even when their template prohibits that sort of parent. What doesn’t this do (well)? Since a draft is linked to its page by having the page ID for a name (!), which conviniently also guarantees uniqueness, modifying page names should be pretty much impossible. It would be best to create a table to store the references, but I kind of like that you can keep everything 100% PW API. The most complicated fieldtypes I have tested this module with are Images/Files and Multiplier. That covers my immediate need, but perhaps PageTables will cause problems. I don’t have any experience with those. There are probably a lot of other things to look out for, but I can’t remember any more right now. Be aware this is most definitely not production ready or anything. I would like to thank Teppo Koivula, whose Changelog module I used for inspiration downright based this on. Great work there, and a lot to learn from. If you find fragments of Changelog in this module, that’s no coincidence. Also hugely helpful are the great members of this forum and Ryan’s code, which I assume we all use as our main documentation <3 Please absolutely tear this apart, if you can spare the time to have a quick look. I like to think I did okay, but I’m eager to learn and I’m sure this is full of questionable practices, bugs and inefficiencies. So yeah, its unlikely anyone will have the need to use this on a site, but hopefully I can get some feedback out of it and perhaps it can teach other beginners like me a trick or two. GitHub link again. /wall of text
-
By the way, there is also closest($foo) and parentsUntil($foo).
-
That shouldn’t happen, actually. Does it do that on your site?! It’s supposed to return the parent closest to Home, as matjazp said. I mean, what would be the point of just returning Home for every single page on the site
-
Try $page->parent("parent=$foo") edit: parent, not parents.
-
If I understand correctly, for that trick to work you don’t need to literally host your images in a seperate location. It should suffice to have a subdomain that points to the same paths you’re normally using. Basically, the benefit comes from loading images via a different domain, because it makes the browser allow a parallel connection. Not sure how relevant this is with modern browsers, though.
-
There is start? $posts = $pages->find('template=news, sort=-created, start=80, limit=40');
-
It’s not a mouseover, but I think you’re looking for something like Soma’s Field Helper module? It also provides links to edit the fields. Very helpful. http://modules.processwire.com/modules/helper-field-links/
-
Sure, as long as the name is unique enough for you to put it in your selector. You may also want to look into urlSegments. For this purpose, they’re basically the same thing, but with prettier urls. For example the url might be /mycategory/atlanta/, where atlanta is a urlSegment. It doesn’t exist as a real page, but you can access it with $input->urlSegment1. Or something like that. I'm on mobile, so just check out the docs on urlSegments. It’s very easy to implement. Just always make sure you only accept values you expect, and sanitize your stuff. In case of this example, you’d use $sanitizer->pageName().
-
Are you familiar with $input->get? You can simply accept a city argument on category pages and vice versa. On your category page, you list cities like so: foreach ($cities as $city) { echo "<a href='{$city->url}?category={$page->id}'>{$city->title}</a>"; } On the city page where that link leads, you accept the argument "category": $category = $pages->get($input->get['category']); Now you know the city and the category to search for. Refer to the docs for more info on $input. Note there are several other ways to solve your problem.
-
There are multiple ways of doing what you seem to describe. Check out the fieldtypes repeater, multiplier, page, and pagetable, for example. Some of these are ProFields that you can license for little money. Which one is best suited depends on the kind of data you want to store. You can’t add the same field to a template multiple times. You either have to use one of the repeating fieldtypes that work similarly to image/file, so you can have multiple values per page, or create more fields. For example, it might make sense to have a field for a phone number and another for a fax or mobile number, instead of one repeating field where it might be difficult to tell which is which after the fact.
-
Email and phone are extremely annoying in Firefox desktop as well. They’re very picky and don’t work well with standard keyboard commands. My first instinct was that the tab key takes you behind the @, instead it took me to the next field and threw out all my previous input. Then I tried End, which didn’t work at all. It never occurred to me that you have to type the @ yourself. Also pasting doesn’t work and neither does arrow-down to show the browser’s suggestions. Those are probably the most common ways people enter their email addresses. +1
-
Your images field is probably set to Automatic because you use it for multiple images in another template, but for user profiles you limited it to 1, which means you don’t have to use →first(). You can also configure the field to always give you an array, regardless of the max-setting. Then you have to write →first() every time, but you’ll always know what you’re working with. Maybe a single image should throw a descriptive exception when accessed like a WireArray.
-
No. If you really want to use this textfield approach, use muzzer’s technique and make sure every area is wrapped in pipe symbols, so you can select areas %= '|$area|'. However you should be aware that that’s not a good idea at all. If it’s at all possible to use pagefields, as LostKobrakai suggested, you should do that. Once you have set up your areas as pages, it will make everything much easier.
-
I’m on my phone and it looks fantastic, but if you could somehow make it so the Safari interface expands when scrolling back up, as it does on most websites, iPhone users will surely appreciate it. Then again, I’m still on iOS 7, so maybe that isn’t an issue anymore with newer Safaris.
-
Do you have any more information on this problem? Can you show the code? Is there anything in the logs? Btw the German keyboard has a key for the straight apostrophe, should be next to Ä (Shift+#). You’re using an acute accent which puts weird gaps into words. You should also use that apostrophe to delimit static strings in PHP.
-
German (de-DE) not maintained
Jan Romero replied to Nico Knoll's topic in ProcessWire Language Packs
Nice, thank you for your continued effort! By the way, “actual” is a false friend. To mean “aktuell” you want something like “current” or “the latest” -
Strategies for storing and using email templates
Jan Romero replied to onjegolders's topic in General Support
There is a way, and it works exactly as you described Only your syntax is slightly off. You need to pass an array like so (or prepare it beforehand): $SomePage->render('optional_non-default_template.php', array('recipient'=>'Mr. North')); Then on that page’s template you can simply call $options['recipient'] and it will === 'Mr. North'.