Is it possible to publish component revisions within workflow? - tridion

Our current setup is that we have two targets, Staging and Live. Collaborators may update the affected component while it is still within the workflow. A final activity is set to publish the related pages to Live. Is it possible to publish component updates (revisions e.g. 2.2, 2.5) to Staging from within the workflow?
The TOM API documentation for Page.Publish() method does not seem to have an input parameter to fullfil such purpose.
EDIT: Additional details to our current setup: The page we're trying to publish has a "custom renderer", so to speak. The page template is setup to pull components from a certain folder recursively and build the HTML accordingly. The method used is Folder.GetItems(OrganizationalItemItemsFilter). It retrieves the list of components together with their data. The page doesn't have component presentations.

For standard Tridion solutions i.e. using Page+ComponentPresentations+Workflow, this will suffice:
Setting activateWorkflow parameter to True in the Publish() method will publish the workflow revision. It's the 3rd parameter:
Public Function Publish( ByVal targets As Variant,
ByVal activateBlueprinting As Boolean,
ByVal activateWorkflow As Boolean,
ByVal rollbackOnFailure As Boolean,
Optional ByVal publishTime As Date = 0,
Optional ByVal unpublishTime As Date = 0,
Optional ByVal deployTime As Date = 0,
Optional ByVal resolveComponentLinks As Boolean = True,
Optional ByVal priority As TDSDefines.EnumPublishPriority = Normal,
Optional ByVal ignoreRenderFailures As Boolean = False,
Optional ByVal maximumRenderFailures As Long = 0 ) As String
Reference: TOM API Documentation: "activateWorkflow | Indicates whether the item is being (un-/re-)published from the user's work list."
However, if customized renderers are used to build page output, like when using Folder.GetItems() to retrieve components in templates, additional calls would be required to actually retrieve the latest revision of components such as the version-zero -v0 trick by Nuno.
Please note that if you decide to do this, the latest revision will always be published to your targets and it may not exactly be "approved" content.

Related

DropDownList Data Items Shared With All Web Users?

I'm designing a custom ASP.NET drop down list for a Web application to display a list of a lot of organizations.
Btw: I reviewed every other SO question related to dynamically creating a drop-down-list and I couldn't find an answer.
Since there's a lot of organizations I want to build the item list as fast as possible.
Here's my ideas:
I'd share the list like this:
Imports System.Web.UI.WebControls
Public Class Organizations
Inherits DropDownList
Private Shared m_Organizations As List(Of Organization) = Nothing
Public Sub CreateChildControls()
' If list not populated get list from database.
If m_Organizations Is Nothing Then
m_Organizations = Get_Organizations()
End If
For Each Org As Organization in Organizations
Item_Obj = New ListItem(Org.Name, Org.OrgId)
Items.Add(Item_Obj)
Next
MyBase.CreateChildControls()
End Sub
End Class
I did a test. I created a single web page with two copies the drop down list. I ran the web page.
On initial startup of the web page I see m_Organization Is Nothing and Get_Organizations is called.
When I select an organization I see m_Organizations IsNot Nothing so Get_Organizations is not called. That's what I wanted.
When I click on a Submit button on the test page I see m_Organizations IsNot Nothing so Get_Organizations is not called. That's what I wanted.
So Organizations is persisted across page postbacks.
Now my question.
Suppose 3 users are using the web application at the same time and they display the web page with the Organizations drop down list.
Will m_Organizations be shared with all three web applications so it is loaded only once for all three users?
Or, is each user in their own process and therefore GET_Organizations will be called a total of three times?
Thanks, Ed
Each user has their own web page, controls, and code values. They each get their own code copy and their code runs just FOR each user.
So, to load up the dropdown list? It not clear why you pulling into a list?
The base .net objects such as row, and dateable run a lot faster then lists. And these base types can be directly binded to the drop down list (no need for a loop).
So, your on load would be something like:
So, in page load event, you have this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If IsPostBack = False Then
Me.Instutions.DataSource = Myrst("select ID,Institution from Institutions")
Me.Instutions.DataBind()
End If
End Sub
So, only on the page load do we fill up the combobox (drop down list). You check the "isPostback" value.
Now it possible that you using datasets (or the newer EF) for the data. But even in that case, you can get/grab the data table from that, and shove it directly into the dropdown list data source. You as a general rule will NOT run loops to fill these types of controls (gridview, listview, dropdownlist). They can be bound directly to the result of the data source without loops. And since each users will get their own copy of the data, and your code runs for each user? Then you do want to avoid things like loops - since that code will run separate for each user and each page post back.
So yes, each user gets their own web page, gets their own variables, and runs their own code 100% separate from each user. And that includes a copy of the datasets you have.
When the user selects a value from the drop down list? (yes, we have auto postback = true), and thus the code for that wlll look like:
Protected Sub Instutions_SelectedIndexChanged(sender As Object,
e As EventArgs) Handles Instutions.SelectedIndexChanged
' pk id from drop list = Instutions.SelectedValue
' text value from drop list = Instutions.DataTextField
End Sub
So, it only takes two lines of code to load up the dropdown list - even when you don't have a dataset, or are using EF.
Now, I did use a helper routine called myrst(), and it can be used to fill dropdown lists, datagrids, listviews etc. and once again only two lines of code, and no looping.
that "handy" routine is this:
Public Function Myrst(strSQL As String) As DataTable
Dim mycon As New SqlConnection(My.Settings.Test4)
Dim oReader As New SqlDataAdapter
Dim rstData As New DataTable
oReader.SelectCommand = New SqlCommand(strSQL, mycon)
Try
oReader.Fill(rstData)
Return rstData
Catch
Debug.Print(Err.Description)
Return Nothing
End Try
End Function
So when they select a value in the drop down list? You do get a full page post back, and your on-load event will run. And yes, EACH user has their own web page, and own copy of that code running - they are not relegated to each other in ANY way, and all local, global variables and code is run 100% in a separate session for each user. And each user also has their own Session() variables - and again they are 100% separate and not shared between all users.
So yes, all 3 users will each call and each load up their own copy of that data. (yes, it called 3 times). if that was not the case, then what would occur if you wanted to filter only companies or records belonging to the one user? so you can consider all code and even loading of data a 100% separate thing/concept and process for each user.

vb global variable to be accesses by different classes

I am new to VB and am working on an asp.net VB web application.
I have a partial class called s_new.aspx.vb which is the vb page behind the page s_new.aspx.
In this page there are a series of select dropdowns, which when selected lead to different options becoming available eg different select boxes appearing and or with different options.
One particular select box accesses a method in a different class (webcontrols).
My problem is that I need the web controls class to change its behavior based on a certain selection made in the s_new.aspx.vb page.
If I was using C# I would create a global variable and use that as a decision maker, but I cant seem to to this in VB.
below is a snippet of the code I am using:
Partial Class s_new
Protected Sub fldSourceofFunds_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles fldSourceofFunds.SelectedIndexChanged
Select Case fldSourceofFunds.SelectedIndex
Case 1
####
Case 2
###
Case 3
do something and set the variable
End Select
End Sub
Partial Class Webcontrols
Private Sub ReloadChildren()
If (variable from s_new has certain value) Then
ResetChildren()
Select Case PaymentMethodValue.ToLower.Trim
Case "payment via provider/platform"
Case "payment direct from client"
Case "payment via provider/platform and payment direct from client"
End Select
End if
End Sub
End Class
This is an existing project and I need to minimize the changes I make to the project, eg I am not able to make large changes to the structure to accommodate this change. As I said above, this would be a simple solution in C# and I assume it is simple here to.

Making use of service references in vb.net

I've been trying to make use of this API in order to create a small app that will be run at a set interval in order to monitor a value. I've been told to do it in vb.net using service references and have so far managed to make use of the method that returns the last publication time, but when I try to retrieve the actual information from the table I receive an error:
"Exception: Compression is Not Enabled,This Web Service expects
clients to support GZIP,Deflate Compression"
So far i've been finding it difficult to find any info that is applicable to my current setup so i'm not sure how to progress. Is there anything i'm missing or any resources that would help me get my head around this?
Here is the current code i'm using to get the values.
Private Sub Soap(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim svc As New FlowInfo.InstantaneousFlowWebServiceSoapClient()
Dim str As String = svc.GetLatestPublicationTime().ToString
MessageBox.Show(str)
Dim body As FlowInfo.EDPReportBE = svc.GetInstantaneousFlowData()
End Sub

Public Shared Variable Shared Between Users?

I've taken over the maintenance of the website (ASP.NET VB) and on one particular page I noticed the below code
Inherits System.Web.UI.Page
Public Shared UserNumber As String
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
UserNumber = Session("UserNumber")
...
End Sub
My question is whether the variable UserNumber can be accessed or changed by any other user than the current one?
Many thanks
A Shared variable is the same as a static variable in C#.
These can be shared across all instances, therefore different users would share the same variable.
Looking at the variable name, I would assume you would need to remove this Shared
You are applying a Session variable value to the Shared String on Page_Init.
Therefore each time the user loads the page, their session variable will override the current value.
If you are not using this variable outside of this class, then I would recommend changing it to:
Protected UserNumber As String
EDIT My initial answer was incorrect. Trying again...
Technically, as #Curt indicated, a Shared variable is shared across instances of the class.
However, with the code as is, it is less likely that the value will be shared amongst users as it is set to each user's local copy of the value in their Session in Page_Init.
There is a possible "race condition" where after the shared variable UserNumber has been initialised in Page_Init, and another user submits a request which updates the value of that variable from their session, the first user will then see the second user's value. i.e. users can see other user's values for concurrent requests.
Instead, I recommend using a ReadOnly non-shared property to get the value from the Session once:
Private mUserNumber As String
Public ReadOnly Property UserNumber As String
Get
If String.IsNullOrEmpty(mUserNumber) Then
mUserNumber = Session("UserNumber")
End If
Return mUserNumber
End Get
End Property
This uses a pattern called "Lazy-loading", which I use in read-only properties a lot on pages to improve performance and readability of code.

Syntax to change the value of a cached object property

In an ASP.NET 3.5 VB web app, I successfully manage to cache an object containing several personal details such as name, address, etc. One of the items is CreditNum which I'd like to change in the cache on the fly. Is there a way to access this directly in the cache or do I have to destroy and rebuild the whole object just to change the value of objMemberDetails.CreditNum?
The cache is set using:
Public Shared Sub CacheSet(ByVal key As String, ByVal value As Object)
Dim userID As String = HttpContext.Current.User.Identity.Name
HttpContext.Current.Cache(key & "_" & userID) = value
End Sub
Besides that this answer might help; Cache is really there to help you add, read, and drop the objects that your app requires frequently.

Resources