Jump to content

Search the Community

Showing results for 'runtime'.

  • Search By Tags

    Type tags separated by commas.
  • Search By Author

Content Type


Forums

  • Welcome to ProcessWire
    • News & Announcements
    • Showcase
    • Wishlist & Roadmap
  • Community Support
    • Getting Started
    • Tutorials
    • FAQs
    • General Support
    • API & Templates
    • Modules/Plugins
    • Themes and Profiles
    • Multi-Language Support
    • Security
    • Jobs
  • Off Topic
    • Pub
    • Dev Talk

Product Groups

  • Form Builder
  • ProFields
  • ProCache
  • ProMailer
  • Login Register Pro
  • ProDrafts
  • ListerPro
  • ProDevTools
  • Likes
  • Custom Development

Find results in...

Find results that contain...


Date Created

  • Start

    End


Last Updated

  • Start

    End


Filter by number of...

Joined

  • Start

    End


Group


AIM


MSN


Website URL


ICQ


Yahoo


Jabber


Skype


Location


Interests

  1. Hi all. I've got something that I'm not 100% sure is a problem with AppApi or elsewhere, so I'm hoping someone can just help me cross the AppApi module off my list of the things I'm looking into. I'm currently trying get my API to send an email when a certain POST is made. Locally this works fine, but on our test server I'm getting an unexpected error: { "error": "Internal Server Error", "devmessage": { "message": "set_time_limit() has been disabled for security reasons", "location": "/home/runcloud/webapps/D2U-API/site/assets/cache/FileCompiler/site/modules/WireMailSmtp/WireMailSmtp.module", "line": 750 } } Now a quick look through this forum suggests that this should be generating a PHP warning, that I should just be able to ignore, but for some reason it's stopping execution and generating the API error. I'm wondering whether AppApi is handling this as a hard error and stopping execution, but really it would carry on fine if left, or whether the situation I'm seeing is more serious than the examples in that other forum post? @Sebi or @thomasaull do you have any comments about how a PHP runtime warning would be handled?
  2. First off, just increase raw power. Try bumping up your VPS with more power. Easy solution and this stuff is so cheap nowadays. Upgrade the software if possible I've had instances with 300+ fields on a template with more than 500k pages. Queries started to slow down around 200 fields. I bumped the Mariadb version to the latest, switched to INNOdb, PHP 7.2.x and it was running pretty smoother on a digitalocean medium sized VPS ($40/mo). We also had tons of runtime fields and we cached those so a page save would do the calculations instead of calculating runtime. When we eliminated those the application became really snappy with 200-300 concurrent key users doing all kinds of imports and running reports while the 1000 regular concurrent users didn't notice lots of slowdown. Most of the slowdown nowadays come from the interface itself. We used a lot of jQuery kinda tooling inside ProcessWire admin and since the users don't have the fanciest computers, some browsers are not really capable of rendering the back-end. I guess we needed to switch to a SPA, but I'm not working on the project anymore. Jup, this is the key. Especially while desiging applications this is really important. Try to split up as many as you can. I don't store address information on the order, but on the client, and possible even on an address template which you can re-use. You can also use Page fields to combine all those. To comply to GDPR you can also store the blob of address info in one or two fields on the order itself. So if a client requests to remove his data you can easily remove the accoun and associated addresses. And you still have the address data. Another solution is to use the FieldsetPage to create on instance of all address/personal information. In the background PW creates another page containing the info. You add this field to the page once for invoice and once for the shipping info.
  3. I just had a very weird issue today... I'll try and describe it as best as I can: I have a frontend search form (text search and filters), which used to work fine before I have installed and used the RTMU module. Today the following fatal error appeared: PW basically tripped over these lines: public function getMatchQuery($query, $table, $subfield, $operator, $value) { // we don't allow this field to be queried throw new WireException("Field '{$query->field->name}' is runtime and not queryable"); } Now, the strange thing is: I am carefully constructing my selector (only pages within parent 1041, with template 'project' etc.etc.). The only template that used the RTMU inputfield was NOT the template I was querying. I have used it in another template, along with a page-reference field. Now this page-reference field was configured to show template 'project' pages, and children of page 1041. Now that I have deleted the inpufields / removed them from my other template, everything works fine again. How can it happen that this inputfield is somehow interferring a PW selector / search? For a second, I thought I could also just comment this line: // throw new WireException("Field '{$query->field->name}' is runtime and not queryable"); but then again, I don't know what else I could possibly break somewhere else by accident. @kongondo Do you have any idea? Did you ever run into similar issues? SERVER DETAILS ProcessWire: 3.0.124 PHP: 7.2.14 Webserver: Apache/2.4 MySQL: 10.1.35-MariaDB InputfieldRuntimeMarkup: 0.0.2 TracyDebugger: 4.15.8 PS The module worked fine for me otherwise! I have used it to add a link which opens a frontend-page in a modal: return '<a class="pw-panel pw-panel-reload ui-corner-all ui-button ui-widget ui-corner-all ui-state-default" href="https://dev.webapp.mysite.com/somepage/" data-tab-text="Choose x y z" data-tab-icon="eye" id="proj_chooser" role="menuitem"><i class="fa fa-fw fa-search"></i> search / choose</a>';
  4. @ryan This is an excellent addition to the core. For a particular use-case I have, I am wondering if something is possible -- either something already possible I've overlooked, or as a feature request. Sometimes it is useful to have the page info when building a selector for a page reference field — so I was wondering whether it could be possible to use placeholder tokens to pass the current page being edited to the ajax request? For example, in the "Text Tags" section of the field setup, we could enter something like this for the "Ajax URL" : /find-fieldname/{page.id}/?q={q} Where "{page.id}" is replaced with the ID of the page being edited at runtime. Similar to other places in the PW admin where we can insert placeholder tokens. Then in the hook itself, we have: $wire->addHook("/find-fieldname/([0-9]{4})/", function($e) { $pageID = $e->arguments(1); // ... the rest of the code }); I'm using page ID as an example, but it could be any valid page or template variable.
  5. @chrizz your calculation is totally wrong. Only thing that is of interest for imagesizer is uncompressed image in memory. You do not hit a filesize limit, you hit a memory limit. Why you run into it, I can't say. But I can say that we do runtime checks for available memory before opening an image in memory, but also we use a fast calculation depending on most common images for that. Without seeing your original images, I guess your original image has some image markers like EXIF, IPTC, VENDOR-Tags etc. what may be a little over the top of what we use for our precalculation. Theoretically it is possible to pack a lot of data into this, but typically it isn't that big. Maybe an edgecase? (Calculation like we do, fits just into available runtime memory, but without the ImageMarkers?) But one thing is a physical fact: FilesizeCompression cannot reduce needed memory limit. (and therefor I do not need deep theory, this is simply how computers work since ever. In my earlier days, around 1994, we sometimes do some jokes: we compressed big dimensioned jpeg images with the lowest quality setting / highest compression rate, and send them as previews to Artdirectors with a question to them. Always when they tried to display it, it got loaded / uncompressed into memory and their systems imediately got freezed / unusable. So, we only have done that to very unfriendly people who really deserverd a little shock. ) So, what ever you have changed in your second saved imagefile, what is responsible for the fit into memory than, it is not filesize compression. A serious test would need to log the runtime available memory for both images before trying to open it, and the same after they allocated the memory, and compare all that. Also a full check of all file parts in the imagefile (markers and image data). Without that, it says null to nothing and only opens room for glasball looking, guessing or misinterpretions.
  6. @fedeb Looks like I missed a spot on the updates to the Event class, I have fixed that and removed the references to the old fields (location, notes). 1. In ProcessWire a Page can be in a "output formatted" or unformatted state. You can toggle output formatting on with $page->of(true); or toggle it off with $page->of(false); Or you can get the current state with $formatted = $page->of(); When output formatting is on, values returned from the page are intended for output and thus can contain runtime formatting such as entity encoding. This is good for output, but definitely not something you'd want saved the database, so when you are creating pages or saving values on pages you want to have its output formatting disabled, i.e. $page->of(false); This should be done before getting, setting or modifying values that will be saved. 2. The location and notes aren't supposed to be there. I removed them in favor of making the module simpler by just having "title" and "date", and then people can add any additional columns they want. 3. The set() and get() functions are inherited from the WireData class. (Event extends WireData) 4. InputfieldEvents won't be included unless something asks for it (like the page editor in the admin). If you are just using the API side, then the InputfieldEvents module likely will never be loaded or come into play. It's still nice to have in case you ever want to see or edit your data in the admin.
  7. @ryan for the time being the data (groupID, start, end, sequence) are not supposed to be queryable. Ideally groupID should be, because I would like to display all proteins belonging to a groupID in the group page but I think I will use a workaround for this: I have a file for each group containing this information which I plan to parse when loading the group page. Individual files have at most 1000 lines (proteins). In this way I avoid querying 20+ million entries each time you try to access a particular group page. As you suggested I will load each entry (groupID, start, end, sequence) as a text field and then use php explode method to parse it into an array at runtime. The only doubt is probably on groupID: A single groupID can be referenced by multiple proteins and it does contain additional information displayed in their respective group page (I create the group pages separately). The natural limit is around 20 groups although normally this number is 2 or 3 groups per protein. With this setup is it worth using a Page reference field? What are the other storage possibilities? In the future I think I will end up using ProFields or building a Fieldtype module. For this last approach I think I need to read a bit more about modules since I am new to processwire. This tutorial posted by bernhard is a good start. @Hector Nguyen if you are not constraint by memory then loading the csv into memory all at once is the way to go, right? Thanks for all the useful suggestions. p.s. maybe I am diverging from the original thread. If you prefer I can open a new one.
  8. @fedeb Glad that moving the $parent outside the loop helped there. The reason it helps is because after a $pages->save() is the automatic $pages->uncacheAll(), so the auto-assigned parent from the template is having to be re-loaded on every iteration. By keeping your own copy loaded and assigning it yourself, you are able to avoid that extra overhead in this case. Avoid getting repeaters involved. I wouldn't even experiment with it here. That will at minimum triple the number of pages (assuming every protein page could have a repeater). Repeaters would be just fine if you were working in the thousands-of-pages territory, but in the millions-of-pages territory, it's not going to be worth even attempting. Using a ProFields table field would be the best alternative if you needed it to be queryable data. If you didn't need it to be queryable data (groupID, start, end, sequence), I would leave them as they are, space-separated in a plain textarea field — they can easily be parsed out at runtime so you can access them as as properties of the page. (If that suits your need, let me know and I'll get into how that can be done). When working at large scale, it's also always good to consider custom building a Fieldtype module for the purpose too (that's another topic, but we can get into it too). For your groupID, if the same groupID is referenced by multiple proteins, and there is more information about each "group" (other than just an ID) then I think it would make sense for it to be a Page reference field. What is the max number of groupID+start+end+sequence rows that a protein can have? If there is a natural limit and it's not large, then that would open up some new storage possibilities too. Another optimization you can make in your loop: $page->sort = $i; This prevents it from having to detect and auto-assign a sort value based on the quantity of children the parent page has. For the $page->name, if each page will have a unique "protein-name" then you might also consider using that rather than the ("protein" . $i), as it will be more reflective of the page than a generic index number.
  9. Hi, that's where comes, once more, the beauty of pw... something you can easily do, just create a hidden page, let's say "sliders" (can use an template without file) this page will have children using a template without file too, template to which you'll just need to associate the repeater used to create your sliders elements and this is where the magic comes, Hannacode! create yours, something as easy as [[slider id=123]] or [[slider name="xxx"]] id being. the id od the page containing the slider, name... well guess ? and where you want your user to be abble to use them, just add TextformatterHannaCode to your ckeditor; job done, it works a little like wp shortcodes but; a little difference, it works, it lets you write and use the code you want without generating hundreds of html/js/css lines in the page, it won't be broken by some update and it's fast as hell i let you decide where and how to tell your user what code to use, personally, i use kogondo's https://processwire.com/modules/fieldtype-runtime-markup/ it makes easy to add an easily selectable piece of code inside a readonly input in the backend, live example for a customer who wanted to be able to create carrousels and use them anywhere in any page if french, sorry, but you get the idea and, below, there is... a title and a simple repeater, the user has just to add a p in ckeditor, paste the code and hannacode takes care of what's left to do ? hope it helps have a nice day
  10. @fedeb That's the largest quantity of pages I've heard of anyone creating in ProcessWire, by a pretty large margin. So you are in somewhat uncharted territory. But that's really cool you are doing that. I would be curious how different the graph would be if you split it up into batches so that you aren't creating more than a certain quantity per execution/runtime. For instance, maybe you create 10k in one execution and another 10k in the next, etc., or something like that. Would the same slowdown still occur? If so, I would start to think it might be the database index and increased overhead in maintaining that index as the quantity increases. On the flip side, if restarting the process to create each set in batches solves the slowdown, then I would think it might be memory or resource related. A couple things you can do to potentially (?) improve your page creation time: 1. At the top of your code (before the loop) put: $template = $templates->get('protein'); Then within the loop set: $page->template = $template; 2. I don't see a parent page assignment. How are you doing that? Double check that you aren't asking PW to load the parent page every time in the loop and instead handle it like with the template in #1 above. 3. What kind of fields are on your "protein" template? Depending on their type, there may be potential optimizations. Especially if any are Page references. Can you paste in a line or two from the CSV? 4. If you can assign a $page->name = "protein" . $i; rather than having PW auto-generate a name from the title, that will save some resources too.
  11. I know that a runtime field is tempting because it abstracts complexity but such things can quite easily be done via hooks as well. That means you don't need a module and you get even more possibilities: <?php $wire->addHookAfter("ProcessPageEdit::buildForm", function($event) { $page = $event->object->getPage(); if($page->template != "mytemplate") return; $form = $event->return; if($f = $form->get("title")) { $next = $page->next; if($next) $f->notes = "Title of next page: ".$next->title; } });
  12. Hi @adrian Sorry for being too briefly ? This is what I'm talking about: My module hooks into the pagehitcounter's method that logs requests to pages. I had to find a way to get the page path that relates to a given page id efficiently and easily. Otherwise I'd just have a list of page ids shown to the user (which is not really helpful) or the other option would have been to store page paths to the DB or calculate them on runtime (also not ideal). The solution I came up with is to install the PagePath module. That module creates a list of all pages that live on the system and keeps that list in sync with pages (eg when changing a pagename etc). You get a table in the DB that holds the page ID and the corresponding page path. If you don't have that module installed, there is no way (as far as I know) to get that information from the database (well, I guess that's the reason why PagePaths module exists so I'm quite confident with that assumption ? ). RockFinder has the same limitation and I've taken another approach there, see the addPath() method: https://github.com/baumrock/rockfinder3#addpath Does that clarify things? ?
  13. I've done something similar on my extension module for PageHitCounter where only page IDs of page hits are stored. You need to enable PagePath module and then you can join page paths to page ids easily and efficiently. The page paths are kept in sync by the module, cached in the DB and therefore do not need to be "calculated" at runtime on every item.
  14. @ryan - I just discovered that findRaw() won't return the "url" field. I suppose that is to be expected given that it's not a DB stored field, but rather calculated at runtime, but it does still somewhat limit the functionality of findRaw in LOTS of useful situations. Do you think it would make sense to support this, or would it just slows things down too much? The other thing is I am wondering if you'd consider an option to return a standard PHP object rather than an array? It would make it so much easier to switch between find() and findRaw() Thanks.
  15. From recent discussions around the future of Processwire, I suspect my use case might be a bit different to others, as rather than using it in the website 'builder' type scenario, I'm using it more as a database management system, where structured data is critical, and quite often 'pages' will never be visualised via a template, and if they are, the template file is effectively a 'report'. In my case I'm tending to build sites where the admin IS the site, and there's often little or no front-end. I've wondered whether I'd be better to learn some framework like Yii or ASP.Net that have CRUD code generators that can generate data entry forms for SQL tables, but I like Processwire's admin, and the permissions system is something I rely on a lot. I've started working on a membership app, that will have quite a few users, and I've immediately run into a problem. I want admin users to be able to store first name, last name, address etc for members, but it's quite conceivable with a large enough list that it's possible to have more than one say 'John Smith', living at different addresses. I know how to write a hook to put an arbitrary auto-incrementing number in the title field (which will also populate the name field), but this seems to me to break the DRY principle. There's already a page ID, and if I'm effectively populating two other indexed database fields with an arbitrary number so that I can uniquely identify records and keep Processwire happy, it doesn't feel quite right. In straight SQL I can use an auto-increment numeric surrogate primary key and create a constraint on multiple columns so I could have as many 'John Smiths' as I like as long as they reside at different addresses, but I'm not sure how I'd go about this in Processwire, as each field resides in its own table. Perhaps the new Combo Profield @ryan recently released might be have potential for this, as all the subfields reside in a common database table, and there's already some capability to edit the database schema, although I'm not sure if this extends to creating custom constraints? That would be a really great feature, as it would allow defining unique records based on a combination of sub-fields. The Combo fieldtype is still a fieldtype though which needs to be added to a template with mandatory fields, so I still potentially have page id, name, and title all essentially duplicating each other's functionality as arbitrary numeric fields. I understand why page name is meant to be mandatory, as a page that has a template file needs to be accessible via a URL, and the page name is part of the routing, however I'm not sure whether it's practical for pages that don't have a template file to simply work off the page ID? What might be useful is a template property setting that can indicate that the id should be used as the name as well, so there's still a 'name' but it's populated at runtime as a reference to the page id. I'm guessing it might be possible to do something like this via a hook?
  16. ProcessWire RSS Feed Loader Given an RSS feed URL, this module will pull it, and let you foreach() it or render it. This module will also cache feeds that you retrieve with it. The module is designed for ProcessWire 2.1+, but may also work with 2.0 (haven't tried yet). This module is the opposite of the MarkupRSS module that comes with ProcessWire because that module creates RSS feeds. Whereas this module loads them and gives you easy access to the data to do whatever you want. For a simple live example of this module in use, see the processwire.com homepage (and many of the inside pages) for the "Latest Forum Post" section in the sidebar. Download at: https://github.com/r...n/MarkupLoadRSS REQUIREMENTS This module requires that your PHP installation have the 'allow_url_fopen' option enabled. By default, it is enabled in PHP. However, some hosts turn it off for security reasons. This module will prevent itself from being installed if your system doesn't have allow_url_fopen. If you run into this problem, let me know as we may be able to find some other way of making it work without too much trouble. INSTALLATION The MarkupLoadRSS module installs in the same way as all PW modules: 1. Copy the MarkupLoadRSS.module file to your /site/modules/ directory. 2. Login to ProcessWire admin, click 'Modules' and 'Check for New Modules'. 3. Click 'Install' next to the Markup Load RSS module. USAGE The MarkupLoadRSS module is used from your template files. Usage is described with these examples: Example #1: Cycling through a feed <?php $rss = $modules->get("MarkupLoadRSS"); $rss->load("http://www.di.net/articles/rss/"); foreach($rss as $item) { echo "<p>"; echo "<a href='{$item->url}'>{$item->title}</a> "; echo $item->date . "<br /> "; echo $item->description; echo "</p>"; } Example #2: Using the built-in rendering <?php $rss = $modules->get("MarkupLoadRSS"); echo $rss->render("http://www.di.net/articles/rss/"); Example #3: Specifying options and using channel titles <?php $rss = $modules->get("MarkupLoadRSS"); $rss->limit = 5; $rss->cache = 0; $rss->maxLength = 255; $rss->dateFormat = 'm/d/Y H:i:s'; $rss->load("http://www.di.net/articles/rss/"); echo "<h2>{$rss->title}</h2>"; echo "<p>{$rss->description}</p>"; echo "<ul>"; foreach($rss as $item) { echo "<li>" . $item->title . "</li>"; } echo "</ul>"; OPTIONS Options MUST be set before calling load() or render(). <?php // specify that you want to load up to 3 items (default = 10) $rss->limit = 3; // set the feed to cache for an hour (default = 120 seconds) // if you want to disable the cache, set it to 0. $rss->cache = 3600; // set the max length of any field, i.e. description (default = 2048) // field values longer than this will be truncated $rss->maxLength = 255; // tell it to strip out any HTML tags (default = true) $rss->stripTags = true; // tell it to encode any entities in the feed (default = true); $rss->encodeEntities = true; // set the date format used for output (use PHP date string) $rss->dateFormat = "Y-m-d g:i a"; See the $options array in the class for more options. You can also customize all output produced by the render() method, though it is probably easier just to foreach() the $rss yourself. But see the module class file and $options array near the top to see how to change the markup that render() produces. MORE DETAILS This module loads the given RSS feed and all data from it. It then populates that data into a WireArray of Page-like objects. All of the fields in the RSS <items> feed are accessible, so you use whatever the feed provides. The most common and expected field names in the RSS channel are: $rss->title $rss->pubDate (or $rss->date) $rss->description (or $rss->body) $rss->link (or $rss->url) $rss->created (unix timestamp of pubDate) The most common and expected field names for each RSS item are: $item->title $item->pubDate (or $item->date) $item->description (or $item->body) $item->link (or $item->url) $item->created (unix timestamp of pubDate) For convenience and consistency, ProcessWire translates some common RSS fields to the PW-equivalent naming style. You can choose to use either the ProcessWire-style name or the traditional RSS name, as shown above. HANDLING ERRORS If an error occurred when loading the feed, the $rss object will have 0 items in it: <?php $rss->load("..."); if(!count($rss)) { error } In addition, the $rss->error property always contains a detailed description of what error occurred: <?php if($rss->error) { echo "<p>{$rss->error}</p>"; } I recommend only checking for or reporting errors when you are developing and testing. On production sites you should skip error checking/testing, as blank output is a clear indication of an error. This module will not throw runtime exceptions so if an error occurs, it's not going to halt the site.
  17. Thanks. I worked out the first approach which works as a quick fix, but it's good to know the second one will work as well, as I think from an OO programming perspective, it's clearer to use the second option as I am effectively setting a page property, just I'm doing it at runtime, and as a non-persisted property.
  18. Works fine for me here with the dev version, but should also work with the master version (IIRC - sorry, it's been a while since I touched this). Tested in PW 3.0.85. Here's my copy pasted PHP code: // both of these work /*namespace Processwire; return wireRenderFile('runtime-markup-wirerender-test'); */ return ProcessWire\wireRenderFile('runtime-markup-wirerender-test'); The above allows you to have your code inside PHP files. This is the pasted PHP option. It is supported in both front- and back-end. It also allows you to use PHP files, but indirectly. It is not to be confused by the other (currently dev) option of directly rendering PHP files (i.e., just stating name of the PHP file and its path. Are you getting any errors? Tracy? In the template file I echo the field's value like so: echo $page->runtime_markup;
  19. You are absolutely right, implementing that forum from scratch is basically implementing stuff in PHP. If there is some interest, I indeed may write an in-depth blog entry, but for now I'll try to make it short (which probably does not work...). Let's start with a quick view on the five templates involved: forum-root well, this is the parent of everything. The template only contains the global welcome text but the associated php file enumerates any contained forum-group and creates the root layout. forum-group just a group around a couple of forums with its own descriptive bodytext forum-forum well, a forum containing the topics. The forum-forum nodes contain an additional "cache" for post and topic counts to provide a massive speedup when rendering forum-root. The counters are flagged with a timestamp, so they are updated on-the-fly only if required. forum-topic this node holds the post-list. In contrast to all other nodes which manage the content only by child-parent-relationship, this one has a page-table on the child node for the only purpose to see the thread also in admin. forum-post basically the post text with automated creation of title and name from current timestamp. Handling topic updates and user notifications was one of the first things implemented due to its expected complexity, but in the end it was rather easy and little efford with the right fields in place. topic-group, -forum and -topic nodes each has a page select field (holding PW user pages) which may be set or cleared by clicking on the grey wall to activate a "forum guard". Whenever there is a change beneath that node, the guard adds the topic to the per-user notification list (placed in the PW user template, which is more complex than usual this implementation). If there are pending notifications an additional button is displayed in the headline next to the user avatar: The user may check active notifications from that button and reading the topic will in turn clear that notification (remove the topic reference in the user's notification-list). Each user may choose to get informed by mail (standard WireMail) for pending notifications (html or text, various intervals, managed by LazyCron). The trick here is, that the user only get informed once per topic until he re-visited the forum to avoid flooding on active topics. Each visit is also recorded per-user to implement the updated-topic functionality. This is basically a topic/forum/group page select with the current timestamp in the PW user, updated topics are flagged with a bright lamp. https://forum.tom-productions.de/?f=test-forum&t=hallo-unglaublicher&p=1 Handling the post content is one of the more interesting and challenging features in this implementation. Mentions, for example, are detected when writing a post (regular @ syntax followed by the user name). This will simply add the post page to the user's notification list so it can be identified during regular processing. But there is more to explain in this screenshot. If someone replies to its own post, both are merged with that "Ergänzung" text beneath the ruler. That additional header is created during runtime from a data-ts field contained in the <hr> tag so it does survive even a later edit. While such an addition pushes the topic's modified timestamp, an edit doesn't. You may also note the phrase "externes Bild" next to an URL. This is a tribute to the european GDPR to not send the user's IP address to external servers without explicit grant. Clicking on that solid shield next to the cite icon will open a popup which has to be acknowledged. You may also notice the colored links in the user's signature, that's another point to avoid clicking on misleading links. If the link text contains the correct target server, its green, otherwise red (changed the signature for that screenshot). The color on the other hand does not qualify the linked content by any means... That's all done during runtime before actually displaying the post content along with replacing the usual emoticon shortcuts (learnt to love preg_replace_callback). Apropos Emoticons: To eliminate copyright issues I'm using regular Unicode emoticons which nicely pass through the PW engine and SQL, so emoticons will look differently depending on platform (Windows7 only shows black and white, for example). Apropos Signature: The signature actually is specified in markdown in an ordinary textarea field so I don't need to fiddle CKEditor into the LoginRegister module. Conversion into HTML is finally done using text formatter Markdown/Parsedown extra before the content has to pass my link and image filter. Well, there's so much more to tell (for example the CKEditor configuration), but that's for a later post... Ah, there is no magic behind the cite feature. It simply encloses the cited post into <blockquote> so the CKEditor opens with that block already filled.
  20. monollonom

    AZILIS

    Hi all, After seing the website featured in the latest Processwire weekly (thank you @teppo !!), I thought it could be nice to post some details here. I have actually made a few websites using Processwire, but it's the first time I'm posting one in the showcase. Backstory I made a first version of this website in end-2017 when I was starting to use Processwire after a friend recommended it to me. I was in charge of the front/back-end, and helped a bit on the design. At the time there was a slideshow of featured projects as the homepage, the project page was the only template with content blocks, and the information pages (about / contact) were specific templates. About the content blocks, I didn't know about the Repeater Matrix module so I kinda implemented my own, having a simple Repeater with a Select Options field defining which fields to display. All in all the website was pretty nice when it came out and I learned a lot in the process, but this year the agency wanted an update to fit their new narrative, so it was a nice opportunity to make some due changes. Back-end Modules I used : Repeater Matrix ProCache Seo Maestro Email Obfuscation Inputfield Chosen Select Color Minimal Fieldset Page Field Edit Links Runtime Only Tracy Debugger (of course!) This new version is all about content flexibility. The information pages now all share the same template, allowing them to create as many as they want. Each visible templates ("home" / "page" / "project") contains a Repeater Matrix field for content blocks, with 15 different types to choose from and options to add variations in the layout. Front-end To answer to the PW Weekly : it is indeed all custom-made except for three external libraries : plyrjs, flickity and lottiejs. I really like sveltejs but I still have to figure out how I could mix it with PW in my process. The animation in the introduction is described by a .json file and displayed as a SVG using Lottie. The transition colors can be changed. The menu order is defined by the manual sorting in the admin... I don't really know what to say here since it's all hand-made, let me know if you have any question! Screenshots Thanks !
  21. Hi @bernhard, We've been running up against the limitations of ProcessWire's native method of handling subfields in selectors. Basically, every subfield in a selector results in a separate query that runs to return all IDs that match the subfield, and then those IDs are used in the where of the final sql query (as opposed to joining the tables and then doing a where on the data all in a single query). This fails at scale because the individual subfield queries start returning so many page Ids that memory is exhausted or MySQL even crashes. There are ways to work around this in some cases by using separate selectors instead of subfields, but it's not terribly elegant. My question is, can we use RockFinder to solve this problem? In this particular use case, we would still want to end up with Pages in the end. I am guessing that using subfields in a RockFinder selector would behave the same way as it does in native PW (I assume RockFinder just gets the final query that PW creates for it--which may have taken multiple queries to construct--and proceeds from there). But if the join function would allow us to limit results based on the values of subfields all in a single query, then that would be golden. At that point all we would want back from RockFinder would be an array of page ids, which we could pass to Pages::getById() to get the pages back. Perhaps a method call for doing this is worth putting into RockFinder? This would be much more efficient than using the callback since it would be one SQL query to get all the pages. Another thing which I mentioned back with RockFinder1 (and implemented locally) is the option of getting a WireArray of WireData objects instead of standard objects or a plain array. This is still way faster than Pages but allows you to use runtime selectors on the results. Anyway, thanks for your work on this and looking forward to your thoughts.
  22. Isn't the string you're seeing in the log from your inputfield, which you said to be setting a string currently? Probably the sane way to handling the data would be that the runtime value is always the image obj. The sanitizeValue method will make sure any other valid (user) input, like the db string format, is converted to the runtime obj. sleepValue und wakeupValue will only handle the string to runtime obj conversion for both directions.
  23. Its not straightforward and sometimes frowned upon . Have a look at this thread. And this one: And this one for changing published date: OK, if you've decided to carry on, first, some quick by the way technical tips. If unsure whether something is a runtime or DB property, I check the API: http://processwire.com/api/ref/page/ For $page->created, it says: That gives me an idea that when setting, I should probably set in the same format (Unix timestamp). If unsure, I can check the code or try to pass it a normal formatted date. You never know, ProcessWire can convert it behind the scenes. I sometimes check the database table of the field. This case, the table is pages. This helps me to check out the schema and if the property is runtime or saved to DB. There they are. They are columns in the pages table. If need to, I also check the table structure, but don't need to in this case. OK, to the code. // CURRENT DATES // timestamps echo 'Created Date: ' . $page->created . '<br>'; echo 'Published Date: ' . $page->published . '<br>'; echo 'Modified Date: ' . $page->modified . '<br><hr>'; // formatted date echo 'Created Date: ' . date('D d M Y H:m', $page->created) . '<br>'; echo 'Published Date: ' . date('D d M Y H:m', $page->published) . '<br>'; echo 'Modified Date: ' . date('D d M Y H:m', $page->modified) . '<br>'; // MODIFY CREATED DATE $page->created = 1425898824;// Monday, 9 March 2015 11:00:24 $page->published = 1426762824;// Thursday, 19 March 2015 11:00:24// will not work; @see links to threads above $page->of(false); #$page->save();// @NOTE: WILL NOT WORK; you need below $page->save(array('quiet' => true));// @NOTE: ONLY WORKS FOR CREATED // MODIFIED CREATED DATE echo '<hr>'; // timestamps echo 'Created Date: ' . $page->created . '<br>'; echo 'Published Date: ' . $page->published . '<br>'; echo 'Modified Date: ' . $page->modified . '<br><hr>'; // formatted dates echo 'Created Date: ' . date('D d M Y H:m', $page->created) . '<br>'; echo 'Published Date: ' . date('D d M Y H:m', $page->published) . '<br>'; echo 'Modified Date: ' . date('D d M Y H:m', $page->modified) . '<br>';
  24. Well, in my opinion, this would just be a workaround for my original requirement. As I said initially, my ideal solution would be to set the status of a page at runtime (e.g., in the ready.php file or with a hook at the right place) and that the page thereafter behaves as if it had had that status from the beginning of the request. But maybe this idea contradicts some general principles of ProcessWire. Maybe the status of a page is supposed to be persistent in the DB and shouldn't be changed at runtime. But then, why do we have methods like $page->addStatus(Page::statusUnpublished); at all? Maybe someone can clarify the purpose of such methods. I am happy to learn
  25. Thanks Rob, got your message and will take a closer look today. Regarding the functions you mentioned: • wakeupValue() converts a file from a basic storage type (typically an array) into it's representation in ProcessWire. Most often this is used to translate the raw value from the DB into the live value for runtime. • sleepValue() does the opposite of wakeupValue() and translates a runtime value back to it's basic type for storage. If you are just dealing with a simple type like an integer or a string that are represented in the database exactly how they are at runtime, then wakeupValue() and sleepValue() don't need to do anything at all (other than return the value they were given). So these functions really only come into play when the field's value has to be stored differently than it would be presented at runtime. This would be the case for anything that is presented as an object at runtime. Since an object can't just be "stored" and still have its components be searchable and sortable in a database, it needs to be translated to/from fields in a DB table. Likewise, if you are sending object field values to/from JSON/XML web services, you probably want that object represented as an array, so that it can be encoded by XML or JSON. • sanitizeValue() is entirely unrelated to the other two functions (though you may see it called in series with them). But it does nothing other than sanitize a value that is assigned to a $page. So lets say that you have a field called 'myfield' and this API call gets executed: $page->myfield = 'my value'; That value gets passed through the sanitizeValue() method for whatever fieldtype is used by 'myfield'. After passing through sanitizeValue() it gets set to the $page. The sanitizeValue() method is just a way to ensure that invalid data doesn't get assigned to the page. So if the fieldtype used by 'myfield' expects it to be a string, then its sanitizeValue() method should ensure that whatever it returns is a string, regardless of what it's given. Or if you want, you can have it throw an exception when it receives invalid data. But here's what a sanitizeValue() method might look like for 'myfield': public function sanitizeValue(Page $page, Field $field, $value) { if(!is_string($value)) $value = (string) $value; return $value; }
×
×
  • Create New...