Leaderboard
Popular Content
Showing content with the highest reputation on 03/23/2021 in all areas
-
Awesome! Great to hear that! Sometimes you just have to stare at the code a bit of time until it clicks, keep on it! Let me know if I can help you with something else.3 points
-
Well, yes and no. Two migration modules already exist in ProcessWire, but neither suited my needs: “Migrations” by @LostKobrakai seems effective but quite onerous to use and has been deprecated in favour of “RockMigrations” RockMigrations by @bernhard is simpler and has a nice declarative method: migrate(). However, it is ideally suited to “headless” development, where the API is used in preference to the Admin UI. This is great for professional PW developers, but for occasional developers like me, it is much easier to use the UI rather than just the API. In addition there @adrian's ProcessMigrator which is designed for migrating page trees. Concept I wanted something to achieve the following: To allow development to take place (in a separate environment on a copy of the live database, or on a test database with the same structure) using the Admin UI. When finished, to permit a declarative approach to defining the migration and implementing it (again in the UI). To allow testing of the migration in a test environment on a copy of the live database. To allow roll-back of a migration if installation causes problems (ideally while testing rather than after implementation!). To provide a record of changes applied. Although not originally intended, the module I developed also allows the selective reversion of parts of the database by exporting migration data from a backup copy. Also, if changes are made directly on the live system (presumably simple, low-risk mods – although not best practice), it allows reverse migration to the development system in a similar fashion. I should emphasise that what I have built is more of a 'proof of concept' than a fully-fledged module. The code is pretty hacky and uses some stuff outside of the module itself. Lots of validation is missing. However, I have used it successfully in a number of small tests and a medium-sized live migration. If there is sufficient interest, I will tidy the code and make it available, but it would still need input from better coders and PW-savants than me to make it into something more widely usable. EDIT: Please note that the module has moved on a bit from this original post - the design has changed somewhat to make it more robust and flexible and additional features have been added. Please see the help file for full details. I still consider it to be at alpha stage, however, so use with care - test before making migrations and always take backups first. Design The module has the following principal components: A PW module “ProcessMigrateData”, bundled with a bootstrap migration in the same ProcessMigrateData folder, to be placed in the site/modules folder; A Page Class “MigrationPage” to be placed in the site/classes folder; Php files migrationActions.php and migrationControl.php to be placed in the site/templates/RuntimeMarkup folder (and migrationActions.js to be placed in site/templates/RuntimeMarkup/scripts). There are also a methods which need to be put in class DefaultPage and a functions in the init.php file. The module requires the FieldtypeRuntimeMarkup module. Migration definitions are held in .json files in the ProcessMigrateData/migrations/{migration name} folder (I might move this). This folder contains up to 2 sub-folders - “new” and “old” which each contain a file called a migration.json file, which defines the scope of the migration in terms of fields, templates and pages, and also one or more of fields.json, templates.json, pages.json and remove.json. The first 3 of these files contain the field, template and file definitions within the migration scope and the remove.json file simply lists fields, templates and pages to be removed. These migration files are mirrored by pages of template “Migration” under a parent /migrations/ of template “Migrations”. The mirroring happens in two ways: If a new migration is created in the module (from the Setup -> DB Migration menu), then initially no json files exist. The json files are created, after the scope of the migration is defined on the page, by running “Export Data” from the eponymous button. If json files exist, but there is no matching migration page, then the latter is created by the module on accessing the DB Migration admin page. In this case, we are in the “target” database so there is no “Export Data” button, but instead “Install” and/or “Uninstall” buttons. Migrations therefore either view the current environment as a “source” (type 1) or a “target” (type 2). Installation The module creates templates called Migration and Migrations and a page below the root named ‘migrations’. Open the admin page “Setup -> DB Migration” to create a migration. One (“bootstrap” is already installed) and cannot be modified. The pic below illustrates the DB Migrations page in the source environment. The status of a migration (as a source page) can be ‘pending’ or ‘exported’. ‘Pending’ means either that the migration data have not yet been exported or that the current export files differ from the source database. On opening this page in the target environment, the individual Migration pages (type 2) are created from the definitions in their respective /new/migration.json file. The pic below illustrates the DB Migrations page in the target environment. In a target environment, a migration status can usually be ‘indeterminate’, ‘installed’ or ‘uninstalled’. ‘Indeterminate’ means either that the migration has not yet been installed (so no ‘old’ files containing the uninstall definition exist yet) or that the current state matches neither the ‘new’ or the ‘old’ state. ‘Installed’ means that the current state matches the ‘new’ definition and ‘uninstalled’ means that it matches the ‘old’ definition (i.e. it has been actively uninstalled rather than not yet installed). When carrying out development work, you keep a note of what fields, templates and pages you have added, changed or removed. The module does not track this – it is a declarative approach, not a macro recorder. Also, it does not handle other components such as Hanna codes and Formbuilder forms. These come equipped with their own export/import functions. You can update a migration page as you go along, rather than keep a separate note of changed components. The migration page also allows you to document the migration and add any number of “snippets”. These snippets do not do anything, but can be a convenient place to store (for example) Hanna code exports for pasting into the target environment and help to make the page a comprehensive record of the migration. See example below: Note that migration pages just define the scope of the migration. It is entirely feasible for other parts of the dev database to be changed which are outside this scope and which will therefore not be migrated. After sync'ing code files to the target environment, the new migration will be listed on the setup page. On the migration page, in the target environment, there are “preview” buttons to see what changes will be implemented. The migration can then be 'installed'. See example of the migration page in ‘installation’ mode below: That's the gist of it, but inevitably there are complications. Happy to discuss and share further if there is interest in this.1 point
-
Hey folks, @kongondo asked me some questions about how I integrated vue.js into ModulesManager2. I was already planning to release a tutorial video of the integration process soon, but I don't have much time now as I am busy with customer work. So here is a quick roundup, which will be improved over time and become a full-blown tutorial. I hope to cover the basics and don't forget anything. How did you implement the integration? I created a new vue project via vue create . inside my site/modules/mymodule folder Do your assets still live under the Vue JS public folder? I don't exactly know what you mean with assets. Are you speaking of images? I don't use images atm. Where do your view files live, i.e. under your modules directory or in templates? As I mentioned in point one, they are in the modules directory. Here is a screenshot of my directory: As soon as I release the beta of ModulesManager2 you can go through the source code in github. Where is your index.xxx file and how are you serving it? vue-cli comes with a built in server and the index.html is automatically generated on-the-fly. The command for running the server with HMR (hot media reload) resides in the package.json and is run via npm run serve This is the standalone server. Anything else I should know (maybe .htaccess issues, etc)? Create a vue.config.js in your custom module's root directory and add following parameters to it, to disable filename hashing: const webpack = require("webpack"); module.exports = { runtimeCompiler: false, filenameHashing: false, pages: { main: { // entry for the page entry: 'src/main.js', // the source template template: 'public/index.html', // output as dist/index.html filename: 'index.html', // when using title option, // template title tag needs to be <title><%= htmlWebpackPlugin.options.title %></title> title: 'Index Page', } }, configureWebpack: { plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery', }) ] } }; Edit: After creating the config run npm run build Then you can reference these files in your module like I did here: $markup = '<div id="app"></div>'; $scriptPath = $this->config->urls->siteModules . $this->className; $markup .= "<script src='$scriptPath/dist/js/chunk-vendors.js'></script>"; $markup .= "<script src='$scriptPath/dist/js/main.js'></script>"; I added the configureWebpack part to have access to the $ and jQuery objects inside of my vue files. The install/uninstall overlay panel in MM2, is that something custom or a ProcessWire panel? Standard ProcessWire panels If it is a ProcessWire panel, did you have any difficulties implementing it into your Vue app? ProcessWire's panel init happens before vue is initiated or rendered, so pw-panel links inside of vue are not catched. To make pw-panel links inside of vue work, you have to defer (don't know if this is the correct term) the process to a body click event: $(document).on("click", "#app .pw-panel", function (e, el) { e.preventDefault(); let toggler = $(this); pwPanels.addPanel(toggler); toggler.click(); }); I hope this helps. If you have questions, please ask.1 point
-
@Ivan Gretsky - sorry for the trouble - could you please debug which of these conditions (https://github.com/adrianbj/AdminRestrictBranch/blob/4964a3f5b83338f7313f7c6daeefe6c6793640b0/AdminRestrictBranch.module.php#L228) is resulting in the error message? And if it's the last one, then figure out where in this method: https://github.com/adrianbj/AdminRestrictBranch/blob/4964a3f5b83338f7313f7c6daeefe6c6793640b0/AdminRestrictBranch.module.php#L236 or in this hook (https://github.com/teppokoivula/AdminRestrictBranchSelect/blob/3ac88e7f4da482a5a16dad1abe3f221fdaeb2742/AdminRestrictBranchSelect.module.php#L54) in @teppo's module it's returning "1", rather than one of the allowed branch parents? BTW - are you having the same issue with ARB without this addon module?1 point
-
If I understand correctly, this should do it: https://github.com/adrianbj/TracyDebugger/blob/481a548a4d9f09784ccb1c7f598212e2923b2191/TracyDebugger.module.php#L774-L7841 point
-
I’m only aware of this term in the realm of UI design. If that’s what you mean, ProcessWire will not get in your way implementing such a user interface, since it’s very output agnostic. It’s not clear to me what you’re trying to do. Do you mean this? https://en.wikipedia.org/wiki/Single_Table_Inheritance ProcessWire’s data model doesn’t involve inheritance, if that’s what you mean? You can get a pretty good idea of PW’s database strategy by looking at the tables of an existing PW installation.1 point
-
No, CKEditor isn't a supported inputfield. I expect it would create rendering issues in the tag if it contains HTML, and if you are putting anything more than a short piece of text in your "read more" it would result in a huge, cumbersome tag widget. Instead I think you should wrap the "read more" text in "open" and "close" Hanna tags. [[rm-open]] <p>Your text here.</p> [[rm-close]] Then replace the [[rm-open]] with a "Read more..." button and a div open tag, and the [[rm-close]] with a div close tag. Use JS to toggle the visibility of the div when the button is clicked. You could also look at TextformatterPagination and TextformatterAccordion for inspiration but I think the above method would be the simplest.1 point
-
1 point
-
Does this help? https://processwire.com/modules/fieldtype-image-marker/ I have modified it to use the coordinates, but not show the marker on the frontend. Otherwise, perhaps you could build in fieldtype around this https://github.com/maschek/imgmap/1 point
-
How are you doing your markup? You should have something like this: <input type="checkbox" name="color[]" value="red"> <input type="checkbox" name="color[]" value="blue"> Now color is an array: $selector = ""; $colorOptions = $sanitizer->array($input->get->color,'text'); if(count($colorOptions){ $colorOptions = implode('|',$colorOptions); $selector = ",color=$colorOptions"; }1 point