ModX: Duplicate entire site for testing new template? - modx

I want to test a new template & CSS for a site redesign.
Is there any "easy" way to do this?
I'm not familiar with Contexts. Theoretically I'd like to duplicate the main context, then experiment with it ... but how can I access it without having to mess around with subdomains, htaccess, etc.?
Is there any way to "go" to a 2nd context via simple URL?
E.g., say our "live" site is at "www.foo.com" ... I want to duplicate that context, call it "testing", then be able to navigate to the root of the 2nd context with "www.foo.com/testing".
So the duplicate of "foo.com/container/page" would be at "foo.com/testing/container/page" in the 2nd context.

Your best bet is to create a completely separate ModX instance. Contexts serve a different purpose.
On this instance you can edit your existing templates, TVs, chunks, etc. without affecting your master instance, overloading it, nor putting it at risk (specially if it's production). Once the test instance is ready you can easily copy over those edits to your master instance.
In summary the steps would be the following:
Create a new ModX instance and copy data (DataBase & files) from the master instance.
Configure, edit and test your new ModX instance: test.domain.com
Copy over the edits to the master instance following the same guide on step 1.
If you want to have more control over what gets imported and exported on steps 1 and 3 you can use the tool Teleport and check out this video tutorial.
If you use ModX Cloud steps 1 and 3 are easier to accomplish.

Related

MODx Revolution Multidomain/Contexts same content

I have a MODx website. It has 3 different contexts. Each context point to an other domain.
In one context (lets say it is C1), I have a resource (a folder) that has many child resources.
I display the resources with a pdoresources-call (frontend). Everything works fine. It lists/display the resources as it should be. When I click on it, it open as well and show me the content of the resources (The site ist something like a block)
But when I go to an other context (C2) and make the same pdoResources-Call
it lists/display the resources as well. But when I click on the resource nothing happened. It do not open because it is another context.
How can I setup MODx Revolution to have different contexts that all can share content (Resources)
If you organize your resources in a tree with each domain as its own branch, you should setup a single "Start ID" for each context. That happens in the context settings (via main menu).
The full process is beeing described here: https://black-pixel.net/2014/02/24/multilingual-multidomain-site-modx-cms/
Maybe you have to call the PDO-Tools call uncached. Or to make sure, place the call into a chunk, duplicate it and place the context key into it (to have 3 different calls, one per domain).
[[$subtree-call-C1]] for C1 etc...
It sounds like it may be pointing you to something like seconddomain.com/parent/child.html while it should be pointing to firstdomain.com/parent/child.html. If that's the case, you should make sure that each of your contexts has the site_url (and related http_host and base_url) context settings, so that MODX knows to send you to a different domain.

How can I make Content Items without a CommonPart appear in the content list?

I created a custom Type that has a UserPart attached to it.
According to this issue on GitHub you can't add a CommonPart to content that also has a UserPart because it causes a StackOverflowException but I would still like items of my custom Type to show up in the content list. I already store CreatedUtc and PublishedUtc in the custom PartRecord, can I manually plug these in somewhere?
EDIT: For clarification, my specific scenario is that I am building a public facing Orchard website based on existing data that was used in a private application up to this point. I have a legacy table with user accounts that need to be mapped to Orchard Users but they also represent travel agencies that visitors should be able to browse and that Orchard admins should easily be able to edit and create through the Dashboard. I got the idea to create a TravelAgency type with a UserPart from Sipke's webshop tutorial
Content Types do not require to have a CommonPart to show in the Content List. If i remember properly its done by triggering the Creatable() in your migrations.
Also if you have a UserPart, you could Lazy loaded or just reference it via Foreign Key.
Why would you like something like that to be part of the Content List? I usually keep my business-specific Content Types tucked away in a nice section, so there are easier to visualise and use for users.
There is definitely a bug but as they comment you could extend taxonomies to accomplish your task and keep in mind sometimes changing the Orchard Codebase might fit your purposes, you only have to keep track of your changes when you upgrade next time. I have done it a couple of occasions to fit my projects.
If i remember properly, its been a while.. If you look in the core code where the Content List is created it looks for Creatable() Types. digging even more inside the code, chances are the Query in charge will join the CommonPart, hence your problem. You could easily add another query in the controller and add whatever you are after. The problem though, will be refactoring the rest of actions to accommodate your your type too. Way easier isolating your new Type. had to look at it for you, check this baby: Orchard.Core.Contents.Controllers.AdminController

What is the best practice for overriding strings in Orchard CMS?

I often have the situation where the wording of specific strings from various modules or core features needs to be changed for specific tenants & themes in Orchard CMS.
For example, I may have a client that prefers to have the shopping cart checkout button say "Checkout Now" rather than "Go to checkout" which is a string contained within a view in a shopping module.
I can simply override the razor view in my theme and change the string, however views often are quite complex, and it doesn't feel right overriding a view just to change one string.
Another approach I have tried is to define a po translation file within my theme to override the string from the module. This works because the strings in the module are defined using the T() syntax. However, I've noticed that as soon as I define an override for a string within my theme, this override effects all tenants, instead of just the one tenant that has this theme enabled. I'm inclined to think that translations within modules/themes should be ignored from tenants where they are not enabled.
So I'm left wondering what the best approach for this scenario is?
The localisation/po file approach would be ok if tenants ignored po files from themes that aren't enabled, but then again, it would be really nice if there was a module or feature in core that allowed you to specify string overrides via the admin interface. I guess it's more of a "rewording" task than a "translation" task.
The preferred way of doing this is through template overrides. If you don't want to do that, you can actually break shapes down, and delegate the rendering to smaller templates that are easier to override. This is done by simply refactoring the part of a template that you want to be able to override individually into a separate template. This post explains how to do that: http://weblogs.asp.net/bleroy/creating-shapes-on-the-fly
If you're not willing to do that, you can use this module to get strings from the database instead of po files: http://gallery.orchardproject.net/List/Modules/Orchard.Module.Q42.DbTranslations It should be possible to modify it to fit your sceanrio.

Best Practices for Content Types in SharePoint

Recently, we came across a severe problem in production farm with the Content Types. I would like to explain the background of this problem first.
We have nice working feature for Content Types installation in production and test farms. We developed and deployed (using wsps) this SharePoint feature in Visual studio. We are using the publishing pages using page layouts and Content Types to help content editors to quickly publish the web pages. Unfortunately, some Content Types and site columns have been manually updated/added by some people in the production, so whenever I (developer) make some changes to the existing Content Types (using Visual Studio and feature activation/deactivation) , SharePoint removes one or two columns (during feature activation/deactivation) from Content Types; or the columns which have not been added in a best practice way. I think the best practice is to update Content Types using Visual Studio.
Now, I wish to ensure that site columns shouldn't get removed from Content Types upon feature activation/deactivation.
Note: Our feature for Content Type activation/deactivation doesn't hold any activation dependencies in the feature.xml
Recommended Approach
Based on all these factors, my suggestion would be to:
• Create two Features: one for the original markup and one for making changes. (Or you can put them in the same Feature; I just want to differentiate between where you do what.)
• The original Feature should contain the CAML for Site Columns and Content Types. This ensures the IDs have been assigned ahead of type and remain constant.
• If you want to update a Site Column by changing nearly anything about it except its Field type, do it using a Feature Receiver. By doing this, you can call the Update method and pass in a boolean indicating if you want all the existing assets in the site that inherit from this to update to, (something you couldn't do via the CAML.)
• You can also add an existing Site Column (that you provisioned via the CAML feature) to an existing Content Type (that was provisioned via the CAML feature). This is helpful if the Column was not part of that Content Type before, etc.
• In a scenario like the one I just mentioned in the last bullet point, it's necessary to deactivate and reactive the CAML feature (to provision the new assets) before calling your Feature Receiver. What will this mean for the site? Since all the Site Columns and Content Types in the lists in the site are using the same ID's as the ones provisioned in the Site Collection root, removing its parent from the Site Collection won't change that. It might leave it orphaned temporarily, (i.e. there will be no relationship between that item and an item in the Site Collection root, but it will function the same way it always has, since it's really a fully-functioning copy of the original item) until you reactivate the Feature that puts the item back in the Site Collection. It's like the parents are going on vacation when you deactivate the Feature, and are coming back home when you activate the Feature again.
You have a choice when it comes to how you maintain the CAML and the Feature Receiver, since you have two scenarios: existing Site Collections and new ones.
• You could make a policy that every time you write code in your Feature Receiver to update a Site Column or Content Type, you have to make the change in your CAML as well. That would mean that every time you activated the CAML Feature in a "fresh" Site Collection, the CAML would be up-to-date and accurate; there would be no need to run the "updater" feature. (In your Feature Receiver, you should make sure you do some extra checking to make sure a Site Column doesn't already belong to a Content Type before adding it, etc. in case that change is already in place before the code executes.) This approach means you only have to execute one Feature when creating a new Site Collection, but it also means you're maintaining changes in two places: in your Feature Receiver for making changes to existing sites, and in your CAML for new sites. It's a cleaner approach, but also contains an element of redundancy, which always leaves room for human error.
• The other approach is to simply assume that every time the base CAML feature is activated, you're always going to execute the Feature Receiver. This approach says the only time you'd change the CAML is to add a new Site Column or new Content Type; otherwise, all the changes happen in the Feature Receiver. This approach reduces redundancy, but also means your Feature Receiver code could get quite large with all your changes over time, and it could leave your CAML as very much "legacy" over time.
Src: http://blog.beckybertram.com/Lists/Posts/Post.aspx?List=eb3e1762%2Dbab0%2D4e96%2D8bc5%2Dd67d6e6bfd44&ID=18
Updating Content Types is still one of the underdeveloped portions of Sharepoint which sometimes causes trouble, especially in Content Deployment scenarios.
The best thing in your case would be to always avoid making any changes to content types by hand (using UI)
Whenever you are installing the content type, make sure that you remove the previous one and then install the new one. (Sometimes its not possible due to pages being already created out of it).
My current approach to deploying content types is to do as much as possible using code rather than CAML. That way it is easy to fully control the logic of updates, including ensuring that changes made manually don't cause conflicts. I have the structure defined as attributes on an interface I also use for strongly typed list access, but there are several other ways you could do it.
The only piece that isn't available in the API is setting a specific content type ID, so you need to have a caml file for that, but it's a small/simple file, doesn't try to make updates and is only referenced from a feature that will also run the update code.

Proper way to hide place holders in a SharePoint 2007 Master Page?

I am working on a specialized instance of MOSS for a client where What I am wanting to do is hide elements on the master page. In particular, I want to hide the main top navigation bar, the search functionality and the label that shows up in the upper-left-hand corner that tells you the name of the site you are on. So I made a copy of the default.master, and then in SP Designer I set the visible attributes for the placeholders for these blocks to “false” in the new master file.
I can then assign the master to my normal site collection no problems and it seems to been working like I want it to. But when I go to look at the system pages (i.e. any of the forms or backend stuff), it is still using the old default master. And when I tried to set the System Master Page to my customized master file, my MOSS instance threw a File Not Found error. Then certain parts of the admin area just started failing in that same way (i.e. I would try to go into Site Settings -> Content and Structure and it also would throw a File Not Found error) Then at one point, the whole Site Collection would throw “Unknown Error” and there didn't seem to be a way to recover, short of reverting the state of the VM I am running MOSS in for development purposes.
So I am curious, what is the best way to create a custom master page and then hide elements on that page? I realized that my web cluster didn’t have the proper flag set up to actually show me real ASP error messages, so I am going to change that tonight when I get home and see what SP is really telling me about all of this. I have also read that changing the application.master file is not recommended, but I figured I could get away with making a custom page for the Site and System master pages and not worry about application.master. I have been reading a bunch of Heather Solomon articles as well as various other things. They all basically say that it’s ok to hide elements on a master page, but not delete them outright as SP will break if you do that. Would it be advisable to use a JS/CSS hack to manually hide elements that way, rather than actually making a new master page?
You create an asp:placeholder with the visible attribute set to false and place the contentplaceholders that are to be hidden in that container, weird I know but it works... as for the system.master you probably would want to make a copy of the system.master that SharePoint uses and then alter that one in the same manner.
Thank you so much for posting this. Works like a charm. I was so afraid because everyone says not to mess with the Application.Master. All I did was open it with Notepad and add Visible="false" (I wanted to hide the topnavigation bar because I have custom tabs that display depending on a user's permissions which are controlled by code in default.master. But then if a user had to upload a file, upload.aspx uses application.master and all the tabs would be displayed.)
I edited this line only:
wssuc:TopNavBar id="IdTopNavBar" runat="server" ShouldUseExtra="true" Visible="false"
Works like a charm!
Note that the following pages will also be affected:
Site Settings
View all site content
Workflow settings of a document library
Recycle Bin
Search results

Resources