Jump to content

DawPi

Clients
  • Posts

    8,449
  • Joined

  • Last visited

  • Days Won

    20

Reputation Activity

  1. Like
    DawPi reacted to Matt in Beta 9 is now on the table!   
    Beta 9 is here, and there's a little addition to the editor!

    Along with the usual weekly round up of bug fixes, we've added a basic implementation of tables in the editor. We're testing this out to see how it goes before we build on it, but you should be able to add rows and columns and do all the usual table-y things.

    Let us know what you think!
     
  2. Like
    DawPi reacted to Charles in CDN and Firewall Transition   
    We’ve got some exciting news! All communities hosted on the Invision Community platform will be switching to Cloudflare Enterprise edition for CDN and Firewall services. This transition starts now and will be complete by the end of January 2025.
    Don’t worry, you won’t experience any downtime during this transition. If you do see any issues, like a secure certificate warning, just clear your cache and try again. If your community keeps getting connection errors for more than 5 minutes, please reach out to our support team.
    We’re thrilled to offer you these improvements, including enhanced security, faster speeds, and more redundancy. We’ll also be able to better control bots and filter bad-bots while still allowing Google, Bing, and other safe search engines to crawl your community. AI content scrapers have become a real pain for communities, constantly searching for great human-generated content. This change will help us control those AI bots.
    We’re confident that this transition will be smooth and hassle-free. If you have any questions or concerns, please don’t hesitate to contact our support team. We’re excited to see these improvements and many more in the coming months!
  3. Like
    DawPi reacted to Matt in We're in heaven with Beta 7!   
    Beta 7 is here, and I'm digging deep into my Bingo Lingo today!

    As always, check out our release notes for a full list of this week's fixes.
    Update:
    If you notice Pages article comments have vanished, do one of two things:
    Edit each database and under display add a value for comments per page.

    Wait until after 3pm GMT and apply the patch. 😇
  4. Like
    DawPi reacted to Klaus Mouse in Support for Observance of Shabbat?   
    Oh, good catch on the 8:30PM vs 7:30PM. Thank you. Total oversight on my part. 
    I spoke with Yeshua and I received a little more clarification on this request and how I can accomplish what I need without a plugin and nor without violating the ToS, but rather relying on the servers' configuration itself to isolate what is IPS and what is Shabbat script; thus... this reply will mark this as resolved. I thank everyone who contributed to the conversation as it helped me arrive to this solution to share with all.
    In /var/www/html/.htaccess I modified the DirectoryIndex property to shabbat.php and at the end of shabbat.php I added a header("Location: index.php"); and voila, IPS admin is not upset about the software and the directory is sufficient; however the line I needed to add was: 
    DirectoryIndex shabbat.php index.php index.html index.htm After that, IPS software's index.php is restored and untouched, and the Shabbat script prohibits access to the IPS software during the window of time required. 
    Thank you again for clarifying the 7:30PM vs 8:30PM. 
    Here is the complete .htaccess file:
    DirectoryIndex shabbat.php index.php index.html index.htm <IfModule mod_rewrite.c> Options -MultiViews RewriteEngine On RewriteBase / RewriteCond %{REQUEST_FILENAME} !-f RewriteRule \.(js|css|jpeg|jpg|gif|png|ico|map|webp)(\?|$) /404error.php [L,NC] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule> Here is the shabbat.php script: 
    <?php if(isset($_GET['debug']) && $_GET['debug'] == "1"){ ini_set('display_errors', 1); ini_set('display_startup_errors', 1); error_reporting(E_ALL); } date_default_timezone_set('America/New_York'); function getHebrewDate() { $date = new DateTime('now', new DateTimeZone('America/New_York')); $jd = gregoriantojd($date->format('m'), $date->format('d'), $date->format('Y')); $hebrew_date = cal_from_jd($jd, CAL_JEWISH); $hebrew_months = [ 1 => 'Tishri', 2 => 'Heshvan', 3 => 'Kislev', 4 => 'Tevet', 5 => 'Shevat', 6 => 'Adar', 7 => 'Adar II', 8 => 'Nisan', 9 => 'Iyar', 10 => 'Sivan', 11 => 'Tammuz', 12 => 'Av', 13 => 'Elul' ]; return sprintf("%d %s %d", $hebrew_date['day'], $hebrew_months[$hebrew_date['month']], $hebrew_date['year'] ); } $current_time = new DateTime(); $friday_730pm = (new DateTime('friday this week 19:30'))->setTimezone(new DateTimeZone('America/New_York')); $saturday_830pm = (new DateTime('saturday this week 20:30'))->setTimezone(new DateTimeZone('America/New_York')); if ($current_time >= $friday_730pm && $current_time < $saturday_830pm) { if (!empty($_SERVER['HTTP_X_SHABBAT_CHECK'])) { return; // Exit if this header is already set } header('X-Shabbat-Check: true'); header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache'); header('Expires: Thu, 01 Jan 1970 00:00:00 GMT'); header('Content-Type: text/html; charset=utf-8'); $remaining_time = $saturday_830pm->getTimestamp() - $current_time->getTimestamp(); $end_date = $saturday_830pm->format('l, F j, Y'); $current_hebrew_date = getHebrewDate(); ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Shabbat Shalom</title> <style> body { background-color: #2F4F4F; /* Slate Steel Gray */ color: #2C2C2C; /* Noir Graphite Dark Gray */ font-family: Arial, sans-serif; display: flex; flex-direction: column; justify-content: center; align-items: center; height: 100vh; margin: 0; } .container { background-color: rgba(255, 255, 255, 0.9); padding: 2rem; border-radius: 10px; text-align: center; box-shadow: 0 0 20px rgba(0, 0, 0, 0.1); max-width: 600px; width: 90%; } .countdown { font-size: 2rem; margin: 1rem 0; font-weight: bold; } h1 { margin-top: 0; } </style> <script> function startCountdown(seconds) { const countdownElem = document.getElementById('countdown'); function updateCountdown() { const days = Math.floor(seconds / 86400); const hours = Math.floor((seconds % 86400) / 3600); const minutes = Math.floor((seconds % 3600) / 60); const secs = seconds % 60; countdownElem.textContent = `${String(days).padStart(2, '0')}d ` + `${String(hours).padStart(2, '0')}h ` + `${String(minutes).padStart(2, '0')}m ` + `${String(secs).padStart(2, '0')}s`; if (seconds > 0) { seconds--; setTimeout(updateCountdown, 1000); } } updateCountdown(); } document.addEventListener('DOMContentLoaded', () => { const remainingTime = <?php echo $remaining_time; ?>; startCountdown(remainingTime); }); </script> </head> <body> <div class="container"> <h1>SHABBAT SHALOM!</h1> <p>Our community is honoring Yeshua's Sabbath for Shabbat.</p> <p>Our site will be back online in:</p> <div class="countdown" id="countdown"></div> <p>We will reopen at 8:30pm on <?php echo $end_date; ?>.</p> <p>Current Date: <?php echo $current_hebrew_date; ?></p> </div> </body> </html> <?php exit; } else { header("Location: index.php"); } I believe this solution will work when IPS 5 is released as well, thus this solution is "future-proof" until the PHP syntax itself changes and the script needs to be adjusted for PHP 9 or PHP X whenever that comes out. 
    Shalom! ~Andrei
  5. Like
    DawPi reacted to Matt Finger in IC 5: Editor Extension JavaScript Framework   
    Several questions have arisen regarding the v5 Editor Extension system. While we have yet to create a fully fleshed out dev docs center, I wanted to share a tentative, high-level rundown of what's possible.
    What you need
    Before continuing, I want to state this material is intended for developers. It is expected you have prerequisite knowledge of JavaScript, and have also read through and understand the tiptap core concepts. Lastly, I want to restate the extension framework is a work in progress subject to change, and therefore the specifics in this post are all tentative, whereas the final v5 docs will be posted elsewhere.
    Introduction
    It is possible to add 3rd party plugins which have direct access to the Tiptap APIs from the following editor methods
    ips.ui.editorv5.registerExtension(name, definition)
    ips.ui.editorv5.registerNode(name, definition)
    ips.ui.editorv5.registerMark(name, definition)
    The definition is forwarded to the corresponding Tiptap extension generator Extension.create(definition), Node.create(definition) or Mark.create(definition). Several important concepts and differences between the Tiptap definitions and the ones in ips.ui.editorv5 are noted below
    Add Buttons
    Perhaps the most important addition to the underlying Tiptap definition is the ability to specify an addButtons() method which adds buttons to the toolbar
    The method should return an object mapping strings to ButtonDefinitions, for example
    const buttonDef = { addButtons() { return { test1: { html: '<div>Red background</div>', command: ({commands}) => commands.toggleMark(this.name), locations: [ { after: 'bold'} ], isAvailable: editor => editor.can().setMark(this.name), isActive: editor => editor.isActive('bold') } } } } Button Lang Strings
    Make sure to register a lang string for the button either in the jslang.php file of the app or by calling ips.setString(key, value) directly. This string is used for the tooltip on the button, set it to an empty string to remove the tooltip.
    The button lang key is generated as follows ipsCustom{ExtensionType}__{ExtensionName}_{ButtonKey} where
    ExtensionType is Extension, Node or Mark and is determined by the type of plugin
    ExtensionName is the name you passed to registerExtension, registerNode or registerMark
    ButtonKey is the key in the object returned by addButtons()
    Button Content
    There are 2 ways to add content to a button:
    ButtonDefinition.html - String - This string is parsed, sanitized then set as the innerHTML of the button in the toolbar.
    All attributes except 'class', 'style', 'id', 'src', 'title', 'rel', 'alt' are removed
    All the following elements are removed: 'script', 'link', 'style', 'pre', 'code', 'iframe', 'object', 'embed', 'noscript', 'video'
    Only the first element is preserved. For ex, <div>some content></div><img /> would have to be wrapped in another element
    ButtonDefinition.element - HTMLElement - Alternatively, you can use a HTMLElement instance. It is sanitized in the same way as the html
    Also, note that, even if you specify an HTMLElement, only a copy of its outerHTML is inserted in the toolbar, so things like event listeners or references to the element will not return the element in the toolbar
    ButtonDefinition.command - function({...CommandProps, event?: MouseEvent}):void
    Called whenever the button is clicked. This function is passed the arguments object provided by editor.commands.command(props), with the additional property event which is the click event.
    ButtonDefinition.isActive - function(Editor):boolean|boolean|undefined
    This is called to determine if the button should have an 'active' class applied. It's passed the editor instance. Alternatively, you can pass a boolean to make it always active or inactive. If omitted, the button will never have the 'active' styling
    ButtonDefinition.isAvailable - function(editor):boolean|boolean|undefined
    This is called to determine if the button should be available in the toolbar. Like the isActive property, it gets passed the editor and returns a boolean
    ButtonDefinition.locations - (LocationDef|Location|null)[]
    The locations determine where the button will appear. Each element should be either the Location directly or a LocationDef. You null is interpreted as "put this at the end of the toolbar"
    Omit the locations array to add the button to the end of the toolbar
    Location - string - A location is a string representing a button key of another button in the toolbar.
    You can also put the button in dropdown toolbars using the following strings as a Location
    align__nested - the text align options
    format__nested - the extra options that exist inside the ... dropdown
    insert__nested - the + insert button (where the boxes and quotes natively live)
    LocationDef - Object
    LocationDef.before - Location|undefined - Optional: The key of another item in that toolbar that this button should be placed before. If there is no button with the provided key, the button is added to the end of the toolbar.
    LocationDef.after - Location|undefined - Optional: Same as before, except this button will appear after the provided button.
    If you define both LocationDef.before and LocationDef.after, the after rule will apply unless that item is nonexistent
    See the [data-toolbar-item] attribute of items in the toolbar to get the key of items.
    Use traditional JS functions
    All the root-level methods of the definition object get bound to the built extension, so it is very important you use traditional functions instead of arrow functions for the root-level methods. For example, the following would not work
    ips.ui.editorv5.registerNode('myextension', { addButtons: () => ({ makeRed: { html: "<div>make red</div>", isActive: editor => editor.isActive(this.name), ... } }) }) But this would
    ips.ui.editorv5.registerNode('myextension', { addButtons() { return { makeRed: { html: "<div>make red</div>", isActive: editor => editor.isActive(this.name), ... } } } }) Conversely, it is recommended to use arrow functions instead of traditional functions for any closures (functions created inside the root-level methods). Doing it this way ensures the this keyword is preserved. For example
    ips.ui.editorv5.registerNode('myextension', { addKeyboardShortcuts() { return { // BAD Enter({editor}) { return editor.commands.toggleMark(this.name) // `this` may not be defined as expected }, // GOOD Escape: ({editor}) => { return editor.commands.unsetMark(this.name) // `this` refers to the extension definition itself } } } }) The plugin name
    Unlike the Tiptap API, you don't need to pass a name in the definition itself. The editor method will automatically add the name depending on the extension type (Node, Mark, or Extension) and the name argument of the register<Node|Mark|Extension>() method. That being said, keep in mind
    You should be especially careful to make sure your name is unique. There can only be one extension of a given type with the same name.
    Use this.name in the definition methods rather than the string name you give. All the root-level methods of the definition are bound to the generated extension so no worries about this not being defined
    Be careful adding __ (double underscores) to the name, or to the restrictions (see below) for that matter. This can potentially lead to conflicting lang strings... for example if the extension is my__extension, and someone creates another extension named my with a restriction extension, the restriction's lang string will likely conflict with this extensions' lang string.
    Restrictions
    The Editor has 3 possible states: Minimal, Standard and Advanced. Community Admins can configure which user groups use which state, and can add restrictions to a given state level. For example, the feature "convert links to iframes" can be restricted to the Advanced Editor; in this case, the raw_embed restriction will be present unless the Advanced Editor is used.
    From the perspective of apps, however, each restriction is a string, and you can see if a restriction is active by checking editor.options.restrictions.has(restriction) (editor.options.restrictions is of the type Set<string>). When a restriction is present the functionality corresponding to it should be disabled. The editor has no knowledge whether it's in the Minimal, Standard or Advanced state, but only whether the restriction string is present.
    You can define restrictions for your extension by adding an array of strings as the property restrictions in your definition. Every restriction
    Must contain only letters, numbers dashes and underscores.
    Gets prefixed before passing to internal handlers with ipsCustom(Node|Mark|Extension)__{extension_name}__, where Node|Mark|Extension corresponds to the extension type, and extension_name is the name arg passed when registering the extension. It is a lot to type but this ensures there won't be conflicts with other restrictions. This prefixed name is also what gets added to the set editor.options.restrictions
    Must have a lang string containing the human-readable name registered. The lang string tells admins what the feature does, and a warning is raised when there is not one. This can be added either to jslang.php in an app before building it, or by calling ips.setString(restrictionKey, 'Human Readable Name')
    For example, in the js:
    ips.ui.editorv5.registerNode('myNode', { restrictions: [ "can_add" ], addButtons() { return { addSomething: { isAvailable: editor => !editor.options.restrictions.has('ipsCustomNode__myNode__can_add'), html: '+', } } } }) To add the lang string in the JS, you'd add this before or immediately after registering the node
    ips.setString("ipsCustomNode__myCustomNode__can_add", "Can add myNode nodes?"); Or, ideally, in jslang.php, add
    $lang = array( // ... other keys ... "ipsCustomNode__myCustomNode__can_add" => "Can add myNode nodes?", ); A note on Privileges vs Restrictions
    A privilege-based system assumes a feature is disabled by default, whereas a restriction-based system assumes it's enabled by default. The Editor Restriction System is, well, restriction-based. Therefore, though it is technically possible to use a restriction as a privilege, where a feature is disabled unless the restriction is present, it is strongly discouraged because it creates a counter-intuitive UI for Admins: it will disappear when a user is less restricted.
    The Empty Restriction
    You can also define a restriction with an empty string as the unprefixed key. When this restriction is present, the extension isn't added to the editor instance. For every other key, the onus is on the developer to ensure the restriction is enforced accordingly.
    ips.ui.editorv5.registerExtension('restrictibleExtension', { restrictions: [ "" ] // "" disables the extension altogether }) ips.setString('ipsCustomExtension__restrictibleExtension__', "Can use the restrictible third party extension") Descriptions
    For any given extension restriction lang string, you can add a more detailed restriction by creating a lang string with the same key suffixed by :description. This description appears in the AdminCP Restriction Configuration Form.
    For example, if the restriction itself after prefixing is ipsCustomNode__mynode__, the description would be stored in the lang string ipsCustomNode__mynode__:description.
    HTML Escaping
    Lastly, it is also worth noting, for security purposes, any html inside the restriction name or description will be sanitized. For example, the lang definition "<code>" is inserted in the AdminCP Restriction Form's source HTML as &lt;code&gt;
    IPS Plugins are Sandboxed
    All the IPS plugin definitions are sandboxed, meaning any properties in the definition that are not whitelisted will be removed.
    The biggest property that is removed is addProseMirrorPlugins(), but any property not in the following keys will be removed
    [ 'name', 'group', 'isInline', 'isBlock', 'isText', 'selectable', 'exitable', 'atom', 'addOptions', 'addKeyboardShortcuts', 'addAttributes', 'addGlobalAttributes', 'renderHTML', 'parseHTML', 'onCreate', 'onUpdate', 'onBeforeCreate', 'onFocus', 'onBlur', 'onBeforeCreate', 'onSelectionUpdate', 'onDestroy', 'onTransaction', 'priority', 'defaultOptions', 'addInputRules', 'marks', 'addNodeView', 'whitespace', 'defining', 'isolating', 'renderText' ] Priority
    The priority key's default value is higher than the Tiptap default. It is recommended to not specify this in the definition unless you know for sure you need to override other custom plugin commands, keyboard shortcuts, or HTML converters, there is no need to set this.
    How to load the code?
    Method 1: Using an App (best practice)
    In most cases, it's best to add your extension inside a custom app. In most cases, the extension will define a new type of content that is not whitelisted by the backend Parser, so it is lost during sanitization.
    This is why it is beneficial to use an app which has both the extension and a parser rule to whitelist the element/attributes. It also adds organization to your customization so that you won't forget where or how it's setup.
    To do this, simply put your plugins in *.js files in <your app dir>/dev/editor/. When the app is built and installed it is all compiled and loaded seamlessly on the front end
    Method 2: Using the ips:editorBeforeInit event
    For simpler plugins that do not require any new content types (for example a <span> with a style attribute), you can indeed add them inside a <script> tag anywhere in the page, with either inline or remote JS code. To ensure that your extension is registered after ips.ui.editorv5 is created but before the editor is actually created, hook onto the event ips:editorBeforeInit which is fired on the document. For example
    <script type="application/ecmascript"> document.addEventListener('ips:editorBeforeInit', () => { ips.ui.editorv5.registerMark('redBackground', { parseHTML() { return [{tag: 'span', getAttrs: node => node.style.backgroundColor === "red" && null}] }, renderHTML() { return ['span', {style: 'background-color: red'}, 0] }, ... }) }, {once: true}) // the once:true flag is very useful because it prevents the same code from needlessly running and replacing the extension over and over </script> This code can go anywhere, but directly in the theme is a good place to start. Note it gets cumbersome very quickly this way
    The actual Event is a CustomEvent instance that has the following in its detail property
    elem : HTMLElement - The element that has the data-ipseditorv5 attribute
    textarea: HTMLTextAreaElement - The actual textarea that is being replaced with an editor in a form
    content: string - The starting content of the editor.
    options: Object - The config that is about to be passed to the editor. You can modify this object to change the default configuration, but note that this is stateful - you'd have to read/update the options each time the event fires instead of just once like for registering extensions.
    Font family support
    It is possible, when listening to this event, to add or change supported font families. At the core, a font family consists of
    A main property. This is either a global family default (see below) or a string to be added as the first entry in the font-family CSS property
    An array of fallbacks. The entries, like main, are either a string or a global font family default
    The editor option ipsFontFamily.additionalFontDefinitions defines additional fonts as an object mapping the name to the font definition. For example, to add fonts from the ips:editorBeforeInit event
    document.addEventListener('ips:editorBeforeInit', e => { e.detail.options.ipsFontFamily = { additionalFontDefinitions: { "Comic Sans": { // the user will see "comic sans" in the dropdown main: "Comic Sans MS", // this is added to the CSS property fallbacks: [7] // 7 corresponds to 'sans-serif'. The compiled font family property will be `font-family: "Comic Sans MS", sans-serif; } } }; }) Extending Fonts
    For any builtin fonts, you can define them in your plugin to change their behavior.
    For example, if you have MS-specific versions of Helvetica installed on your community, you could set fallbacks: ['Helvetica MS']. This will make Helvetica MS the first fallback, while preserving the default fallbacks after it.
    Global Family Constants
    In css, certain keywords are accepted as the font family which will translate to dynamic CSS behavior or OS preset fonts. The following numbers can be used in lieu of a font string to embed these keywords. Note the type number MUST be used in the js, not the stringified object property shown below
    { "6": "serif", "7": "sans-serif", "8": "monospace", "9": "cursive", "10": "fantasy", "16": "emoji", "17": "math", "18": "fangsong" } Builtin support for unknown fonts
    The option ipsFontFamily.allowUnknownFonts works as follows.
    When processing HTML, if there exists a span[style] tag in the HTML that defines a font-family and the font is unknown, the editor will construct a temporary font family definition and preserve its value. That being said, the custom font will be forgotten should the user change the font to a builtin choice; to ensure an option remains visible, you'll need to define it in your extension. It is generally good practice to not allow these fonts as they will have varying support across devices.
    Example Plugin
    This is an example of an Extension which will register a Mark that creates <kbd> elements to denote keyboard shortcuts
    ips.ui.editorv5.registerMark('myKbdElement', { exitable: true, parseHTML() { return [{ tag: 'kbd' }] }, renderHTML() { return [ 'kbd', { style: ` border-color: var(--i-color_hard); background-color: var(--i-background_2)` }, 0 ] }, addButtons() { return { test1: { html: '<span><i class="fa-solid fa-keyboard"></i></span>', command: ({chain}) => chain().toggleMark(this.name).focus().run(), // This puts the button before bold, after the 'link' button, inside the `...` menu and at the end of the toolbar locations: [ { before: 'bold' }, 'link', 'format__nested', null ], isAvailable: editor => editor.can().setMark(this.name), isActive: editor => editor.isActive(this.name) } } }, addKeyboardShortcuts() { return { // "Mod" is command or ctrl, depending on system defaults; "Mod-Shift-K": ({editor}) => editor.chain().toggleMark(this.name).focus().run() } }, restrictions: [ "" ] }) // This sets the restriction string. Ideally, this should go in the jslang.php of your app but it is ok to do this here ips.setString("ipsCustomMark__myKbdElement__", "Can apply keyboard styles"); ips.setString("ipsCustomMark__myKbdElement_test1", "Keyboard Command"); Note that, in this case of <kbd> elements, you'd also have to add a parser rule via the AdminCP Dev Center to allow them to be saved.
  6. Haha
    DawPi reacted to Matt in ipsGrid   
    Ehren, you look different today.
  7. Like
    DawPi reacted to David N. in Bulk Mail "send test mail" button to send mail to myself   
    I wish the Bulk Mail feature had a "send test mail" button to send an email to myself to check what it looks like before proceeding with the Bulk Mail. 
    Meanwhile my workaround is to save the Bulk Mail with only the Admin selected and proceed. 
  8. Like
  9. Like
    DawPi got a reaction from Sonlong in Invision Community 4: A more professional report center   
    Wohoo! This is something truly valuable for so many communities!
  10. Like
    DawPi reacted to Matt in V5 Release Question?   
    Hi Zak,
    It's a good question. Developers are always reluctant to give a ballpark figure for when they expect a product to be released for two reasons: firstly, they are overly optimistic about how long things take, and secondly once a date or month is given, it starts a countdown. If we miss that date then it becomes a bit of a stick to wave at us.

    All that said, we are confident that we'll release v5.0.0 final in Q1 2025. It will probably feel like quite a soft release as we won't update our website, etc, and we'll offer it alongside v4 which will be supported for quite a while yet. We'd expect most will stick with v4 while testing out v5 and waiting for it to mature a bit before converting over.
  11. Agree
    DawPi got a reaction from Joel R in Invision Community 4: A more professional report center   
    Wohoo! This is something truly valuable for so many communities!
  12. Like
    DawPi reacted to Jimi Wikman in Invision Community 5: A video walkthrough creating a custom theme and homepage   
    It is an honor to give a little something back to Invision Community that has been the source of so many fond memories!
    I hope it will show some of the many capabilities the amazing team have created for us!
  13. Like
    DawPi reacted to Matt in Invision Community 5: A video walkthrough creating a custom theme and homepage   
    Can you start from a stock Invision Community 5 installation and have it themed, customized, and a new homepage built in under an hour without relying on custom templates and coding?
    Yes, and Jimi Wikman, a long-time Invision Community customer, did just that in his latest YouTube video.
    Jimi has over twenty-five years of experience in development and twenty years of experience in graphic design.
    Invision Community 5 has been in testing for a few months now, and Jimi produced this amazing walkthrough of Invision Community 5's new page editor and theme editor while re-creating his own site.
    Our vision for Invision Community 5 was to put the power into the hands of everyone, not just those who are proficient in PHP, HTML, and CSS. Jimi's video shows this vision as a reality as he moves through the theme editor to create his custom theme, and the page editor to build a custom homepage.
    Sit back and enjoy watching Jimi put together a new site.
    Thanks Jimi!
    If you're interested in testing Invision Community 5 for yourself, just join our Beta Testing Club.

    View full blog entry
  14. Like
    DawPi reacted to Nathan Explosion in How or where change time format AM/PM to 24h   
    ?
    @bosss go into your languages and ensure that the locale is set correctly.
    Default for a language is "English (United States)"

    result:

     
    I change to my actual locale:

    Result

    Swedish

    Result

     
     
     
     
  15. Like
    DawPi got a reaction from Joel R in [IC5] Further development plans for the application system?   
    Hello,
    it was discussed a lot my friend. Read this entry first:
    https://invisioncommunity.com/developers/devblog/blog/ic5-introduction-to-listeners-r8/
    Best regards and good luck! IC5 isn’t as bad as it might seem at first. 😉
  16. Like
    DawPi reacted to Baian007 in Well hello Beta 2, where have you been?   
    For me (self-hosted ), the upgrade was successful. The package was downloaded manually.
  17. Like
    DawPi reacted to Matt in Well hello Beta 2, where have you been?   
    Beta squad! (I'm trying something new, don't judge me)
    Invision Community 5.0.0 Beta 2 is floating through our cloud deployment system and should be available soon.

    There's a lot fixed in this version, so thank you for your patience over the past week or so. The full list of fixes is here: https://invisioncommunity.com/release-notes-v5/
    Hopefully we didn't add to many new bugs. 🤞
  18. Thanks
    DawPi got a reaction from Daniel F in App that can create dev folders for plugin and apps needed   
    https://github.com/codingjungle/toolbox
  19. Like
    DawPi reacted to Adriano Faria in App that can create dev folders for plugin and apps needed   
    Dev Toolbox from @CodingJungle.
    The 4.7 will work only for apps (plugins removed). The 4.6 version works for plugins and apps.
  20. Thanks
    DawPi got a reaction from TDBF in Third Party Developer Version 5 Question   
    Hm,
    https://invisioncommunity.com/forums/forum/533-invision-community-5-modification-questions/
  21. Like
    DawPi reacted to Ryan Ashbrook in Welcome to Beta 1   
    Download should be available now.
  22. Like
    DawPi reacted to MythonPonty in Welcome to Beta 1   
    Biiiiig Thanks to you @Matt and the whole team. You've spend so much time last year... I'll check the upgrade for my community tonight (German Time) 😉
     
  23. Like
    DawPi reacted to Matt in Welcome to Beta 1   
    Welcome to Beta 1!
    We finally made it! After three months of intense alpha testing, and many more months of development, we're ready to move into beta testing.

    For a full run down of how to access the beta, see the overview page.
    A reminder that beta software will contain issues. We've done a lot of testing, but only limited testing upgrading from v4, so there's likely to be issues for some depending on server OS, and other site specific factors. It's best you don't immediately update your production site. 🙂 

    I want to extend my thanks to everyone that was involved in the early focus group, the very early alpha testing and the more public alpha testing. Each click, each error hit and each bug report moved us forward and I'm very grateful for your help.
    Now we enter the most exciting phase, the last stretch before a full release!
    You'll be able to download a little later today.
  24. Like
    DawPi reacted to Interferon in Next Step: Bulk add externally hosted files in the Downloads system   
    I found a service provider here who is able to complete this task, so it's basically solved:
    https://invisioncommunity.com/third-party/providers-directory/
  25. Thanks
    DawPi reacted to Daniel F in [this site] forums/front/topics/postContainer bug   
    Thanks, resolved.
×
×
  • Create New...