Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/31/2020 in all areas

  1. We’ve got several updates on the dev branch this week, but I want to finish one more of them before bumping the version to 3.0.150, so will likely do that next week. The biggest change this week is the addition of a new core class called FieldsTableTools. This will be used internally by the $fields API variable for manipulating field table schema in the database, and its methods are accessed from $fields->tableTools(); Though this is one you probably won't be using from the API unless developing Fieldtype modules, so if you just want to know what the benefits are, feel free to skip to the last two paragraphs. Initially these methods are primarily focused on managing unique indexes for fields, though will expand to manage other schema manipulations as well. An example of its utility is also included in this week’s commits—our email fields (FieldtypeEmail) now have the ability to enforce uniqueness at the DB level. If you edit an email field (Setup > Fields > email) and click on the Advanced tab, there’s now a checkbox there to enforce unique values, ensuring that a given email address cannot appear more than once (i.e. not appear on more than one page). The same ability will be added to text and integer fields (FieldtypeText and FieldtypeInteger) as well, but we’re starting with the email field because it’s needed for an update hopefully wrapping up next week: the optional ability to login to the admin with your email address. Having a unique index on a DB column is actually a pretty simple thing, but as it turns out, it takes a lot of code to support the ability in an existing installation. That’s because we have it as something you can toggle on and off (on that Advanced tab), and when you toggle ON a unique index, there can’t be any duplicate values in the existing data, or the index will fail to apply. So there’s a lot of supporting code in FieldsTableTools to do things like detect and warn about duplicate values, delete empty values before adding the index, identify when the index is present without querying the table, reporting error conditions in a manner that understandable and recoverable, as well as the actual schema manipulations that add or remove the index. I realize this sounds a bit technical (and that's partly why I'm not putting this in a more formal blog post), but I think most developers will at some point find it very useful in building sites and applications. Not only will it enable us to safely support login-by-email in the admin (coming next), but it’ll be useful in any situation where you need to prevent a value from repeating. Whether that is in preventing double bookings for a date, location, seat, etc., or preventing any kind of redundancy like post titles, author names, product titles, phone numbers, or codes (UPC, ISBN, ASINs, EIN, SSN, etc.), this feature can come in handy. And supporting it at the DB level is a lot more solid than supporting it at the code level. Right now it’s just supported in email fields, but all of the logic has been delegated to the newly added class so that we can easily support it in any other fields (with text and integer fields coming next). Following that, the $fields->tableTools(); will also be gaining methods for modifying other types of field schema. For instance, rather than just supporting the INT column type for integer fields, wouldn't it be nice to go to Setup > Fields > [some integer field] and select both unsigned and signed integers of different types: TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT, for any new or existing integer field? MySQL also offers a similar array of size variations for other types that would be useful in our text and textarea fields, among others. So you'll be continuing to see ProcessWire offer more options for existing FIeldtypes in future core versions, enabling you to more efficiently store and manage content in PW. But of course we'll do it in a way that keeps it simple, ensuring that you don't have to think about these things unless/until you want or need them.
    12 points
  2. ... and everything went silky-smooth. I finally got around to update a small portfolio site from PW 2.3 straight to latest dev. I spent roughly one hour, tested everything, and hey: no major hassles. I updated the few modules I used (and installed some new ones like Tracy or AoS), updated PHP as well, and that was more or less it. Imagine having such an un-touched WP, Typo3 or MODX site, and updating straight to the latest version... What a nightmare. That is - if they would actually still run that long ? I actually expected it to go as smooth as it did, but I'm always surprised and in awe again when I do such a big update. Thank you ProcessWire.
    11 points
  3. Hi, With the deprecation of Instagram's API and therefore the end of the Instagram Feed module, I've developed a replacement module which uses the Instagram Basic Display API: https://github.com/nbcommunication/InstagramBasicDisplayApi To use this module you'll need: ProcessWire >= 2.7 A Facebook Developer account Access to the Instagram user account you wish to use Prior to installation, you'll need to create a Facebook app. The app you will create uses the User Token Generator for authentication - it does not need to be submitted for App Review (and therefore stays in Development mode). The README contains full instructions on how to create and set up the app and also how to use the module. The primary reason for this module's development was to retain functionality on existing websites that use the Instagram Feed module. To assist with upgrading, this module replicates some methods provided by Instagram Feed. I've already upgraded a couple of sites and it was quick and painless ? Cheers, Chris
    4 points
  4. Here's a small new module that adds a "Manage tags" button to the template list, just like the field list already has. Easily add, remove and change tags for your templates. https://github.com/BitPoet/TemplateTagsEditList
    4 points
  5. This is an update about how it's been running blog sites using ProcessWire. I hope it's OK for me to post in this category even though I've already showcased my sites awhile back. I thought it would be helpful for people to get a feel for what it's like to use ProcessWire on an ongoing basis for blogging. Often people talk about the development of a site, but it's not quite as often that we hear about the ongoing running of a PW site and how the PW API influences that, which is what I'll cover here. As background, we at The GrayFly Group own and run the blogs goodkidsclothes.com and flipfall.com. The development of these PW sites has been covered in a showcase thread for GoodKidsClothes and another for FlipFall. Here are some of the unique experiences I've had running these two sites. "Running" covers everything from coding and making modifications to the templates, to writing our articles, to interacting with ad partners or with others seeking us out for something related to one of those sites. So this is a different experience from agencies who develop for others; we develop for ourselves. As background, the main traffic to the websites comes from organic search results. Income from sites is from affiliate marketing and advertisements. GoodKidsClothes PW experience: "to think it is to do it." For GoodKidsClothes.com, one of the things we noticed was that if we could think it, we could do it, thanks to the easy-to-use PW API. The need for a change Here is a concrete example of what I mean: we noticed that many people would enter the site on an older article (e.g. via a search result). However, we continually put out a lot of time-sensitive information, e.g. a style guide, a piece of news relating to a change in a children's clothing company, etc. I didn't want people to miss out on this, yet many were, because after reading their entry page, they'd leave. They had no idea (unless they clicked on the link to home page) that there was another article that could be of value to them. All too often, by the time people learned about that new article via search results, they'd be too late for the news to be relevant - in fact, it wouldn't even be the newest article anymore by that point. The solution So, using the PW API, we modified the article template so that if someone was reading any article that was not the most recent article, then at the end of what they're reading, they'd see a small section highlighting the most recent article. Here is a screenshot: As you can see above, our newest article is highlighted immediately below the article they're reading, unless of course they are already reading the newest article. In the case shown above, the newest article (recipe-related) did not happen to be time-sensitive, but in most cases that article would be time-sensitive, so that's why we made this change. To make the change we simply used the PW API to query what the latest article was and store its identity in a variable - those sorts of queries we set up in _init.php. Then we modified the article template such that if the current page was not the latest article, to include the featured box that you see above. Another need for a change You'll also notice links in boxes above and below where the featured article box is. These are ads (they blend OK right?!) These ads brought another problem to our attention: we'd put the ads blocks on all articles equally. However, in the case of the most recent article, often the most recent article would usually have a time-sensitive offer or some other call to action e.g. signing up for our newsletter (well, not in the case of the recipe article above, but in most cases the latest article would have something we prefer the reader to do). We didn't then want our readers to get distracted by the ads and either leave the site, or click on an ad and click away from the site, instead of doing whatever the call to action is. The solution Again using the ProcessWire API, we modified the "article" template so that there was conditional logic on the ads: if the current page is not the latest article, include the ad code (otherwise no ads). This mean no ads were seen on the most recent article, allowing for less distractions to the reader on time-sensitive articles and more likelihood of them following through on the call to action. Conclusion for GoodKidsClothes We were able to make all these changes within minutes of thinking of them! In-house, without a ton of knowledge of programming, thanks to the awesome ProcessWire API. We actually made all those changes live, i.e. going in there and making changes to the code of the site as its running live. Yes, we had backups of the entire site and we always first save a copy of the template file under a different name (usually prefixing it with OLD_ ) before modifying the live version. This is how helpful ProcessWire is. We can make changes that benefit our site and make them in-house as we think of them. If this was done under some other CMS, we would be unable to make those changes without either a) hiring a developer or b) training up in whatever the other CMS is to make the changes in-house. Either way, it would take considerably more time to do anything. So, despite not having a formal programming background, we now have a very "nimble" site that we can adapt as needed to changes that we desire, within minutes of thinking of the change we need, with only needing to know a little PHP, html, and CSS, just the very basics, and looking up the PW API. FlipFall PW experience: "the answer is yes." In the case of FlipFall, there have been times when a potential ad partner asks a question like "can you put different ads on different categories?" or other things. Sometimes they are questions I ask myself of the website "Can we do A/B testing of different ads; i.e. show a certain ad block 50% of the time totally randomly and another ad block the other 50% of the time?" "How about ads from this company some of the time and a different company other times?" The answer is always "yes." Coming from other CMS's (that I used but did not program with) I used to brace myself a bit if I saw an email that asked "Can you....?" but now thanks to ProcessWire I don't have that bracing reaction any more. So long as I can think of a way to do it (and so far I always have, thanks to the PW API), I can say "Yes we can." More to the point, I can actually say "Yes, we can make those changes in-house within [whatever brief timeframe I think it will be]" instead of having to be vague about timeframes because of needing a developer. So I no longer worry about "Can you ...?" questions because the answer is yes. Overall conclusions ProcessWire is a superb CMS for those who own and run a site. The PW API makes it easy to make changes to the look and functionality of the site as needed. Such modifications wouldn't easily be possible on alternative CMS's that are heavily "theme-based".
    3 points
  6. This warning relative to search copabilities by tags that was introduced in 3.0.106 https://processwire.com/blog/posts/pw-3.0.106/#a-new-way-to-search-with-upgraded-tags-for-fields
    3 points
  7. Thanks for the report. PHP 7.3 apparently makes some changes to the regex engine and so an update to the bundled Simple HTML Dom Parser was needed. Done now in v0.1.6 of this module.
    3 points
  8. Hello all, I'm in the process of updating some websites to comply to the new GDPR opt-in regulations. Doing some resarch, I found this open source tool: https://klaro.kiprotect.com/ It looks quite promising and implementation seems quite easy. Have you used this tool? What is your experience so far? I saw that @Jens Martsch - dotnetic made some comments to the klaro GH issues. Did you implement this with PW?
    2 points
  9. Same here, i've been repeatedly graced with effortless and smooth upgrades countless times... such a godsend!
    2 points
  10. UPDATE 2020-01-30 SnipWire 0.8.0 (beta) first public release! It is done! After almost 1 year of hard work and a lot of help from the usual suspects I just released the first public version! Please note that this is still a beta so please test, test, test before you use this plugin in a real project. The module can be loaded via PW modules directory (just submitted - in review I think) or directly via GitHub. More infos will be added soon ...
    2 points
  11. Yes it is good and in use on the site https://www.p-jentschura.com/ I added this directly in the HTML so it has nothing to do with ProcessWire in general, but I am thinking about developing a module for it to set the options. But thats only for the far future and next website project.
    2 points
  12. I have recently started to integrate Twig in my ProcessWire projects to have a better separation between logic and views as well as have cleaner, smaller template files as opposed to large multi-purpose PHP-templates. Though there is a Twig module, I have opted to initialize twig manually to have more control over the structure and settings of the twig environment. This is certainly not required to get started, but I find that having no "secret sauce" gives the me as a developer more agency over my code structure, and better insights into how the internals of the libraries I'm using work. Framework like Drupal or Craft have their own Twig integration, which comes with some opinionated standards on how to organize your templates. Since Twig is not native to ProcessWire, integrating Twig requires one to build a solid template structure to be able to keep adding pages and partials without repeating oneself or having templates grow to unwieldy proportions. This will be an (opinionated) guide on how to organize your own flexible, extensible template system with ProcessWire and Twig, based on the system I developed for some projects at work. Somehow this post got way too long, so I'm splitting it in two parts. I will cover the following topics: Part 1: Extendible template structures How to initialize a custom twig environment and integrate it into ProcessWire How to build an extendible base template for pages, and overwrite it for different ProcessWire templates with custom layouts and logic How to build custom section templates based on layout regions and Repeater Matrix content sections Part 2: Custom functionality and integrations How to customize and add functionality to the twig environment How to bundle your custom functionality into a reusable library Thoughts on handling translations A drop-in template & functions for responsive images as a bonus However, I will not include a general introduction to the Twig language. If you are unfamiliar with Twig, read the Twig guide for Template Designers and Twig for Developers and then come back to this tutorial. That's a lot of stuff, so let's get started ? Initializing the Twig environment First, we need to install Twig. If you set up your site as described in my tutorial on setting up Composer, you can simply install it as a dependency: composer require "twig/twig:^2.0" I'll initialize the twig environment inside a prependTemplateFile and call the main render function inside the appendTemplateFile. You can use this in your config.php: $config->prependTemplateFile = '_init.php'; $config->appendTemplateFile = '_main.php'; Twig needs two things: A FilesystemLoader to load the templates and an Environment to render them. The FilesystemLoader needs the path to the twig template folder. I'll put my templates inside site/twig: $twig_main_dir = $config->paths->site . 'twig'; $twig_loader = new \Twig\Loader\FilesystemLoader($twig_main_dir); As for the environment, there are a few options to consider: $twig_env = new \Twig\Environment( $twig_loader, [ 'cache' => $config->paths->cache . 'twig', 'debug' => $config->debug, 'auto_reload' => $config->debug, 'strict_variables' => false, 'autoescape' => true, ] ); if ($config->debug) { $twig_env->addExtension(new \Twig\Extension\DebugExtension()); } Make sure to include a cache directory, or twig can't cache the compiled templates. The development settings (debug, auto_reload) will be dependent on the ProcessWire debug mode. I turned strict_variables off, since it's easier to check for non-existing and non-empty fields with some parts of the ProcessWire API. You need to decide on an escaping strategy. You can either use the autoescape function of twig, or use textformatters to filter out HTML tags (you can't use both, as it will double escape entities, which will result in a broken frontend). I'm using twig's inbuilt autoescaping, as it's more secure and I don't have to add the HTML entities filter for every single field. This means pretty much no field should use any entity encoding textformatter. I also added the Debug Extension when $config->debug is active. This way, you can use the dump function, which makes debugging templates much easier. Now, all that's left is to add a few handy global variables that all templates will have access to, and initialize an empty array to hold additional variables defined by the individual ProcessWire templates. // add the most important fuel variables to the environment foreach (['page', 'pages', 'config', 'user', 'languages', 'sanitizer'] as $variable) { $twig_env->addGlobal($variable, wire($variable)); }; $twig_env->addGlobal('homepage', $pages->get('/')); $twig_env->addGlobal('settings', $pages->get('/site-settings/')); // each template can add custom variables to this, it // will be passed down to the page template $variables = []; This includes most common fuel variables from ProcessWire, but not all of them. You could also just iterate over all fuel variables and add them all, but I prefer to include only those I will actually need in my templates. The "settings" variable I'm including is simply one page that holds a couple of common settings specific to the site, such as the site logo and site name. Page templates By default, ProcessWire loads a PHP file in the site/templates folder with the same name of the template of the current page; so for a project template/page, that would be site/templates/project.php. In this setup, those files will only include logic and preprocessing that is required for the current page, while the Twig templates will be responsible for actually rendering the markup. We'll get back to the PHP template file later, but for the moment, it can be empty (it just needs to exist, otherwise ProcessWire won't load the page at all). For our main template, we want to have a base html skeleton that all sites inherit, as well as multiple default regions (header, navigation, content, footer, ...) that each template can overwrite as needed. I'll make heavy use of block inheritance for this, so make sure you understand how that works in twig. For example, here's a simplified version of the html skeleton I used for a recent project: {# site/twig/pages/page.twig #} <!doctype html> <html lang="en" dir="ltr"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>{% block title %}{{ '%s | %s'|format(page.get('title'), homepage.title) }}{% endblock %}</title> <link rel="stylesheet" type="text/css" href="{{ config.urls.site }}css/main.css"> </head> <body class="{{ page.template }}"> {% block navigation %}{{ include("components/navigation.twig") }}{% endblock %} {% block header %}{{ include("components/header.twig") }}{% endblock %} {% block before_content %}{% endblock %} {% block content %} {# Default content #} {% endblock %} {% block after_content %}{% endblock %} {% block footer %}{{ include("components/footer.twig") }}{% endblock %} </body> </html> All layout regions are defined as twig blocks, so each page template can override them individually, without having to touch those it doesn't need. I'll fill the content block with default content soon, but for now this will do. Now, templates for our content types can just extend this base. This is the template for the homepage: {# site/twig/templates/pages/page--home.twig #} {% extends "pages/page.twig" %} {# No pipe-seperated site name on the homepage #} {% block title page.get('title') %} {# The default header isn't used on the homepage #} {% block header %}{% endblock %} {# The homepage has a custom slider instead of the normal header #} {% block before_content %} {{ include('sections/section--homepage-slider.twig', { classes: ['section--homepage-slider'] }) }} {% endblock %} Note that I don't do most of the actual html markup in the page templates, but in individual section templates (e.g. section--homepage-slider.twig) that can be reused across content types. More on this in the next section. We still need to actually render the template. The page template (which will be the entry point for twig) will be loaded in our _main.php, which we defined as the appendTemplateFile earlier, so it will always be included after the template specific PHP file. $template_file = 'pages/page--' . $page->template->name . '.twig'; $twig_template = file_exists($twig_main_dir . '/' . $template_file) ? $template_file : 'pages/page.twig'; echo $twig_env->render($twig_template, $variables); This function checks if a specific template for the current content type exists (e.g. pages/page--home.twig) and falls back to the default page template if it doesn't (e.g. pages/page.twig). This way, if you want a blank slate for a specific content type, you can just write a twig template that doesn't extend page.twig, and you will get a blank page ready to be filled with whatever you want. Note that it passes the $variables we initialized in the _init.php. This way, if you need to do any preprocessing or data crunching for this request, you can do it inside the PHP template and include the results in the $variables array. At this point, you can start building your default components (header, footer, navigation, et c.) and they will be included on every site that extends the base page template. Custom sections Now we've done a great deal of setup but haven't actually written much markup yet. But now that we have a solid foundation, we can add layout components very easily. For most of my projects, I use the brilliant Repeater Matrix module to set up dynamic content sections / blocks (this is not the focus of this tutorial, here's a detailed explanation). The module does have it's own built-in template file structure to render it's blocks, but since it won't work with my Twig setup, I'll create some custom twig templates for this. The approach will be the same as with the page template itself: create a "base" section template that includes some boilerplate HTML for recurring markup (such as a container element to wrap the section content in) and defines sections that can be overwritted by section-specific templates. First, let's create a template that will iterate over our the Repeater Matrix field (here it's called sections) and include the relevant template for each repeater matrix type: {# components/sections.twig #} {% for section in page.sections %} {% set template = 'sections/section--' ~ section.type ~ '.twig' %} {{ include( [template, 'sections/section.twig'], { section: section }, with_context = false ) }} {% endfor %} Note that the array syntax in the include function tells Twig to render the first template that exists. So for a section called downloads, it will look look for the template sections/section--downloads.twig and fallback to the generic sections/section.twig. The generic section template will only include the fields that are common to all sections. In my case, each section will have a headline (section_headline) and a select field to choose a background colour (section_background) : {# sections/section.twig #} {% set section_classes = [ 'section', section.type ? 'section--' ~ section.type, section.section_background.first.value ? 'section--' ~ section.section_background.first.value ] %} <div class="{{ section_classes|join(' ')|trim }}"> <section class="container"> {% block section_headline %} {% if section.section_headline %} <h2 class="section__headline">{{ section.section_headline }}</h2> {% endif %} {% endblock %} {% block section_content %} {{ section.type }} {% endblock %} </section> </div> This section template generates classes based on the section type and background colour (for example: section section--downloads section--green) so that I can add corresponding styling with CSS / SASS. The specific templates for each section will extend this base template and fill the block section_content with their custom markup. For example, for our downloads section (assuming it contains a multivalue files field download_files): {# sections/section--download.twig #} {% extends "sections/section.twig" %} {% block section_content %} <ul class="downloads"> {% for download in section.download_files %} <li class="downloads__row"> <a href="{{ download.file.url }}" download class="downloads__link"> {{ download.description ?: download.basename }} </a> </li> {% endfor %} </ul> {% endblock %} It took some setup, but now every section needs only care about their own unique fields and markup without having to include repetitive boilerplate markup. And it's still completely extensible: If you need, for example, a full-width block, you can just not extend the base section template and get a clean slate. Also, you can always go back to the base template and add more blocks as needed, without having to touch all the other sections. By the way, you can also extend the base section template from everywhere you want, not only from repeater matrix types. Now we only need to include the sections component inside the page template {# pages/page.twig #} {% block content %} {% if page.hasField('sections') and page.sections.count %} {{ include('components/sections.twig' }} {% endif %} {% endblock %} Conclusion This first part was mostly about a clean environment setup and template structure. By now you've probably got a good grasp on how I organize my twig templates into folders, depending on their role and importance: blocks: This contains reusable blocks that will be included many times, such as a responsive image block or a link block. components: This contains special regions such as the header and footer that will probably be only used once per page. sections: This will contain reusable, self-contained sections mostly based on the Repeater Matrix types. They may be used multiple times on one page. pages: High-level templates corresponding to ProcessWire templates. Those contain very little markup, but mostly include the appropriate components and sections. Depending on the size of the project, you could increase or decrease the granularity of this as needed, for example by grouping the sections into different subfolders. But it's a solid start for most medium-sized projects I tackle. Anyway, thanks for reading! I'll post the next part in a couple of days, where I will go over how to add more functionality into your environment in a scalable and reusable way. In the meantime, let me know how you would improve this setup!
    1 point
  13. For folk using the module - is the configuration of sets in the textarea working OK for you? I've been mulling over trying to build something a bit more user-friendly, like a kind of repeater field for entering data, but I'm not convinced that it would actually be easier to work with, particularly as I usually only enter an image width per line and that's it. In a future version I want to add the configuration on a per-field basis (maybe even per-image even though that would be overkill), so I want to get the configuration method as solid as possible first. Perhaps retaining the textarea, but with a live preview would be the best option? I'm also not sure whether it is useful to have portrait mode and UIkit widths as config options. Ultimately the module is meant to extend Pageimage so that srcset and sizes can be used - I feel these config options are a result of my own bias in how I use the module, and yet I don't think I've used the portrait option at all! Any ideas/thoughts you have, please come with them! Cheers, Chris
    1 point
  14. I'll join the "bliss train" have also updated sites running for years on old versions with no issues, I hope this thread gets mentioned in the ProcessWire weekly haha, people really need to know it's possible to live without waiting for your the site to break.
    1 point
  15. You could adapt and try out the code in this post:
    1 point
  16. Thanks @nbcommunication, makes sense! If I happen to find time for this I might send you a pull request for this feature, but no pressure – I've got plenty of stuff on my plate as well, and even if I do send such a PR, it's perfectly fine if you don't think the suggested solution is good enough... ?
    1 point
  17. On the off-chance that anyone else stumbles on this and thinks it's a solution for what they need, you should set the field to readonly, instead of disabled. Otherwise ProcessWire looks for a value, doesn't find one, and saves it as empty, meaning you'll wipe all the fields on a save.
    1 point
  18. That's a good question which I don't have an answer to. I copied that from ProcessField, which behaves the same - a warning if you use "manage tags", but none if you assign such a tag in the regular Field edit form. Good point, thanks. Already added in 0.0.2.
    1 point
  19. Very helpful, thanks! I see the module gives a warning if a tag is created that has the same name as an existing template. Tags added to a template via the core way on the Advanced tab don't give this warning. Is there a catch to watch out for if a tag name is also a template name? Also, it's only a small thing but maybe this module only needs to autoload in the PW admin ("autoload" => "template=admin") rather than for the front-end also.
    1 point
  20. I just submitted my first module to the PW modules directory. The module is a full featured e-commerce module but I couldn't find a corresponding category there. May I suggest that a responsible person add a new category "e-commerce" (or something similar)?
    1 point
  21. Nice work! I made a Twig module way back as I was doing similar things to what you do here. Since then others have made (far cleaner) Twig modules too and I recommend these for most people. Getting your hands dirty and seeing how relatively straight-forward it is to use Twig or similar engines from scratch with ProcessWire is extremely valuable though - even if you go back to using the modules in the end. It gives a much clearer picture of what is going on (and therefore what could go wrong too). I've started playing with the Latte templating engine recently and love it (though I hate Php's $ style variables and -> style object notations which Latte uses), but Twig will always hold a special place as it was the first templating engine that actually felt good to use and not a chore! Thanks for the great tutorial!
    1 point
  22. ...or you can use this small module that (with a lot of nicked code from ProcessField) adds the functionality to the Template list: https://github.com/BitPoet/TemplateTagsEditList Best try it out on a copy of the site though, I haven't tested it much yet. Anyway...have fun ? (I'm soon going to use this a lot myself to clean up a few really complex sites...)
    1 point
  23. Just tried out @Mikie's fix for the excluded templates field and it seems to be working. I changed the hardcoded ".php" extension to use $this->wire('config')->templateExtension) instead (so sites with other extensions selected or the use .latte extension option should still work). Tried with and without the default .latte extension option and the excluded templates field seems to be working. Oddly enough, the issue with the Tracy console appears to be resolved even without adding it back to the excluded list (yesterday that didn't work with the .latte template extension). Not sure what I've done differently there, maybe it was a weird caching issue or something. Since I've made a few posts in a row, to summarise the changes I've made: Allow for no default layout file (handy if you have a number of very different parts of the site, json "pages" etc. Still works identically if you want a default layout so shouldn't have any downsides. Added logic to ignore latte rendering if a view file doesn't exist. Makes most cases of the ignored templates field unnecessary. Makes for easier site migration to latte - keep everything as-is, and you can migrate one template at a time without having to manually put everything in the ignored templates field. Added in @Mikie's suggested fix for the ignored templates field This field could still be useful even with my above change, even if just to temporarily disable a template for instance. Changed Mikie's hard-coded ".php" extension to use the templateExtension config option from PW to hopefully make this work in more configurations. Updated to latest Latte version Replaced CRLF line endings with LF in the .module file as well as README.md and CHANGELOG.md as they were the only files to use this format. This should make any future git diff commands cleaner, especially on non-Windows systems. I think that is everything I have changed. All these can be found on my "fork" here: https://github.com/porl/TemplateLatteReplace
    1 point
  24. I would just probably add a new ckeditor span with a class so editors could apply manually. That would also allow excluding headlines.
    1 point
  25. Hi everybody, I want to share what I came up with. Background: The goal was to get a color-accent to every headline on my new project. First thought was to use CSS-only with ::before pseudo element, but the problem is, that the headline is a either a block element (then position absolute left 0 leads to the accent being on the very left even for text-align:center headlines). Or if the headline is inline-block I had some other weird problem that I can't remember right now. Also multiline headlines where tricky. That's why I wanted to add a real element at the beginning of every headline. Wrapping the first word was actually not necessary. I'm adding an empty <i></i> now right behind the opening <h2> or <h3> tag, so the regex get's even simpler. Here's the result: Here's the LESS if someone is interested: // apply style to all elements with tm-fancy attribute // this attribute is added to all h2+h3 via textformatter *[tm-fancy] { font-family: @tm-font-fancy; i:first-of-type { position: relative; } i:first-of-type::before { content: ''; position: absolute; left: -15px; bottom: 5px; width: 120px; height: 20px; background: @tm-secondary; z-index: -1; border-radius: 2px; } } // adjust width and height for h3 h3[tm-fancy] i:first-of-type::before { width: 100px; height: 15px; } And here's the very simple textformatter that I can apply now an every textarea field: <?php namespace ProcessWire; class TextformatterFancyHeadlines extends Textformatter { public static function getModuleInfo() { return array( 'title' => 'FancyHeadlines', 'version' => 100, 'summary' => "Add <i></i> to headlines for color accents.", ); } public function format(&$str) { // early exit if there are not h2 or h3 elements if(strpos($str, "<h2") < 0 AND strpos($str, "<h3") <0) return; // add attribute and inline element via regex $re = '~(<h[23][^>]*)(>)~ism'; $str = preg_replace($re, "$1 tm-fancy$2<i></i>", $str); } } Thx for your help ? PS: If anybody knows a better solution please share it ? Maybe there's a CSS-only way of doing that?
    1 point
  26. @HMCB, thanks! So the datepicker itself is nothing fancy, it's just a style-matched version of Calendario https://tympanus.net/Development/Calendario/index2.html In Calendario, you just setup a JSON array of the events, and init the plugin with JS. The link on each date is to a URLSegment which then is processed via the API to get the events for that date. The URL segment logic was tricky because there are events with series dates (using a ProFields Table) which also need to be accounted for, but the beauty of the PW api is that it only took maybe 20 lines of code for all of the event fetching logic for single date calls. ---- also wanted to say thanks for the mention on the blog, newsletter, and SOTW! ? ---- and the SkyscrapersTurbo™ Profile is well underway, featuring rangesliders for all numeric attributes (Year, Floors, Height) and architect filter. So this version is is possible to narrow down results for very specific combinations.
    1 point
  27. This is the only way I know to create different sizes when uploading images: <?php class ImageCreateThumbs extends WireData implements Module { public static function getModuleInfo() { return array( 'title' => 'ImageCreateThumbs', 'version' => 100, 'summary' => '', 'href' => '', 'singular' => true, 'autoload' => true ); } public function init() { $this->addHookAfter('InputfieldFile::fileAdded', $this, 'sizeImage'); } public function sizeImage($event) { $inputfield = $event->object; if($inputfield->name != 'images') return; // we assume images field $image = $event->argumentsByName("pagefile"); $image->size(120,120); $image->size(1000,0); } } https://gist.github.com/5685631 What I don't know is if it really makes a difference (I guess), and if using drag and drop ajax upload and old school upload would process image one by one. My suggestion is to also upload image already in 1000x* pixels because if they upload 3000+ px images it will just takes a lot longer.
    1 point
×
×
  • Create New...