Leaderboard
Popular Content
Showing content with the highest reputation on 06/07/2020 in all areas
-
We recently launched The Power Supply Shop, an e-commerce store built using a combination of ProcessWire and SnipCart. The site has in excess of 120,000 products and variations, making heavy use of page references as well as SnipCart's "any page can be a product" approach. The site pulls in its data from an external MS SQL database several times a day. At a glance, the site uses: ProCache - as well as WireCache for some heavy product listing pages (50k+) FormBuilder @adrian's Tracy Debugger A modified version of @Soma's Ajax Search @mtwebit's fantastic Tasker and DataSet modules. And that's about it on the module front. For other libraries we're only really using FancyBox.js for product galleries and Anchorific.js for guide pages. At present the site is geared towards the UK, but if and when this changes I'm looking forward to delving into multi-languages with ProcessWire, something I haven't really worked with yet!8 points
-
Forgot to put a note on what is currently supported : Features Auto-save Medias upload support HannaCode support Blocks Implemented Heading Image Paragraph Embed Quote Code Link Table (beta) Block Delimiter Raw HTML Note (custom block markup)4 points
-
v0.0.11 adds support for repeater matrix fields ? Thx to @aComAdi of https://www.a-commerce.ch/ for sponsoring this update! ? $rm->setMatrixItems('your_matrix_field', [ 'foo' => [ 'label' => 'foo label', 'fields' => ['field1', 'field2'], ], 'bar' => [ 'label' => 'bar label', 'fields' => ['field1', 'field3'], ], ]);3 points
-
Ok, it worked ... till the moment when I (as Superuser) wanted to add a new User. I got the "Fatal Error: Call to a member function attr() on null" in this line of the hook: $title->attr('autocomplete', 'off'); As a workaround I replaced it with if ($title) { $title->attr('autocomplete', 'off'); }; That helped - but I feel unsecure if there's something bad still left. Obviously it's just because the user template doesn't have a title field...2 points
-
You can disable autocomplete on input elements with the autocomplete attribute. You can modify built-in forms through hooks by looking up which Process module is creating the form and then hooking after it's buildForm method. In this case, it's ProcessPageAdd. This hook sets autocomplete="off" on both the title and the name input fields: // site/init.php wire()->addHookAfter('ProcessPageAdd::buildForm', function (HookEvent $e) { $form = $e->return; // disable autocomplete for the title field $title = $form->getChildByName('title'); $title->attr('autocomplete', 'off'); // disable autocomplete for the name field $pwPageName = $form->getChildByName('_pw_page_name'); $pwPageName->attr('autocomplete', 'off'); });2 points
-
Hello, I would like to present you a new module which aim to facilitate the productivity of your editors/publishers when working on ProcessWire. The idea begun when my co-worker told me that when typing in ProcessWire CkEditor field he was feeling "loosing motivation" when writing big wall of text and/or inspiration. So he opened his web-browser and show me a site looking to Wordpress - feel free to put your preferred emoji here - then he opened Gutenberg... typed some text and moving some "blocks". I understood immediately why he got this feeling with CkEditor. If you or your client feel like this guy, then you will love this module ! What is currently supported ? Features Auto-save Medias upload support HannaCode support Blocks Implemented Heading Image Paragraph Embed Quote Code Link Table (beta) Block Delimiter Raw HTML Note (custom block markup) Feature Request Frontend Edition And there you go for the preview - sorry I am to lazy and bad at typing text so I had a copy/pasta moment : Module featured in the ProcessWire Weekly #317 - Thanks @teppo1 point
-
Tasker is a module to handle and execute long-running jobs in Processwire. It provides a simple API to create tasks (stored as PW pages), to set and query their state (Active, Waiting, Suspended etc.), and to execute them via Cron, LazyCron or HTTP calls. Creating a task $task = wire('modules')->Tasker->createTask($class, $method, $page, 'Task title', $arguments); where $class and $method specify the function that performs the job, $page is the task's parent page and $arguments provide optional configuration for the task. Executing a task You need to activate a task first wire('modules')->Tasker->activateTask($task); then Tasker will automatically execute it using one of its schedulers: Unix cron, LazyCron or TaskerAdmin's REST API + JS client. Getting the job done Your method that performs the task looks like public function longTask($page, &$taskData, $params) { ... } where $taskData is a persistent storage and $params are run-time options for the task. Monitoring progress, management The TaskerAdmin module provides a Javascript-based front-end to list tasks, to change their state and to monitor their progress (using a JQuery progressbar and a debug log area). It also allows the on-line execution of tasks using periodic HTTP calls performed by Javascript. Monitoring task progress (and log messages if debug mode is active) Task data and log Detailed info (setup, task dependencies, time limits, REST API etc.) and examples can be found on GitHub. This is my first public PW module. I'm sure it needs improvement1 point
-
Finally, a blog post this time ? — ProcessWire 3.0.159 brings some useful and time-saving upgrades to the core two-factor authentication system: https://processwire.com/blog/posts/pw-3.0.159/1 point
-
Hi @MarkE, I got this to work in a multi-instance environment by making the following change (no hooks needed, no new parameters or options). In FieldtypeRuntimeMarkup line #500 (in the method runtimePHPFile()): Change this: // render PHP file(s) with different name and/or more than 1 else { // $filenames is a csv string: convert to array $filenames = explode(',', str_replace(' ', '', $field->renderPHPFile)); foreach ($filenames as $filename) $out .= $files->render($filename, $vars, $options); } To this: // render PHP file(s) with different name and/or more than 1 else { $config = $this->wire('config'); if(2 === (int) $field->defaultPath) $defaultPath = $config->paths->siteModules;// /site/modules/ else $defaultPath = $config->paths->templates;// /site/templates/ // $filenames is a csv string: convert to array $filenames = explode(',', str_replace(' ', '', $field->renderPHPFile)); foreach ($filenames as $filename) { $filename = "{$defaultPath}{$filename}"; $out .= $files->render($filename, $vars, $options); } } And bob's your uncle! This was test my setup. Site 1 (your App) RM installed RM used with Render PHP file(s) option Rendered file lives in scripts/some-folder/script.php Multi-lingual site RM renders in pages OK. Site 2 (your Web/Properties) RM module NOT INSTALLED Instances Site 1 like below in some template file RM output from Site 1 displayed in Site 2 frontend // both of these work without errors // $parentSite = new ProcessWire($pathToParentSite); $parentSite = new ProcessWire($pathToParentSite,"http://site1domain.tld/"); $content = "<h3>RM Field from Parent</h3>"; $parentPagesWithRMField = $parentSite->pages->find("parent=1234,sort=created, limit=3"); foreach($parentPagesWithRMField as $item) { $content .= " <p> <a href='$item->httpUrl'>$item->title</a><br /> $item->rm_field <hr> </p> "; } Now it is interesting that: In the method runtimePHPFile(), $config correctly points to the correct PW instance (if you bd() inside the method and view Site 1 versus Site 2, you'll see the path in both cases point to Site 1) In getDefaultPath(), $config always points to the present site (i.e. If you bd($defaultPath) and check in the page with the RM field in Site 1, it points to Site 1. If you check in the frontend of Site 2 [where we instance Site 1], it points to Site 2). Note, getDefaultPath() is in an included class in the module file (FieldtypeRuntimeMarkup.module). This is the reason why RM was not working correctly. We were passing $files->render(/a/relative/path/). In addition, the defaultPath we were passing in its options came from getDefaultPath() which always points inward. Hence, $files was looking inward (Site 2, in our case). When we prepend $config, we are passing $files an absolute path, hence it works. Anyway, I hope this works for you. Obviously the CSS and JS won't carry over. You'd need to sort that out. It is easy call them from Site 1 to Site 2 if you need to, so you don't duplicate code.1 point
-
Yeah makes sense, checking if the field exists is sensible ? Should work fine. Maybe add the same check for the name field as well? If the template is set to generate the name automatically, the field may be missing as well (I think it skips this step entirely then, but it's an additional safeguard that won't hurt anyone). If you're paranoid you could use a whitelist of templates to apply the hook to as well, to make sure it will never have unintended consequences ...1 point
-
@aComAdi Add $config->pageNumUrlPrefix = Seite; to your config.php. Gideon1 point
-
1 point
-
1 point
-
@teppo Really great to get a lot of different perspectives on it! ? Really nice and well-argumented opinion! It's always funny to once again discover how differently we all perceive the world and how aesthetics comes down to being something so very subjective, as you also write yourself! ? I will agree with you in fact on a lot of things that you point out about the Kirby UI, but I still think it could be really interesting to have the discussion here on the forum about the PW UI. Maybe some cool redesign ideas could pop up? And maybe it could be really interesting to hear some feedback on the UI from clients of PW designers / developers ?1 point
-
Hi @Roych, sorry for my late response, I am currently a bit busy at work. The musical-fabrik repository is the main code for the page https://www.musical-fabrik.de , but there are several additional requirements (processwire's core, modules like PageTable and Repeatermatrix and the database-contents) to get the site running locally. Unfortunately I cannot make everything public, so I would recommend you to start a blank site and try to start building a simple component like shown in Twack's readme. The musical-fabrik page is an example, where everything is built out of nested Twack-components. You can see that in the php-files under /site/templates/, for example site/templates/default_page.php: <?php namespace ProcessWire; $twack = wire('modules')->get('Twack'); $general = $twack->getNewComponent('General'); echo $general->render(); This file is called, when a processwire-page with the template default_page is called. The only thing we do here is loading the Twack-module, initializing the General-component (located under /site/templates/components/general/) and then rendering it. The general-component renders the basic html structure, adds a header and a footer, and adds the default_page component as the main content area between header and footer. default_page registers itself under the global name 'mainContent', which can be used from everywhere else to add content-components to a page: $this->twack->makeComponentGlobal($this, 'mainContent'); Because of that, the galleries_container-template can add a gallery-grid under the default contents: <?php namespace ProcessWire; $twack = wire('modules')->get('Twack'); $general = $twack->getNewComponent('General'); $content = $twack->getComponent('mainContent'); $content->addComponent('ContentGalleries', ['directory' => 'contents_component', 'title' => '']); echo $general->render(); I hope, that helps to basically understand the underlaying logic of the site. Twack does not force you to use it that way, you are free to structure your components in many other ways. I am currently working on the documentation for the ajax-functionality, that lets you render every component as an json-array instead of html, which makes it very useful for app-api-development as well. Maybe, if you are interested, I could starting to write tutorials for some special Twack-components (like a simple header, footer, ...). The contents-component and my form-component, that builds a bootstrap-html-form from any processwire-template could be useful as well. Feel free to ask if something is unclear, I am aware that it can be hard to understand the concepts of Twack. But I am also convinced, that it is a great way to structure processwire projects. Thank you very much for your interest in it!1 point
-
It seems to be an issue with the RSS feed for the ProcessWire blog at https://processwire.com/blog/rss/ , which has not been updated since the 3.0.154 / 3.0.155 post in late April.1 point
-
Thanks @teppo for your insight, as always highly appreciated. I got what you mean. I think that there is a part of question of taste but also depending on the task on which the user is involved/focused. In first instance, while discussing with the colleague, I started to insist that he could use the CKEditor to write his articles; The point is here, he is specialised in content creation. I also suggested MS Word as tool - but no, the UI is not soft as Gutenberg. Then I abdicated and told him to write his articles on Gutenberg and a local install of Wordpress, after all, I will not touch at it, and I can import the content of a Wordpress page to ProcessWire. I don't know if you guys are used to write content, but this guy showed me also the editor that was crafted for the big site Medium. It's something similar, polished, the editor contain an inline toolbar and some blocks. I understood then that it's like an "new" category of users, they are used to write content in a modern environment. I was not even aware of those type of editor / blocks approach ? . So yes, I can understand that it can be "intimidating". Yes! First mission that was to bring back this guy to use ProcessWire is almost done ?? @Pixrael Yes it could. The module you would like to see was already mentioned and I remember that Theo, Elabx and Joshua worked on something. It was not grapejs but the idea remain the same. If you really want to give a try and invest some time the community will help you ! @bernhard wrote nice tutorials on modules creation you could begin with, then start a new thread here in the modules/dev forum. There are some hard works in perspective and I think that a module like that should be taken by a group with dev and designers ?1 point
-
To be clear I wouldn't say that it was a failure by any means — more like we didn't see major benefits going with Editor.js vs. Repeater Matrix + CKEditor. "Results were inconclusive" ? Like you said, Editor.js probably isn't going to replace Repeater Matrix if what you really need is a block builder; at least it doesn't seem like a good idea at the moment. While it could definitely help with some tasks that CKeditor currently isn't very good at — such as embedding images — at the same time the "every element is a block" approach can also feel a little intimidating and perhaps even unintuitive for those more familiar with "traditional" content editors (CKeditor, Word, etc.) Should probably also mention that I did my proof of concept back in March, when the Editor.js project seemed a little... unresponsive. There were big missing parts (including i18n support) and issues that were not getting much attention. Now that I've checked, it appears that the project is going strong again. Hope this makes sense. All in all I'm very curious to see where you're going with this module! ?1 point
-
If I got what you mean (compatible Fieldtype ?) it's already the case, you can drop a textarea then choose EditorJS, CkEditor or the vanilla textarea as field. Sure ! On my side, it's the possibility to fetch those JSON data directly into the third party apps (mobile, desktop, etc). Glad to hear that someone tried to implement this editor solution. Could you elaborate on why it wasn't a great success ? As a non-editor who I am, I really like what I feel writing thing on this fieldtype. About RepeaterMatrix, I think (and we already saw some posts here in the forum) that it could be used to make a page builder, but thats not intended by this module.1 point
-
Intrigued! As it happens, I have InputfieldEditorJS + FieldtypeEditorJS proof-of-concept sitting on one of my own sites as well. Mostly functional, though your module looks way more polished. I never got to implement media uploads, for one. It was intended as a test to see if our team would prefer that over Repeater Matrix, and since it wasn't a massive success, I never fully completed it. Very much looking forward to seeing your module in action ?1 point
-
Sorry @rick not yet, there is a chance that the module will be released as ProModule with refund policy to be able to try the module.1 point
-
I am using ->size() to downsize images on the website. I love to have the original images stored in the backend for possible future changes in resolution. Visitors can access the original (full resolution) images by deleting the size numbers in the url of the image. Is it possible to prohibit access to the original images?1 point
-
1 point
-
That's what RockMigrations is for ? I've thought about a similar thing back in 2016 because I didn't know better (https://processwire.com/talk/topic/14603-rocksvn-brings-version-control-to-your-fields-templates/ ) but migrations are the way to go. The new migrate() function makes it very easy to build reusable setups: https://github.com/BernhardBaumrock/RockMigrations#migration-config-files1 point
-
I've uploaded a new version (0.9.5) to GitHub. It tries to handle DB connection loss errors and it has a basic profiler to optimize your import routines. See the wiki for more details. Note: TaskerAdmin needs some fixes in its JS-based task executor. Don't use this feature atm. (Cron is always the preferred task execution method.)1 point
-
I was thinking about this too... There was a dev branch that dropped the [file + rules in description] scheme and introduced a fieldset of [rule + (optional) file]. It turned out to be too complicated and it did not work well so I dropped it. An easy solution is to allow source location override. So... see this commit and use the input:location configuration option. Not the best solution as it still requires a (dummy) file to be uploaded (to create the import rules in its description), but it works. You can even use this solution to refer to files uploaded to other pages using this URL scheme: wire://pageid/filename Hope it helps. That's different. It downloads data for a single field (e.g. a file to be stored in a filefield) not for an entire DataSet.1 point
-
Just wanted to explain @kixe's excellent answer a little for those who might be wondering why that hook isn't listed in the Tracy Captain Hook panel or on the Captain Hook page: https://processwire.com/api/hooks/captain-hook/ What is going on is that ProcessPageEdit extends Process and Process has a ___headline() hookable method. If you're used the Tracy Captain Hook panel, it always pays to check the class that the current class extends: Now we're looking at the hooks for the Process class and we can see that headline is available. Hope that helps! The other useful tip is the to click the "Toggle All" button at the top and CTRL/CMD +F and look for "headline"1 point
-
1 point
-
Thanks for the feedback. I'll definitely have a look at InputfieldMarkup and wirequeue. It is possible to integrate the UI elements into other pages. There's a renderTaskList() method to perform this: if(wire('modules')->isInstalled("TaskerAdmin")) { $out .= '<h3>Tasks</h3>'; $out .= wire('modules')->get('TaskerAdmin')->renderTaskList($selector); } It can render a task list or a detailed task monitoring div including JS code to show the progressbar or even to execute the task when displaying the page. It needs improvement, however, as its links point to the TaskerAdmin page atm and the list UI is not really customizable.1 point
-
Here's a short snippet for site/ready.php that hooks after ProcessPageEdit::buildForm and moves a regular field (named "testfield here") from the Content tab to Settings. The methods used are from the InputfieldWrapper class. <?php wire()->addHookAfter("ProcessPageEdit::buildForm", null, "moveFieldToSettings"); function moveFieldToSettings(HookEvent $event) { $form = $event->return; $field = $form->find("name=testfield")->first(); if($field) { $settings = $form->find("id=ProcessPageEditSettings")->first(); // Alternatively, find a specific field to insert before/after: // $settings = $form->find("name=template")->first(); if($settings) { $form->remove($field); $settings->append($field); // In the alternative, insert before or after the found field: // $form->insertBefore($field, $settings); } } }1 point
-
On my side i prepared a function for srcset and <picture> tag creation. Function output look like : <picture> <!--[if IE 9]> <video style='display: none;'> <![endif]--> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.404x270.jpg' media='(max-width: 479px)' /> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.692x462.jpg' media='(max-width: 767px)' /> <source srcset='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.427x285.jpg' media='(max-width: 959px)' /> <!--[if IE 9]> </video> <![endif]--> <img src='data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==' data-srcset='/site/assets/files/1058/terra-nova-001.630x421.jpg' alt='terra-nova-001' class="lazyload uk-width-1-1" /> </picture> Here are my functions : /** /** * Generate Attributes Array or String * * @param $item * @return string */ function buildAttrs($item) { $attributes = ""; // echo "<pre>Key : " . print_r($item, true) . "</pre>"; if(array_key_exists('attributes', $item) && is_array($item['attributes'])) { foreach($item['attributes'] as $key => $attr) { $attributes .= ' ' . $key . '="' . $attr . '"'; } } return $attributes; } /** * * @param $image * @param $key * @param $options * @return string */ function buildSrcAndSrcset($image, $key, $options) { $return = ''; // echo "<pre>Key : {$key}, " . print_r($options, true) . "</pre>"; if(!empty($options[$key]) && !empty($options[$key]['sets']) && is_array($options[$key]['sets'])) { $x=1; $countSets = count($options[$key]['sets']); $sets = ""; foreach($options[$key]['sets'] as $k => $rules) { $y=$x++; $separator = ($y != $countSets) ? ", " : ""; if(!is_array($rules) && $rules == 'original') { $static_url = static_url($image->url); $sets .= "{$static_url} {$key}w{$separator}"; } elseif(isset($rules['width']) || isset($rules['height'])) { $size = imageResize($image, $rules); if(!is_null($size)) { $sets .= "{$size['url']} {$size['width']}w{$separator}"; } } } if($sets != "") $return = " {$key}='{$sets}'"; } elseif(!empty($options[$key]) && !empty($options[$key]['method']) && is_array($options[$key]['method'])) { $img = imageResize($image, $options[$key]['method']); if(!is_null($img)) $return = " {$key}='{$img['url']}'"; } elseif(!empty($options[$key]) && is_string($options[$key])) { $return = " {$key}='{$options[$key]}'"; } return $return; } /** * Image : Create <img /> tag with attributes and responsive lazyload option * * @param $image * @param array $options * @return string */ function image($image, $options = array(), $lightbox=FALSE) { $return = ""; // Alt attribute $alt = ($image->description != '') ? $image->description : pathinfo($image->filename, PATHINFO_FILENAME); $alt = " alt='{$alt}'"; if(array_key_exists('picture', $options) && is_array($options['picture'])) { $picture = $options['picture']; // Set Attributes $attributes = ""; if(array_key_exists('attributes', $picture)) { $attributes = buildAttributes($picture['attributes']); } $return .= "\n<picture{$attributes}>"; if(array_key_exists('source', $options['picture']) && is_array($options['picture']['source'])) { $return .= "\n\t<!--[if IE 9]><video style='display: none;'><![endif]-->"; $sources = $options['picture']['source']; foreach($sources as $key => $source) { $attrSrc = buildSrcAndSrcset($image, 'src', $source); $attrSrcset = buildSrcAndSrcset($image, 'srcset', $source); $attrDataSrcset = buildSrcAndSrcset($image, 'data-srcset', $source); $attributes = buildAttrs($source); $attrMedia = " media='{$key}'"; $return .= "\n\t\t<source{$attrSrc}{$attrSrcset}{$attrDataSrcset}{$attributes}{$attrMedia} />"; } $return .= "\n\t<!--[if IE 9]></video><![endif]-->"; } if(array_key_exists('img', $options['picture']) && is_array($options['picture']['img'])) { $img = $options['picture']['img']; $attrSrc = buildSrcAndSrcset($image, 'src', $img); $attrSrcset = buildSrcAndSrcset($image, 'srcset', $img); $attrDataSrcset = buildSrcAndSrcset($image, 'data-srcset', $img); $attributes = buildAttrs($img); $return .= "\n\t<img{$attrSrc}{$attrSrcset}{$attrDataSrcset}{$alt}{$attributes} />"; } $return .= "\n</picture>"; } elseif(array_key_exists('img', $options) && is_array($options['img'])) { $img = $options['img']; $attrSrc = buildSrcAndSrcset($image, 'src', $img); $attrSrcset = buildSrcAndSrcset($image, 'srcset', $img); $attrDataSrcset = buildSrcAndSrcset($image, 'data-srcset', $img); $attributes = buildAttrs($img); $return .= "\n<img{$attrSrc}{$attrSrcset}{$attrDataSrcset}{$alt}{$attributes} />"; } else { $src = " src='" . static_url($image->url) . "'"; $width = " width='{$image->width}'"; $height = " height='{$image->height}'"; // Set Attributes $attributes = ""; if(array_key_exists('attributes', $options)) { $attributes = buildAttributes($options['attributes']); } $return .= "\n<img{$src}{$width}{$height}{$alt}{$attributes} />"; } if(isset($lightbox) && $lightbox != FALSE) { $page = wire('page'); $title = ($image->description != "") ? $image->description : $page->title; $overlayEffect = (!is_bool($lightbox) && $lightbox != '') ? " " . $lightbox : " uk-overlay-fade"; $return = "\n<figure class='uk-overlay uk-overlay-hover'> \n\t{$return} \n\t<div class='uk-overlay-panel uk-overlay-background{$overlayEffect}'></div> \n\t<div class='uk-overlay-panel uk-overlay-icon{$overlayEffect}'></div> \n\t<a class='uk-position-cover' href='{$image->url}' title='{$title}' data-uk-lightbox=\"{group:'{$page->name}'}\"><span class='uk-hidden'>{$title}</span></a> \n</figure>"; } return $return; } /** * Resize Image * * @param $image * @param array $method * @return array|null */ function imageResize($image, $method=array()) { $alt = ($image->description != '') ? $image->description : pathinfo($image->filename, PATHINFO_FILENAME); if(isset($method['type']) && isset($method['width']) || isset($method['height'])) { // Set Resize Options if(isset($method['options'])) $options = $method['options']; else $options = wire('config')->imageSizerOptions; if($method['type'] === 'size' && isset($method['width']) && isset($method['height'])) { $size = $image->size($method['width'], $method['height'], $options); } elseif($method['type'] === 'width' && isset($method['width'])) { $size = $image->width($method['width'], $options); } elseif($method['type'] === 'height' && isset($method['height'])) { $size = $image->height($method['height'], $options); } else { $size = null; } if(!is_null($size)) { return array( 'url' => static_url($size->url), 'width' => $size->width, 'height' => $size->height, 'alt' => $alt ); } } elseif(is_null($method)) { return array( 'url' => static_url($image->url), 'width' => $image->width, 'height' => $image->height, 'alt' => $alt ); } return null; } /** * Return url with static url * * @param string $url * @return string */ function static_url($url="") { $config = wire('config'); if($config->debug === false && isset($config->static_url) && $config->static_url != "") { $static_url = $config->static_url; } else { $static_url = ""; } return $static_url . $url; } I set responsive sizes on my config file : /** * Responsive Image Options */ $responsiveSizes = array( 'small' => '480', 'medium' => '768', 'large' => '960', 'xlarge' => '1220' ); $config->resSmall = "(max-width: " . ($responsiveSizes['small']-1) . "px)"; $config->resMedium = "(max-width: " . ($responsiveSizes['medium']-1) . "px)"; $config->resLarge = "(max-width: " . ($responsiveSizes['large']-1) . "px)"; $config->resXlarge = "(min-width: {$responsiveSizes['xlarge']}px)"; And I created a file (including this file inside my init.php file) that file have responsive image sizes like : /** * Template --Villa List-- */ $respImgOptions['villa']['list'] = array( 'picture' => array( 'source' => array( $config->resSmall => array( 'srcset' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 404, 'height' => 270 ) ) ), $config->resMedium => array( 'srcset' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 692, 'height' => 462 ) ) ), $config->resLarge => array( 'srcset' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 427, 'height' => 285 ) ) ) ), 'img' => array( 'src' => 'data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==', 'attributes' => array( 'class' => 'lazyload uk-width-1-1' ), 'data-srcset' => array( 'method' => array( 'type' => 'size', 'width' => 630, 'height' => 421 ) ) ) ) ); And after all done calling images from page like : // on here you need to send single PageImage ! $img = image($page->image->first(), $config->respImgOptions['villa']['list']); Like this usage if you have https://github.com/aFarkas/lazysizes and https://github.com/aFarkas/lazysizes/tree/gh-pages/plugins/respimg every thing will work well !1 point
-
Yes, if the WordPress site supports webmentions. If the site doesn't support webmentions and does support pingback, this module will fallback to sending a pingback. There are WordPress plugins to add webmention support,. See http://indiewebcamp.com/WordPress for more info. As I understand it, there's actually two plugins to get the full features: Webmention and Semantic Linkbacks. The latter gives you more user-friendly text for linkbacks (of all types). There's a pretty active group of WordPress users in the indiewebcamp community and I know they'd love to help anyone get set up with these plugins. Feel free to stop by the IRC for any help: http://indiewebcamp.com/IRC1 point