Drupal 7 reverse node reference url effect - reference

I love using the Node Reference URL module but in the case of my current project I need something similar and with a slightly different effect.
I have a node type called Event which needs to have exactly 3 webforms referenced to each event I create.
With node_reference_url the configuration means I will setup the node reference fields in the webform node type with my Event type selected as the target.
However, I need to find a way of reversing that. I'm looking for code tips (or a module if it exists) which will allow me to configure the Event type so that I can have links on each event page to create a total of 3 webforms and their NIDs to be saved as references to the parent event page.

I am using entity reference to do such a thing. It allows you to add one or more reference fields to your content types. These references can be to nodes, profiles, etc.
If you would add these to your Event you could probably select the webforms from there.
I know this plugin also integrates with views (under advanced > relations), allowing you access the fields of the referred content. (Incuding the title and link to node options.)
Want to take it a step further?
Have a look at reference dialog. This module allows you to build similar reference fields combined with Add, Edit and Delete buttons. If the content you are referring to is not yet created, you can do so in an overlay.

Related

Drupal how to add a search filter to admin content page

I've never used Drupal before (development or managing content). I was asked to extend the admin content page to have a filter and simply don't know enough to get moving quickly.
Can anyone tell me if adding a search by text filter in the admin content area requires code or is there a CMS feature like adding a node for this task.
If code is required, is there something like a hook for this area? Not sure where to start. I will be investigating on my own but pointers to get me oriented to Drupal would help.
By default Drupal provides search mechanism ready to use. But there are also additional module which can improve search experience. You don't need any coding to use that search. You already have search form block ready to use.
Go to Structure -> Blocks and find block called "Search form". Now all you have to do is to put that block in some region and it will appear on front-end. Of course if it's not already styled by your theme it may be needed to put some extra CSS to make it look nice. There are also some template files which you can override and put some your HTML if you need.
There's also template file for search results page (which of course will work out of box also).
You may also need to create new block region if you want to place your form at some specific place, not covered by any existing region defined by your theme (easy thing to do!).
See https://drupal.stackexchange.com/q/30633/101329, the "Admin Views" module lets you configure the search form as you like.

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.

Can I use a Kentico macro to get a partial path?

I would like to know if it is possible to use kentico macros (not necessarily coding a custom one) to access part of the rewritten URL's Path.
Example: http://www.mysite.com/Category/Subcategory/
I would like to get the last part (Subcategory) so that I may then filter content dynamically. The reason I want to use the macro is to simply not have to have 20+ different page templates only so I can have different web part properties.
Assuming you are using Portal templates, and you don't want an 'all items in all subcategories' list on the parent:
Create an Article List web part on the parent page — parent to all the sub-categories.
Set the web part Path to /{0}/{1}/{2}/% (if your path was /Home/Parent/Subcategory for example) or something similar for your environment.
Use the default setting of Inherit for the page template for all subcategory pages.
This will not show anything on the parent page, and the sub-categories will show only the documents under themselves. Note: If you want the subcategory items to have their own views when user digs down to /{0}/{1}/{2}/item, you may need to filter by changing template inheritance, or Document Types on the web part, or something like that if you don't want the whole sub-category list to also show on the item-specific pages.
You can create a custom macro or, you can also use the string operations which are allowed within macros. Please see http://devnet.kentico.com/docs/6_0/devguide/available_macro_methods.htm#string_methods (and you can e.g. use the EndsWith or TrimStrart or something similar).
However, I think the best way would be to create a custom macro which will exactly fit. There might be some combination of macros and macro functions - but I think it is faster just to code a custom one which will cover your need 100%.
Also, you can take a look on the K# if there is something that will fit - http://devnet.kentico.com/docs/6_0/devguide/ksharp_syntax.htm

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.

SharePoint SPContext.List in a custom application page

I have a custom SharePoint application page deployed to the _layouts folder. It's a custom "new form" for a custom content type. During my interactions with this page, I will need to add an item to my list. When the page first loads, I can use SPContext.Current.List to see the current list I'm working with. But after I fill in my form and the form posts back onto itself and IsPostBack is true, then SPContext.Current.List is null so I can't find the list that I need to add my stuff into.
Is this expected?
How should I retain some info about my context list across the postback? Should I just populate some asp:hidden control with my list's guid and then just pull it back from that on the postback? That seems safe, I guess.
FWIW, this is the MOSS 2007 Standard version.
Generally speaking I try and copy whatever approach the product group has taken when looking to add functionality of my own. In this case they add their own edit/view/add pages via the list definition itself.
I built a solution that also needed its own custom "New" form, not open source unfortunately, though if you are interested you can download it, its called "Tagged Links" (Social Bookmarking for SharePoint) and you can find some links on my blog.
To give you a few hints and tips, the following should set you off in the right direction:
Created a new list definition.
Created a new Content Type In the content type you can define your own "FormTemplates" that references a Rendering Template which determine what gets displayed in the "Middle" bit of those forms.
Copied the standard Rendering Template, but then made the changes to it that I
needed.
Wrapped it all up in a solution, and deployed.
My Rendering Template actually included an overridden "Save" Button where I did a lot of the extra work I needed to do during the save.
Anyway, it is a little too much work in my opinion but, I think, it most closely matches the standard approach taken by the product developers. Let me know if you need more detail and I will see if I can put together a step-by-step blog post, but hopefully this gets you off on the right direction.
I would be surprised if you could do something in a _Layouts file that you can't do in a forms template. You have pretty much the same technologies at your disposal.
Looking at the way SharePoint works with ListItems and Layouts pages (for example "Manage Permissions" on a list item), I can see that they pass some variables in via querystrings:
?obj={76113B3A-FABA-4389-BC85-4BB2CC5AB423},6,LISTITEM&List={76113B3A-FABA-4389-BC85-4BB2CC5AB423}
Perhaps they grab the context back each time programmatically using these values.
I'm not using a custom "new form", so this might not apply. I added an event receiver to my custom content type and then do my custom code in the ItemAdded or ItemAdding events. This code fires when the event is added to a list. You can use the event receiver properties to get to the parent List, Web, and Site.
I'd like to think my issue is "special" here, since I am using a custom form. I chose to use a custom form rather than a custom FormTemplate simply because I'm doing a lot of stuff that's not very SharePoint list-like (making ajax calls to get info from a third-party app then generating some dynamic form elements based on that ajax result, then subsequent processing of that data on postback). I thought it'd be a nightmare to try this within the usual custom rendering template mechanism.
I also don't think I can supply the custom form declarations in the list definition itself, because I have multiple content types associated with this list, and each content type has its own custom form (the other type is thankfully much simpler).
Actually, my simple way of keeping the list guid in my hidden field was a very low impact way to address this specific problem. My main concern is that I'm not sure why the SPContext just loses all its usefulness when I postback here, which makes me think I'm doing something wrong.

Resources