Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/05/2020 in all areas

  1. I wanted to write a bit of an update since this project was so well received last year. The Architekturführer has now been online for about nine months, and we have been getting mostly positive feedback. Thankfully, I was able to resolve all issues with Google's indexing of the page. The site's SEO is actually pretty solid now, being one of the first results when searching for "Architekturführer" (at least from within Cologne). We have also added some new content and restructured some pages. The homepage, for example, now features only selected projects. An iconic new entry that everyone who's been to Cologne in recent years will recognize is the Rheinboulevard Deutz. There's also an entirely new section for architecture-themed walks (Spaziergänge) that you can take in different areas of the city. If you come to visit for a day, make sure to check those out ? Finally, we got some traffic through word of mouth and a couple of architecture news sites, the visitor numbers are steadily rising each month. The only thing I find a bit lacking is that the number of PWA installations are very low. It seems the whole PWA concept has not really come through yet, or maybe it's just not that much of an added benefit compard to the normal site. I'm interested to see how PWAs will fare against native apps in the future, once they become more widely adopted.
    4 points
  2. You want to write that line: $mobile_menu = $homepage->children; in one of a few different ways, e.g.: $mobile_menu->add($homepage->children); // or, though no need to create a new PageArray beforehand in this case: $mobile_menu = $homepage->children->makeCopy(); to avoid any caching issues and avoid changing "builtin" PageArrays. If you directly assign $homepage->children, $mobile_menu points to the already loaded instance of the children PageArray of $homepage and your new, empty PageArray gets discarded. Repeated calls to $pages->get(1) are cached and return the page object already in memory. I can only guess since you didn't post that part of the code, but it looks like you may have inadvertently manipulated $homepage->children when you built your main navigation. Make sure to use add() or makeCopy() in that part too.
    2 points
  3. Well, it's just this dinosaur JS plugin. Use a custom JS in admin or a hook: $("#AdminDataTable1").trigger( 'sorton', [ [[1,1]] ] ); // sort 2nd column in descending order
    2 points
  4. Hey folks! Took a couple of late nights, but managed to turn this old gist of mine into a proper module. The name is SearchEngine, and currently it provides support for indexing page contents (into a hidden textarea field created automatically), and also includes a helper feature ("Finder") for querying said contents. No fancy features like stemming here yet, but something along those lines might be added later if it seems useful (and if I find a decent implementation to integrate). Though the API and selector engine make it really easy to create site search pages, I pretty much always end up duplicating the same features from site to site. Also – since it takes a bit of extra time – it's tempting to skip over some accessibility related things, and leave features like text highlighting out. Overall I think it makes sense to bundle all that into a module, which can then be reused over and over again ? Note: markup generation is not yet built into the module, which is why the examples below use PageArray::render() method to produce a simple list of results. This will be added later on, as a part of the same module or a separate Markup module. There's also no fancy JS API or anything like that (yet). This is an early release, so be kind – I got the find feature working last night (or perhaps this morning), and some final tweaks and updates were made just an hour ago ? GitHub repository: https://github.com/teppokoivula/SearchEngine Modules directory: https://modules.processwire.com/modules/search-engine/ Demo: https://wireframe-framework.com/search/ Usage Install SearchEngine module. Note: the module will automatically create an index field install time, so be sure to define a custom field (via site config) before installation if you don't want it to be called "search_index". You can change the field name later as well, but you'll have to update the "index_field" option in site config or module settings (in Admin) after renaming it. Add the site search index field to templates you want to make searchable. Use selectors to query values in site search index. Note: you can use any operator for your selectors, you will likely find the '=' and '%=' operators most useful here. You can read more about selector operators from ProcessWire's documentation. Options By default the module will create a search index field called 'search_index' and store values from Page fields title, headline, summary, and body to said index field when a page is saved. You can modify this behaviour (field name and/or indexed page fields) either via the Module config screen in the PocessWire Admin, or by defining $config->SearchEngine array in your site config file or other applicable location: $config->SearchEngine = [ 'index_field' => 'search_index', 'indexed_fields' => [ 'title', 'headline', 'summary', 'body', ], 'prefixes' => [ 'link' => 'link:', ], 'find_args' => [ 'limit' => 25, 'sort' => 'sort', 'operator' => '%=', 'query_param' => null, 'selector_extra' => '', ], ]; You can access the search index field just like any other ProcessWire field with selectors: if ($q = $sanitizer->selectorValue($input->get->q)) { $results = $pages->find('search_index%=' . $query_string . ', limit=25'); echo $results->render(); echo $results->renderPager(); } Alternatively you can delegate the find operation to the SearchEngine module: $query = $modules->get('SearchEngine')->find($input->get->q); echo $query->resultsString; // alias for $query->results->render() echo $query->pager; // alias for $query->results->renderPager() Requirements ProcessWire >= 3.0.112 PHP >= 7.1.0 Note: later versions of the module may require Composer, or alternatively some additional features may require installing via Composer. This is still under consideration – so far there's nothing here that would really depend on it, but advanced features like stemming most likely would. Installing It's the usual thing: download or clone the SearchEngine directory into your /site/modules/ directory and install via Admin. Alternatively you can install SearchEngine with Composer by executing composer require teppokoivula/search-engine in your site directory.
    1 point
  5. 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.
    1 point
  6. ProcessWire 3.0.98 Pageimage Manipulator 2 0.2.9 Some files(?) put pim2 in endless loop . Loop in ImageManipulator02.class.php : public function __construct($entryItem=null, $options=array(), $bypassOperations=false) { // version check module == class $m = wire('modules')->get('PageImageManipulator02')->getModuleInfo(); $m = preg_replace('/(\d)(?=\d)/', '$1.', str_pad("{$m['version']}", 3, "0", STR_PAD_LEFT)); $c = preg_replace('/(\d)(?=\d)/', '$1.', str_pad("{$this->version}", 3, "0", STR_PAD_LEFT)); if(!version_compare($m, $c, '=')) { throw new WireException("The versions of Module PageImageManipulator02 ($m) and it dependency classfile ImageManipulator02 ($c) are inconsist ent!)"); return; } $this->bypassOperations = true===$bypassOperations ? true : false; // validate PageImage, FileImage, MemoryImage if($entryItem instanceof Pageimage) { $this->pageimage = $entryItem; $this->entryItem = 'page'; $this->filename = $entryItem->filename; $this->isOriginal = $entryItem->original===NULL ? true : false; if(!$this->isOriginal) { // traversing up 'til reaching root reference $this->originalImage = $entryItem->original; while(null !== $this->originalImage->original) { // !!!!!!!!!!!! ENDLESS LOOP HERE !!!!!!!!!!!!!!!!!!!!!!! $reference = $this->originalImage->original; $this->originalImage = $reference; } } }
    1 point
  7. Hi everybody, I'm doing some CKEditor optimizations and as I'm not doing that often it's bringing quite some trouble with it... For example today I wanted to add the maximize plugin and it didn't work - the docs of CKEditor are slightly different to what we need at ProcessWire, so I thought we could share our findings in this thread! See here:
    1 point
  8. 1 point
  9. Usually guides from 2014 work just well and are still valid ?
    1 point
  10. ?‍♂️ ?‍♂️ ?‍♂️ ?‍♂️ ?‍♂️ Thx, that explains it ? I've also linked to your explanation in this old justify walkthrough that I was following all the time, not knowing that it was overly complicated ...
    1 point
  11. Maximize works right out of the box. I use it in almost every installation without adding anything new - besides the Maximize entry in the CKEditor-field settings.
    1 point
  12. Hi @porl, I have a functioning TemplateEngineLatte for TemplateEngineFactory module going which covers all my notes above (except the error logging). Figuring out the best way to be able to render independent snippets. So maybe ignore all my comments above. Can send to you if you want, its wip for personal use at the moment, but it works.
    1 point
  13. There were some changes to module settings and functionality so no guarantees on this I'm afraid. There were just too many bugs in the old version that I got beyond caring about ensuring backward compatibility and I was installing on a new site. I think you should test on a dev site first to see if it breaks anything before running on a production site.
    1 point
  14. 1 point
  15. I believe it is also fixed in: https://github.com/adrianbj/MarkupSEO/commits/various-fixes-enhancements As far as I know, this is the most improved version of the original module available - lots of bug fixes and improvements. That said, I am not maintaining it anymore, but if anyone wants to keep it going, I would start from that version. Otherwise, take a look at SEOMaestro.
    1 point
  16. You can simply edit /** * mystyles.js * * This file may be used when you have "Styles" as one of the items in your toolbar. * * For a more comprehensive example, see the file ./ckeditor-[version]/styles.js * */ CKEDITOR.stylesSet.add( 'mystyles', [ { name: 'Inline Code', element: 'code' }, ... { name: 'Heading Underline Span', element: 'span', attributes: { 'class': 'heading_underline' } }, ... ] ); and in your field definition (tab input), add "Styles" to the toolbar.
    1 point
  17. You should be able to replace the try/catch block with this if clause, but this is untested (I'm not using the module anywhere): $imgSmart = $page->get(implode('|', $configData['imageSmart'])); if($imgSmart instanceof WireArray) { $pageData['image'] = $imgSmart->first()->httpUrl; } else { $pageData['image'] = $imgSmart->httpUrl; }
    1 point
  18. i added new option in menu options because i needed css class in <a> tag, searched for a while and didn't find any example so had to do the following. $NavOptions = array( 'wrapper_list_type' => 'ul', // ul, ol, nav, div, etc. 'list_type' => 'li', // li, a, span, etc. 'menu_css_id' => 'navbarSupportedContent', // a CSS ID for the menu 'menu_css_class' => 'navbar-nav ml-auto', // a CSS Class for the menu 'current_class' => 'active', 'default_title' => 0, // 0=show saved titles;1=show actual/current titles 'default_class' => 'nav-item', // a CSS class to apply to all menu items 'ahref_class'=>'nav-link' ); added following line in MarkupMenuBuilder.module $this->set('linkClass', isset($options['ahref_class']) ? $options['ahref_class'] : ''); // if $iTag is empty, apply css id and classes to <a> instead if(!$iTag) $out .= "\n\t<a{$itemCSSID}{$class}{$newtab} href='{$m->url}'>{$m->title}</a>"; else $out .= "\n\t<{$iTag}{$itemCSSID}{$class}>\n\t\t<a{$newtab} href='{$m->url}' class='{$o->linkClass}'>{$m->title}</a>"; suggest me if there is any better way out!!
    1 point
  19. Just installed it. Really simple. Really useful. Thx a lot! ?
    1 point
  20. PageListSelect in a VEX modal - very nice ? Looks great!
    1 point
  21. Released: http://modules.processwire.com/modules/jquery-ion-range-slider/ The built in rangeslider is good, but it is somewhat limited if you need really specific slider interfaces, like with pips and showing the value on the handles. There are many Jquery rangesliders, but one of the best and easiest to implement is the ion.rangeSlider. http://ionden.com/a/plugins/ion.rangeSlider/en.html This is a preview of the very simple module that basically allows you to enable the ion.Rangeslider on any text input, and then you type in your params into the textarea field (careful, you can break the page's javascrpt if you are not careful!) There are way too many options to really make this configurable, so the easiest way it to have a free text field where you enter any params. The params are just passed to the instance of the slider. Features of ion.Rangeslider: Skin support. (5 skins included and PSD for skin creation) Any number of sliders at one page without conflicts and big performance problems Two slider types single (1 slider) and double (2 sliders) Support of negative and fractional values Ability to set custom step and snap grid to step Support of custom values diapason Customisable grid of values Ability to disable UI elements (min and max, current value, grid) Postfixes and prefixes for your numbers ($20, 20 € etc.) Additional postfix for maximum value (eg. $0 — $100+) Ability to prettify large numbers (eg. 10000000 -> 10 000 000 or 10.000.000) Slider writes its value right into input value field. This makes it easy to use in any html form Any slider value can be set through input data-attribute (eg. data-min="10") Slider supports disable param. You can set it true to make slider inactive Slider supports external methods (update, reset and remove) to control it after creation For advanced users slider has callbacks (onStart, onChange, onFinish, onUpdate). Slider pastes all its params to callback first argument as object Slider supports date and time Screenshots comparing Inputfield Rangeslider (Soma) vs. JqueryIonRangeSlider... 1) basic range using currency ' Same with different skin Range of years Same with narrower column and different skin.. the module is functional and being used on 1 site, but some additional testing is needed...
    1 point
×
×
  • Create New...