Jump to content

DrQuincy

Members
  • Posts

    248
  • Joined

  • Last visited

  • Days Won

    1

Everything posted by DrQuincy

  1. In case anyone is interested this will remove absolute links on all specified HTML (CKEditor Textarea) fields using the current host (HTTP and HTTPS) and is case-insensitive. Based on @Robin S’s code. $wire->addHookAfter('Pages::saveReady', function(HookEvent $event) { $htmlFields = [ // NOTE: Set your fields here 'html1', 'html2', ]; $host = $_SERVER['HTTP_HOST']; $find = [ 'href="http://' . $host . '/', 'href="https://' . $host . '/', ]; $page = $event->arguments(0); foreach ($htmlFields as $htmlField) { if ($page->$htmlField !== null) { $numChanged = 0; foreach ($find as $f) { $numChanged += mb_substr_count(mb_strtolower($page->$htmlField), $f); $page->$htmlField = str_ireplace($f, 'href="/', $page->$htmlField); } if ($numChanged > 0) { $this->message($numChanged . ' ' . $host . ' link(s) converted to relative links for field “' . $htmlField . '”'); } } } });
  2. Oooh, interesting, thanks. I'll give it a look. ? Is this safe to use in production do you know? I couldn't find it on processwire.com where it gives this status. I know soma is a big contributor here so I would imagine it's decent!
  3. I've looked at the multi-lingual template that comes with PW and not sure this can do what I'm after. Imagine a suite of sister sites: same templates and fields but different content and (slightly different) CSS. Is it possible to have a single PW install that hosts multiple sites, each with a different HTTP host. When you add a field or template it is global in the sense that it is available to all domains. However, the actual page entries in the database are different and are loaded based on the HTTP host. E.g. johnsreallycheapcarinsurance.com and johnsreallycheaphomeinsurance.com are on the same server, same PW install and they have a template called services and a repeater called serviceList. I can create a service page on each and they will automatically use the same template file and repeater field but will have different content. johnsreallycheapcarinsurance.com/services/ johnsreallycheaphomeinsurance.com/services/ So they would use the same HTML template and repeater but would have different content. Is this easy/possible with PW without having to maintain more than one install? It's kind of like a tree partition based on the domain. Thanks.
  4. Thanks @wbmnfktr I think the Markup/HTML option refers to the where internal links go to rather than the format. Thanks @Robin S. I do often add that in the notes but it does seem to confuse some users — of they just don't read it. I like your hook idea though; that could be very effective.
  5. Is there any way in a CKEditor field to have links to the current host automatically converted to root relative links? E.g. I'm on domain.com and I add this code in source: <a href="https://www.domain.com/foo">Foo</a> And on save or in the front end it converts it to: <a href="/foo">Foo</a> Any other links would stay as is. PW seems to be good at using root relative links (e.g. if you select a page from the link CKEditor dialog) but wondered if this is possible without having to do a find/replace in the database. I'm thinking of instances where you move from development to product and end up absolute links to the development domain.
  6. For anyone that is interested in doing the same this seems to have worked. Place this in admin.php, before the controller.php line: $config->styles->add('/assets/css/custom.css'); And then add this in your new custom.css file: form#selected_image_settings p#wrap_info span#action_icons span { display: none; } form#selected_image_settings p#wrap_info span#action_icons span#description_action { display: block; } span#selected_image_pixels, span#selected_image_checkboxes { display: none; } Now you just get the image description button. Make sure you check the Skip width attributes on image tags in the Page Edit Image config or set width and height to auto in your main site CSS. I will test it out a bit more but seems to be working fine for now.
  7. @Zeka Interesting, thanks! I think if I can hide the parts I obscured in red that would do it. Is it easy to add custom CSS to the back-end?
  8. I can see in the Page Edit Image config there is an option to stop Skip width attributes on image tags but although it doesn't set width="" on inserted images it does still allow the size to be set in the dialog. Also, if you resize it it creates a new image on the server: I basically don't want any image resizing doing and no variations created. So what I want ideally is these options hiding: I just want it as simple as possible and prefer to handle sizing outside of the editor (the Images field already uses client-size resizing). Is this possible?
  9. Thanks for your help. Because we may end up with a lot of posts I am creating a JSON file in a hook (based on @MoritzLost's example) so there is almost no overhead on the front-end. $wire->addHookAfter('Pages::saved', function(HookEvent $event) { $page = $event->arguments(0); if ($page->template == 'news-item') { $pages = wire('pages')->find('template=news-item'); $years = []; foreach ($pages as $p) { $year = wire('datetime')->date('Y', $p->getUnformatted('newsDate')); if ($year !== null) { $years[$year] = isset($years[$year]) === false ? 1 : $years[$year] + 1; } } file_put_contents('json/news-years.json', json_encode($years, JSON_PRETTY_PRINT)); } }); Thanks. ?
  10. Thanks very much for your example, I'll give it a go tomorrow and let you know. ?
  11. I may have missed it in the docs but is there an easy and performant way to count pages that have a date field by year. So, let's say you have a news-item template with a dateFiled field that is of Datetime type. I would like to return something like this: 2020 => 17, 2019 => 46 ... Where the values are year and count respectively. So basically something like this in MySQL by in PW selectors (ideally without having to use raw database queries): SELECT YEAR(`dateFiled`) as `year`, COUNT(YEAR(`dateFiled`)) AS `count` FROM `news` GROUP BY YEAR(`dateFiled`); Thanks!
  12. The title says it all really. When using $sanitizer line() and text() seem the same and lines() and textarea() respectively. I.e. strip_tags() and then if line() or text() remove line returns also. What are the differences? Thanks.
  13. Ah yes, that explains it. It says: I can't help thinking just escaping the string rather than filtering things out (as you would do with standard SQL query) makes more sense.
  14. Aha, I knew there must've been a simpler solution, thanks! I don't know how I missed the whitelist option. After running a few tests, it seems though basically so long as your selector doesn't contain double quotes you can wrap it in double quotes and it will accept anything. And even then you can escape the double quote with a backslash. $selector = '"This is a \"valid\" selector string \'^%$!"'; // This works as is Is there an API function to prepare a string in this way? Unless I'm missing something wouldn't a simpler solution be to have an escapeSelectorValue() type function that adds " to the beginning and the end and escapes double quotes? I'm not being critical, just trying to understand the rationale behind the API. Thanks!
  15. I have thought about this and I think if this is the case there are a few options available: Call wire('sanitizer')->selectorValue() via a hook on save or in the template Limit the characters with regex in the text input disallowing the above Have an extra field that stores the unfiltered text and then have a hidden field that stores a filtered version (managed via hooks); show the unfiltered version in the front end but search via the filtered hidden one (this would mean, using my example, '100' and '$100' are the same when searching) If there aren't going to be loads of options use some kind of enumeration (1=$100, 2=$200) via another template, select options, etc and search the number instead of the value If you are using FULLTEXT search I think this is irrelevant as it ignores these characters anyway (unless using BOOLEAN MODE, does PW support this?). Can someone just confirm though that PW does not support exact match searching with the following? "\\0", "\\", "`", "|", '=', '*', '%', '~', '^', '$', '#', '<', '>', '[', ']', '{', '}', "\r", "\n", "\t" I guess I am thinking about edge cases here as unusually filtered values are simple and anything more complex would be FULLTEXT. Thanks.
  16. Looking at the source and the docs it seems like you can't escape special characters and the following aren't allowed: "\\0", "\\", "`", "|", '=', '*', '%', '~', '^', '$', '#', '<', '>', '[', ']', '{', '}', "\r", "\n", "\t" I guess it doesn't matter so much in a natural language search where these kinds of things are filtered out anyway but where you are finding pages using field=value selectors this could trip you up. Is there a built in way to filter these characters out of a field when you save it so you know when you use exact match selectors on them it will be reliable? E.g. product page with field 'bid' with a value '$100'. I run pages()->find('template=product, bid=' . wire('sanitizer')->selectorValue('$100')). This will fail to find my product won't it as it will looking for ' 100'' not '$100'. I know in the real world you probably wouldn't store the '$' but I am just using this as an example. Or do you just assume that any exact match fields should be more predictable values (e.g. numbers, preset categories) and that anything that allows special characters would only ever be searched by a FULLTEXT index? Thanks.
  17. This might be a silly question but wire('sanitizer')->selectorValue() seems to remove characters like ^ and = rather than escape them. Does that mean you cannot, for example, use pages()->get() to match a field that contains any of these characters? Or is there an escape function I'm missing? I don't actually need (yet) to but I wondered if this was a limitation. If so, what characters are/aren't allowed? E.g. can you can only use a-z-Z0-9'"-_? Thanks. ?
  18. A few questions please: If you want full control over the rendered HTML how does it work? Does conditional fields hiding still work via CSS classes? (E.g. if you select x from a drop down field y shows) How effective is the spam prevention if you use this method? Is it easy enough to force the form to render with JavaScript and add a time delay (e.g. the form must've loaded rendered at last 2 seconds ago to pass validation)? If you render the front-end HTML yourself does it still do client-side validation? Does it handle all server-side validation? Can you set the from name and email headers for any emails sent so they are different to the reply to ones? Can you easily hook in custom PHP code on the back end for a) validation and b) processing the form if successful? Thanks.
  19. This is great. I have just added .trim() so that it picks up on href=" javascript:alert('');" too. if (element.attributes.href.trim().substring(0, 11).toLowerCase() === 'javascript:') { Thanks again. ?
  20. Fantastic, thanks to you both. This community is excellent. I will look at those plugins but like @MortizLost I favour the KISS approach. And the important point is external tools can not only be more specialist you are always evaluating the final complete HTML document as opposed to whatever the CMS can do. I find in PW, for example, I will have blocks of includes that pull in a list of content from elsewhere in the site tree (such as a list of team members or featured case studies) but anything Yoast-type would have no way of knowing this as the template decides it. Yes, it could pull the HTML via AJAX based on the page's path but this is overkill, in my opinion. Also, these tools make help you pick up on things you've missed but they can't evaluate anything within the context of a wider SEO strategy.
  21. Thanks, I'll give it a go when I am in the office later! Do you think it is odd it allows this by default but disallows it in the link dialog? Is there a reason for it or is it an oversight?
  22. I haven't used WordPress in a long time, I never liked it really for reasons I won't bother going into. One thing that comes up from time to time, not just for PW site but in general, is something like “Will there be something similar to Yoast in my new site?” As a default in PW I add a SEO fieldset with optional meta title, description and H1 (title property from PW is used for meta title and h1 if these fields are not set) with some simple guidelines in the notes on how to fill them out. I understand Yoast has some additional tools that advise on the actual body content (word count, paragraph length, etc). Obviously PW doesn't have this. To be honest, I have always thought things like that are really for making poor SEO become mediocre and they can't do the job of a human and create excellent SEO. Also one of the things I love about PW is that I can let clients build pages on a modular basis (using repeater matrices) as opposed to a single body HTML field and so I do not even know that such tools could effectively evaluate such content since it is assembled dynamically. I have been familiar with SEO since before it was a term and have worked with a lot of pro SEOs and none of them have ever been bothered about having something like Yoast so long as the fields I mentioned above are editable. I may be wrong but Yoast seems to appeal more to those less familiar to SEO. No offence is intended if you are a pro SEO and use Yoast. ? What are your thoughts on this?
  23. I use CKeditor 4, the same as PW, in other projects and have noticed it allows <a href="javascript:alert(document.cookie)">. Does anyone know how I can use config to disallow any hrefs that start with javascript:? It's fine in PW as HTML Purifier seems to catch it but I wondered for other projects. There is an option config.linkJavaScriptLinksAllowed but it only applies to the link dialog. I'm sure it must be doable with regex in config.allowedContent but I'm drawing a blank. Thanks.
×
×
  • Create New...