Jump to content

BitPoet

Members
  • Posts

    1,275
  • Joined

  • Last visited

  • Days Won

    56

Everything posted by BitPoet

  1. The longer answer: yes, a hook should work, but you'll have to modify the html output of InputfieldRadios::render. Quick&Dirty: /* site/ready.php */ wire()->addHookAfter('InputfieldRadios::render', null, 'addOptionImages'); function addOptionImages($event) { $obj = $event->object; if($obj->name == "NameOfYourRadiosField") { $opts = $obj->getOptions(); $ret = $event->return; foreach($opts as $key => $value) { $id = $obj->id . "_" . wire('sanitizer')->name($key); $ret = preg_replace( "~(<input.*?id='{$id}'.*?)<span.*?>.*?</span>~", '$1' . "<img style='display: inline;' src='$value'>", $ret ); } $event->return = $ret; } } The "display: inline" style is needed to keep the image on the same line as the radio button.
  2. @Lenz: the fields works like a charm on 3.0.9. The message you get is because to work, ImageMarker needs a regular image field as well on the template. You add the image field to the template and enter the name of that image field in the imagemarker field's settings. Then, on a page with that template, you add an image to the imagefield, save the page and imagemarker picks up the image from that field.
  3. Try leaving out the leading slash, i.e. echo $page->render('singleimage', 'products/singleimage');
  4. @adrianmak, Edge is known to be a bit picky with loopback connections. While 127.0.0.1 has been fixed when Spartan was renamed to Edge, other IP addresses bound to the loopback driver still can make problems. One of these two changes usually works: Open a DOS box (best use "run as administrator") and type "CheckNetIsolation LoopbackExempt -a -n=Microsoft.MicrosoftEdge_8wekyb3d8bbwe" Or: go to Control Panel -> Internet Options -> Security -> Local Intranet -> Sites and uncheck the option "include all local (intranet) sites not listed in other zones"
  5. 1. Relatively easy, yes, as in no harder than dealing with them if you build a full solution from scratch. 2. No, there isn't. A fieldtype for that would need to be tailored to a certain implementation logic. 3. There's nothing specific in the api, no, but if you build a field type for it, you can use all the field selectors together with a few lines of PHP to set headers, etag etc. based on the field value to output an image and hook into the existing logic of pagefile/pageimage to add your db inserts on top of PW's builtin upload logic. 4. You can either use PW's database interface (class Database, which is just a small wrapper around mysqli), use plain PDO or include your own database access class. PW has a few reasons for adding images to pages, one of the being security - if you have $config->pagefileSecure enabled and define access restrictions to a page/template, you implicitly limit access to its files too. Any option to store files completely outside PW's page structure will break that relationship and require you to limit access rights on a per-image basis (or to implement your own permissions logic that checks access rights with the pages the images are used in, meaning you still need to "assign" images to pages somehow). I do understand the wish to provide some kind of "image pool" though - it's, in fact, one of the next things I have to tackle for our company's intranet, as we have a lot of repeating images and documents in the technical manuals section there that need to be kept in sync. I'll probably introduce some kind of "files library" template, add library pages in places in the tree wherever security settings change and extend the pwlink and pwimage plugins for CKEditor to allow easy picking and inline uploading. You'd need to do something similar to be able to pick your external images. As for outputting files/images not stored in the usual location under the page's directory in assets/files, the code for FieldtypeSecureFile (which stores page files outside of the web root) is worth looking at.
  6. This should IMHO be filed as a bug. The problem here is that Pagefiles::cleanBasename doesn't account for this kind of URLs without a trailing filename. It simply splits the string at the last dot in the URL when it should only look for dots after the last path separator (and perhaps also account for a reasonable maximum extension length, but that's another thing). This is the relevant code: $dot = strrpos($basename, '.'); $ext = $dot ? substr($basename, $dot) : ''; It should (untested) be sufficient to change it to: $slash = strrpos($basename, '/'); $dot = strrpos($basename, '.', $slash); $ext = $dot ? substr($basename, $dot) : ''; if(strlen($ext) > 10) $ext = substr($ext, 0, 10); // Not sure what a reasonable default would be here
  7. "equipment" is a page array. You can use the removeAll method to clear it of all items: $player->of(false); $player->equipment->removeAll(); $player->save(); $player->of(true);
  8. Support for %e is a bit of a fuzzy subject (which is mentioned in the docs). I'd create a small php file and call it directly to check for %e support: <?php header('Content-type: text/plain'); echo 'Month is ' . strftime('%e') . PHP_EOL; ?> EDIT: Didn't look closely enough. As dates in February and April are shown, it's unlikely that it's about %e. Pleaes move on, there's nothing to see here.
  9. I can think of two possibilites to approach this: Reverse your logic and add the products in a page field to the option page (not really intuitive) Add a counter field to the option pages' template(s) and update the value through a hook on Pages::save for your product template (with a similar looping logic as in your code above). Then you can easily filter with $optionpages->children("usecount>0").
  10. You can't use a wildcard in Access-Control-Allow-Origin if you want to do XHR. A simple workaround would be to return the value of the Origin request header instead of the wildcard.
  11. You need to allow credentials for cross domain requests for ajax calls in the mobile framework you use. For regular xhr objects this just means setting xhr.withCredentials = true; but depending on the library, this may have to be done in a less direct way (like in beforeSend in jquery where you have access to the xhr object).
  12. At least in 2.7.0 it already removed pipe characters (this is from Sanitizer::selectorValue): $value = str_replace(array('*', '~', '`', '$', '^', '|', '<', '>', '=', '[', ']', '{', '}'), ' ', $value);
  13. Uhm. Shouldn't it be $selection = implode("|", $input->get->filter); ?
  14. Is mod_proxy active on server a? Edit: with server a I mean the customer's original server.
  15. Sorry, didn't look closely enough. I meant h2 span:hover { text-decoration: underline; } Though for that kind of styling you should always use classes or ids to avoid styling unrelated content. I'm assuming here that you want the text to underline when you hover over it. If you want to style the text on hovering over the image, it's a completely different topic.
  16. A good place to start reading would also be the Map Marker field module, which Ryan created as an example. In short: The Fieldtype is responsible for taking care of saving to and loading from the database as well as sanitizing values, creating the database table(s) and assembling the correct database query from a selector. The Inputfield renders the input form elements and processes form input. InputfieldMapMarker generates its input elements manually in the render method, but you can also use InputfieldXXX modules (like it does in ___getConfigInputfields) and add those to an InputfieldWrapper, then render that.
  17. That is what the :hover pseudo class is for. span.caption:hover { text-decoration: underline; }
  18. I wouldn't rule out mod_security then, it's famous for returning that kind of random errors, as there are a lot of parameters that work together to trigger an exception. If possible, I'd look into mod_security's log file to either rule it out or confirm the exact trigger(s), and go from there.
  19. There's also a danger of decreasing perfomance instead of the opposite if you aren't careful with includes, as you may be introducing round trips to the content server or trading a few lines of PHP code for separate request parsing and additional file IO. Even if you speed up nine out of ten requests, the one that has to fetch every dynamic part from scratch may simply take too long in the user's eyes. Thus, Varnish ESI / NGINX SSI usually come hand in hand with in-memory caching, and if you plan for really high traffic, you'll want to make that cache distributed and add some kind of boot-up script to fill (most of) the memory cache in case of a purge (this is a point where I realized how convenient elastic cloud servers could be in heavy load environments, as you could fire up a copy of your PW server and run the boot-up script there without slowing down the life instance). I've been thinking about approaches there for a while as I'm working on my forum project, and it can be quite a headache. There's all kinds of partial, dynamic content like forum statistics, login boxes, thread updates, last posting lists or PM information, and each has different requirements regarding actuality and load impact. Add different levels of visiblity to that (i.e. through forum roles or user settings) and the flow chart becomes one of the feared many-legged spiders Expiry of memory-cached contents is another minefield in itself. I guess one generic rule, for PW as for every other web application, is that the right key already brings you half the way to the goal. If you can have your backend (PW) fill the memory cache with dynamic content and either pass the right key in a cookie to the user, use a unique URL or use GET/POST parameters to form the key, the cache can fetch that content easily. Of course, not every content is easily cacheable, and sometimes it may make sense to keep the memory footprint of cached content small by breaking it up so one doesn't end up trying to cache every single one of a thousand possibilities for every single user. In NGINX, this could e.g. mean that, instead of caching the complete logout box for each user, to render it once into memcache with placeholders and letting NGINX substitute ("echo") the necessary keywords it has retrieved through earlier calls to the memory cache (and stored the results with "set"). That's just a small brain dump and mostly theoretical, but it is an interesting topic and one I'll have to face sooner or later, so if anybody has practical experience, it would be interesting to hear about that.
  20. Any chance this is apache with mod_security enabled?
  21. It should be sufficient to set the extensions property (i.e. valid file extensions).
  22. This is a classic case for OR-groups. parent=/portfolio/, sort=sort, (project_location_london=camden), (project_location_elsewhere=midlands)
  23. If you want to sort the artists differently for each genre, you'll probably have to reverse the logic and add an "artists" page field to the genre template and put the artists there. Each page then keeps its own sort order for its field contents, so your client can sort the artists however he wants. It doesn't scale as well though if you have many artists.
  24. You could perhaps use OR-groups in the selector (untested): $options = array( "level" => true, "max_levels" => 2, "selector_level2" => "(parent!=$lastpageid), (id=$items)" );
  25. You're mixing two concepts here: First, the native parent-child relationship that PW provides. ABBA is a child of the Pop page (category). This is what the backend shows and every page can only have one parent. Second, you have relationships through page fields. This is completely structure-agnostic. You're actually making things a little complicated by placing the artists underneath a category. Easier would be to have a page "artists" underneath "music" with its own template and under which you have all artists, no matter what category they belong to, and simply set all the categories for the artists like you already do. Presentation of the relationship for the frontend happens in your PHP template file for music-genres, where you get all the artists for the category with a selector like $artists = $pages->get("template=music-artist, music_genre_types={$page->id}"); instead of calling $page->children. You could mix both concepts and merge $page->children with the result of the selector above, then your current approach would still work.
×
×
  • Create New...