-
Posts
5,007 -
Joined
-
Days Won
333
Everything posted by Robin S
-
multilingual tags for images and files
Robin S replied to virtualgadjo's topic in Wishlist & Roadmap
I don't know much about multilingual websites, but I think Page Reference fields are multilingual. And Page Reference fields are the most powerful way to implement tags anywhere in PW. Now that have the custom fields for Files/Images feature it seems like this would be a good solution. -
The title field is already optional. You just need to make it non-global by editing the Title field and unchecking the Global checkbox on the Advanced tab. Then you can remove it from any templates where you don't need it. If you want to see the values of other fields (instead of Title) in Page List you can set that on the Advanced tab when editing the template.
-
@ryan, what follows is only about the idea of taking Repeater Matrix in a Bard-like direction for long-form content, as referred to in my earlier post. I don't have an opinion on the "builder" idea because it's not something I or my clients need. Looking at the Bard video you can imagine it as rich text field (i.e. CKEditor or maybe Editor.js) with Repeater Matrix elements distributed through it. You can add new Matrix items and edit them within the rich text interface. Here's a mockup of what a hypothetical "Repeater Matrix Bard" field might look like: But as far as I can see such an interface would be very difficult to implement. You'd have to somehow replicate the Matrix item interface inside CKEditor or Editor.js, maybe as plugins. [Actually, as soon as I made this mockup I suddenly had another idea for how it could be done, but I'll come back to that at the end of this post]. So when I first started thinking about this idea (back when Bard was introduced to Statamic) I wrote that option off as too difficult and turned to working with the existing CKEditor and Repeater Matrix fieldtypes. Of course this was going to involve compromises and the result was never going to be as slick as the Bard interface. My idea was to use placeholders for the Matrix items within the CKEditor field, in the form of CKEditor widgets. Each widget would correspond to a Matrix item, and a Textformatter module would replace the placeholders with rendered Matrix item output when the page is rendered for the front-end. This is easy to do via $matrix_page->render(). First I experimented with keeping the Matrix field visible in Page Edit, with the Matrix field in accordion mode. Hovering a widget placeholder in CKEditor highlighted the Matrix item (to help the user work out which placeholder is linked to which Matrix item) and clicking the widget scrolled to and opened the Matrix item for editing. But this takes the user away from CKEditor and disrupts the writing experience a bit too much. So then I changed to hiding the Matrix field in Page Edit so the user only sees the CKEditor field. When they add or edit a Matrix item a Magnific modal opens where they can work with the fields within the Matrix item. I added a dropdown to the CKEditor toolbar to let users add new Matrix items/widgets within the CKEditor field. This works okay but it's not fantastic - the main dissatisfaction I have is that my widgets are rather basic. This is because I'm no expert when it comes to CKEditor and its widget system. But looking at example widgets in a tutorial it seems that it's possible for them to have richer layouts and items like images (icons?) within them. I'm using the title attribute tooltip to show the text from the Matrix item header, but it would be great if the widget contained an icon corresponding to each Matrix type (sidenote: we really need a larger selection of icons available in the core) and perhaps some of the item content. Maybe the developer could specify code for each Matrix type that would render the HTML of the widget? I fear this is all beyond me but if you're interested maybe you could explore the possibilities of this? Or see if a similar approach would be more easily accomplished in Editor.js. A screencast of the system in action: Because the user doesn't see the Matrix field it would be possible for items to become orphaned there after their corresponding widgets are deleted from the CKEditor field. But it would be good to keep orphaned items for a short while to serve as disaster recovery. So perhaps orphaned Matrix items would be automatically removed after some period of time. Coming back now to the mockup screenshot and an idea of how to achieve it... What if there was a special rich text Matrix type available to be added to any Matrix field? This would consist of a CKEditor field in inline mode (to reduce the distraction of the toolbar) together with (optional) Files and Images fields to allow for linked files and embedded images (edit: it would be good if somehow a single Files field and a single Images field was shared between all rich text items). This matrix type would render differently within the Repeater Matrix inputfield - it wouldn't have a permanently visible header and the Files and Images fields wouldn't be permanently visible either. Instead a special toolbar would appear when the rich text item was hovered (probably at the bottom to avoid clashing with the CKEditor toolbar). This toolbar would include the standard Matrix icons (sort, copy, toggle, delete) and icons that make the Files and Images fields visible for when those need to be accessed. But when nothing is hovered it would render just as the rich text portions appear in my mockup. It would also be nice if the Matrix "add new" links were replaced by a "+" icon that appears when you hover between existing Matrix items, like in Bard. That would reduce some clutter in the inputfield and allow new items to be inserted in whatever position is wanted. This approach would not be quite as nice as a single rich text field containing Matrix items. Because I think the concept of multiple text fragments is not what users imagine for a long-form article. And it would result in more pages behind the scenes, although that probably isn't a big problem. But it seems like it might be relatively simple solution to the Bard idea.
-
I didn't know about adding custom links here, thanks. ? It's somewhat limited though because it can't handle URL segments or GET variables which are widely used in the admin, so you can't link to a module config for instance. My preference would be for a separate panel just for shortcut links, internal and external. The PageListSelect works well for pages but I think inputing URLs would be better because then it's one interface for entering any kind of link. Example: Just thinking out loud here, but when a link is added or changed it would be cool if... The root URL is removed from internal links so link becomes relative. If a URL is submitted without a label... For internal URLs, $pages->getByPath($url) is used, and if a Page object is returned the page title is used as the link label. For external URLs and internal URLs for which getByPath($url) returns a NullPage, attempt to get the title element using DomDocument and use it as the link label. libxml_use_internal_errors(true); $dom = new \DOMDocument(); $dom->loadHTMLFile($url); $list = $dom->getElementsByTagName('title'); $label = $list->length ? $list->item(0)->textContent : $url; These latter features aren't crucial, they're just so we have the option of being lazy and adding a URL only. ?
-
It wouldn't be a bad thing to have a filter box too, although I don't think I'm familiar enough with the input labels to use that much myself. The Perfmon module looks good - I hadn't seen it before. Honestly these features aren't something I need on a typical project - I just thought the timeline looked cool. If I needed to focus in on performance I would try Perfmon, and I have Profiler Pro but haven't actually explored its features yet. I do have another idea/request though... What do you think about adding a Shortcuts panel? This would be for custom internal or external links that a user finds they are needing to visit regularly during development. For instance, I often need to visit the LoginRegisterPro config screen during development. And you could add links to various external API documentation pages that you want to jump to quickly. Sure, you could use your browser bookmarks but mine are already an out-of-control mess, and by having the links in a Tracy panel it would keep them nicely connected to a project. I'm imagining an interface that lets you enter a label and URL for each shortcut - a textarea would do, or you could get fancy with some kind of repeater-like interface. It would be good if absolute internal links were converted to relative links (i.e. strip out the site root from the URL) so the links keep working if the root URL changes.
-
From an article @szabesz linked to earlier... No idea how difficult it would be to show a cool timeline like that, and probably something that would be better done in the Tracy core. But it looks nifty!
-
@adrian, how about this: By default all the config fields are displayed so you can use Ctrl+F, but when you click a quick link it hides all the config sections apart from the active one. This removes the clutter around the section the user wants to focus in on. Here is the CSS and JS if you want to play with it: #tracy-quick-links .InputfieldContent ul { list-style-type: none; padding: 0; overflow: hidden; } #tracy-quick-links .InputfieldContent ul li { float: left; padding: 0 5px 5px 0; } #tracy-quick-links .InputfieldContent ul li a { background: #e3e9ef; color: #333; display: block; padding: 1px 10px; border-radius: 3px; } #tracy-quick-links .InputfieldContent ul li a:hover { text-decoration: none; background: #d9e1ea; } #tracy-quick-links .InputfieldContent ul li a.active { background: #e83561; color: #fff; } $(document).ready(function() { var $quick_links = $('#tracy-quick-links'); var $config_fields = $quick_links.nextUntil('#wrap_uninstall'); $quick_links.on('click', 'a', function(event) { event.preventDefault(); if($(this).hasClass('active')) { $(this).removeClass('active'); $config_fields.show(); } else { $quick_links.find('a').removeClass('active'); $(this).addClass('active'); $config_fields.hide(); $($(this).attr('href')).show(); } }); });
-
Hi @adrian, You already kindly added some quick links to the Tracy config at my request, but I still find the config interface quite overwhelming. What do you think about implementing a tabbed interface so it's easier to focus on a subset of the config fields? I've posted a demo module that might be helpful: Depending on how you think it's best to divide up the config there would probably be more tabs than could fit in one row. Currently I don't think AdminThemeUikit handles this all that well... ...but seeing as Ryan has recently been working on AdminThemeUikit it might be timely to see if improvements can be made. I'm not sure but probably it would be good if the inactive tabs had some definition of their edge, maybe a pale grey background and white border for separation between the tabs. I'll have a play around with that. Edit: the visual metaphor of tabs is always going to break down a bit when you have more than one row of tabs, but I think the below would be an improvement on the current styling. Editing on tablets and phones is going to become more and more common and the PW admin should cater to these narrower screen widths.
-
If your module has a lot of config fields you might want to divide them into groups inside a tabbed interface. Here is a demonstration module showing how this can be done. https://github.com/Toutouwai/ModuleConfigTabs Thanks to @kixe for providing my starting point in this forum topic.
-
Hi Adrian, The expand and collapse icons in the Dumps panel are not clickable. Probably a z-index issue.
-
[SOLVED] $input->urlSegmentLast dont return the last URL segment
Robin S replied to dfile's topic in API & Templates
It was fixed after 3.0.165 master was released: https://github.com/processwire/processwire-issues/issues/1247 You can upgrade to the latest dev release to get the fix. -
Problem with a repeater field after API data insert
Robin S replied to manlio's topic in General Support
This might work: foreach($users as $u) { $u->of(false); $u->save('user_payment'); } -
Large number of orphaned image files on pages with no images
Robin S replied to Kiwi Chris's topic in General Support
Part of the process that happens when you set a Files or Images field value is the copying of the file to the page's folder in /site/assets/files/. The solution is not to set the Pageimage to the field. Just use some variable name like... $header_image = getHeaderImage($page); ...or if you want it stored on the Page object then invent some property name that isn't a field name, e.g. $page->the_header_image = getHeaderImage($page); -
Below are the style overrides that I apply, mostly just spacing changes and fixes for things that looked off to me. There might be one or two things in there that don't make sense out of context because I'm also loading some custom JS to change the icon of the "user" menu and have the primary link be to the site frontend rather than the user profile. The problem is that if you create the minimal module that extends AdminThemeUikit (i.e. just the class declaration and the getModuleInfo method) then what you want to see is everything displaying as per AdminThemeUikit. Then you would add custom CSS/JS and override any AdminThemeUikit/AdminThemeFramework methods as needed. But what you actually see is this: If that is expected then it would be helpful to have some documentation or a blog post about how to go about extending AdminThemeUikit, or what file structure is needed for a full custom admin theme if anybody is game enough to try that. The only hookable methods that I can see are AdminThemeUikit:renderBreadcrumbs and AdminThemeFramework::getUserNavArray. So for the thing I mentioned (manipulating menus) you can only customise the "user" menu. It's not possible to dynamically add items to the Pages, Setup, Modules or Access menus without resorting to JS hacks like AdminOnSteroids does. And on the topic of the admin menus, the caching is a bit of a pain and doesn't measurably improve performance according to my tests: https://github.com/processwire/processwire-requests/issues/268#issuecomment-464200684 Another menu related request: https://github.com/processwire/processwire-requests/issues/189 What would be great is if for each major part of the admin theme layout (e.g. header, menus, top of content, bottom of content, footer) there was some hookable method so it was possible to inject custom markup at those points.
-
Using concrete dates instead of relative ones in admin
Robin S replied to creativejay's topic in General Support
Depending on how much mixing of relative and absolute dates occur on a single page, it might be possible to avoid those scenarios by excluding specific processes and/or URL segments, e.g. if($page->process != 'ProcessPageEdit') { $wire->addHookBefore('WireDateTime::relativeTimeStr', function(HookEvent $event) { $timestamp = $event->arguments(0); // If given a date string, convert it to a timestamp if(!ctype_digit("$timestamp")) $timestamp = strtotime($timestamp); $event->replace = true; // Set your preferred date format below $event->return = date('Y-m-d H:i:s', $timestamp); }); } -
A dedicated field for height is definitely the way to go, but just wanted to add that for the example titles you gave, the height follows the noun and if that applied consistently then potentially you could include the noun in the search text:
-
Using concrete dates instead of relative ones in admin
Robin S replied to creativejay's topic in General Support
You can use a hook to replace all relative time strings in admin with a specific date format. Add the following to /site/templates/admin.php, at the top after the namespace declaration: $wire->addHookBefore('WireDateTime::relativeTimeStr', function(HookEvent $event) { $timestamp = $event->arguments(0); // If given a date string, convert it to a timestamp if(!ctype_digit("$timestamp")) $timestamp = strtotime($timestamp); $event->replace = true; // Set your preferred date format below $event->return = date('Y-m-d H:i:s', $timestamp); }); -
Recurring dates / calendar module A big +1 from me for this. A lot of sites need this kind of functionality. The key thing is solid RRULE support in a user-friendly interface. It's really common to have events that occur on a regular schedule (e.g. the first Tuesday of the month for now until eternity) but then occasionally have exceptions where the event is moved to a different day or cancelled for a particular date. The Recurme module had the right general idea but if you take a look at the source code you can see why it's not really scalable and needs a lot of tidying. A robust calendar module is not a simple thing so it would be great to have something that's built to the standard of Ryan's other Pro modules. Flexible content I find that Repeater Matrix is fine for when the content is divided into discrete conceptual and visual blocks on the frontend. It's pretty easy to make the mental connection between "conceptual/visual block on the frontend" and "Repeater Matrix item in the backend". Where it's not so good is when you have a long piece of text that is interspersed with different pieces of other content, e.g. text - image - text - graph - text - pullquote - text. In this scenario the editor/author wants to think of the text as one conceptual unit. Breaking the text across multiple Repeater Matrix items feels wrong, and it's difficult to locate and move paragraphs between the different blocks. For this scenario (which is pretty common now - think of Medium articles or other longform articles containing rich content) the Statamic Bard fieldtype looks like it nails the solution pretty well. The user wants to see a single flow of text with elements floating inside the text that represent the other pieces of content. These floating elements should reveal the content they contain (or at least the type of content) so that the user can understand what is what, but perhaps be edited outside of the text editing interface where that is more practical, e.g. click an element to edit it in a modal. I have actually made a couple of different experimental modules that expand Repeater Matrix in this direction but haven't found a fully satisfactory solution yet. Admin theme I'm pretty happy with AdminThemeUikit and don't think it looks dated. I've said before that there's too much padding between and around elements and the main page heading is way too huge (maybe this is where the "cartoonish" criticism comes from), but these things are very simple to fix with custom CSS overrides. I wouldn't want to see the admin styling change every year and I can't relate to the desire to be endlessly changing the admin to keep up with the latest fads. The admin is a place you go to do work, not to see pretty things. It should be plain and utilitarian, which AdminThemeUikit already is. Having said that, a couple of ideas that would make it easier for those who want to tweak the admin: 1. Maybe there could be more config fields in AdminThemeUikit to let people adjust things like spacing and font size without having to add their own stylesheet to the admin. 2. It would be pretty good if developers could more easily create modules that extend AdminThemeUikit so if they want a customised admin theme they only have to override certain specific methods rather than completely duplicating the module. Right now if you do... class AdminThemeFoo extends AdminThemeUikit ...the admin experience completely breaks so it's not currently a good foundation to build on. And it would be good if there were more hookable methods in AdminThemeUikit so that it becomes possible to manipulate the main menus for instance.
- 135 replies
-
- 10
-
-
-
Thanks, I did notice this when it was released and it looks like a nice module. It's only for single images though, and I'd still like to see image and file reference fieldtypes in the core. For some situations such fieldtypes are needed (e.g. avoiding duplication of images/files and associated data/descriptions when the asset is used on multiple pages, roles that may select files/images but not upload new files/images, scenarios where images/files need to be centrally managed, etc) and the fact that the core doesn't cater to this feels to me like a gap that should be filled.
-
Hear, hear! ? One place to find ready answers to this question is the requests repo: https://github.com/processwire/processwire-requests/issues That repo currently has 289 ideas for improvements, and it would be fantastic if you can find the time to do a quick first pass through the repo and add any comments or questions to the requests, and indicate which ideas you think are the most promising for developing this year. At the top of my wishlist is an Image Reference fieldtype: https://github.com/processwire/processwire-requests/issues/207 I'm imagining something that works much like a Page Reference fieldtype, with various options for defining which images are selectable and some elegant way of selecting from a large number of images (maybe a modal interface similar to Lister that lets you filter and select images for adding to the field).
- 135 replies
-
- 16
-
-
Could you please add the steps you are following to reproduce the problem? I'm trying to reproduce it but am not able to. What I'm doing is: Template settings have slashUrls set to false (0). I upload an image to a "single" image field and save the page. I delete the uploaded image file from /site/assets/files/1234/ I check the filesize of the PageImage to confirm that PW can not locate the file. I call the size() method on the PageImage with the now missing file. I tried with both the GD and ImageMagick sizer engines. I check the slashUrls setting of the template. So far I don't experience any changes to the template settings of the page.
-
v0.3.0 released, which adds dropdowns to Edit Role, Edit Permission, Edit Language, and when viewing a log file at Setup > Logs. @flydev ??, this version should also fix the problem you reported above.
- 79 replies
-
- 5
-
-
-
- breadcrumbs
- admin
-
(and 2 more)
Tagged with:
-
Weekly update: Combo now released! 18 Dec 2020
Robin S replied to ryan's topic in News & Announcements
Awesome, thanks @ryan!! I'm just about to go away on holiday but looking forward to working with Combo when I get back. I think it would be cool to have a visualisation of the subfield placement in Edit Template, and when subfields are moved in the visualisation it populates that custom placement field in template context behind the scenes. But that's just an icing on the cake thing, and maybe a better fit for a third-party module. Thanks again for Combo - it's a pretty revolutionary addition to the PW toolbox I reckon. ? -
Weekly update: Combo now released! 18 Dec 2020
Robin S replied to ryan's topic in News & Announcements
A quick proof-of-concept using the API only... Before (Combo subfields grouped together inside fieldset): After (Combo subfields interspersed with other fields): Hooks: // Reposition Combo subfield inputfields in Page Edit $wire->addHookAfter('ProcessPageEdit::buildFormContent', function(HookEvent $event) { /** @var InputfieldWrapper $wrapper */ $wrapper = $event->return; // Imagine this is sort order data coming from some config field $insert_after = [ 'test_combo_colours' => 'image', 'test_combo_description' => 'file', 'test_combo_decimal' => 'test_repeater', ]; // Get the Combo subfield inputfields $combo = $wrapper->getChildByName('test_combo'); $combo_inputs = $combo->getInputfields(); // Reposition them foreach($insert_after as $combo_subfield_name => $normal_field_name) { $combo_subfield = $combo_inputs->getChildByName($combo_subfield_name); $normal_field = $wrapper->getChildByName($normal_field_name); $wrapper->insertAfter($combo_subfield, $normal_field); } // Cannot just remove the Combo inputfield or else subfield value changes don't get processed // So instead a separate hook is used to replace the rendered output of the Combo inputfield // $wrapper->remove($combo); $event->return = $wrapper; }); // Don't render anything for the Combo inputfield $wire->addHookBefore('InputfieldCombo::render', function(HookEvent $event) { /** @var InputfieldCombo $inputfield */ $inputfield = $event->object; $field = $inputfield->hasField; if($field->name === 'test_combo') { $inputfield->wrapAttr('style', 'display:none'); $event->replace = true; }; });- 26 replies
-
- 10
-