Displaying taxonomy on DotNetNuke Page - dotnetnuke

I've added tags to the pages on my dnn site and I would like to display a simple list of the tags that the page is assigned to at the bottom of the page.
I'm using DNN 6 and I've read that this is possible by adding some lines to the skin file.
I've added
<%# Register TagPrefix="dnn" TagName="TAGS" Src="~/Admin/Skins/Tags.ascx" %>
and <dnn:tags runat="server" id="dnnTags" /> as per online suggestions
When I view the page there are no tags, and in the source the only thing outputted is an empty div <div class="horizontal"></div>
This does suggest that the tags.acsx is being called ok
I thought maybe tags weren't working, but when I put a ContentList module on the page and visit the page with ?Tag=test appended to the link it does pick up all the pages and modules with that tag, including the page I am testing.
Has anyone experienced anything like this before?
Thanks
I've now found that removing the below section of code from tags.ascx.cs allows the page to display the list of tags
string resultsUrl = Null.NullString;
var objModules = new ModuleController();
int searchTabId = 0;
ModuleInfo SearchModule = objModules.GetModuleByDefinition(PortalSettings.PortalId, "Search Results");
if (SearchModule == null)
{
return;
}
else
{
searchTabId = SearchModule.TabID;
}

There are two parts to the addition of the skin object. Part 1
<%# Register TagPrefix="dnn" TagName="TAGS" Src="~/Admin/Skins/Tags.ascx" %>
Then you need to actually add it to the page where you need it.
<dnn:TAGS id="mytags" runat="server" />

Related

How to access Another Module's Content and Presentation Items after 2sxc v10.20+

Here is code that worked up through 2sxc 10.9.1. Though I am able to get the CmsBlock for the TabID, ModuleID and get that to .Render(), I need more. Here is the old code. Not sure it makes any difference, but this View is using the normal Link content-type and is running in an older version of the Content App (appx 3.03=ish). 2sxc has been upgraded and is now 11.22.0 LTS.
I have removed unnecessary stuff, so I doubt this runs as is...
#using ToSic.Razor.Blade
#using ToSic.SexyContent.Environment.Dnn7
#{
var Helpers = CreateInstance("_Helpers.cshtml");
// Display the items from the Manage Links module, we go in 'sideways'
// this gives us just the Content items with their Presentations settings, etc.
var sxci = Factory.SxcInstanceForModule(3360, 606); // ModuleID of Manage Links
var dyn = Factory.CodingHelpers(sxci);
var allLinks = dyn.AsDynamic(dyn.Data["Default"]);
}
#* other stuff *#
<div class="row co-documents justify-content-center align-items-center">
#foreach (var linkItem in allLinks) {
var linkInfo = Helpers.LinkInfos(linkItem.Link, linkItem.Window, linkItem.Icon);
string iconStyle = linkItem.IconStyle ?? "fas";
int linkColumns = (int)linkItem.Presentation.Columns;
string linkIconAlign = linkItem.Presentation.IconAlign;
string linkIconBGColor = linkItem.Presentation.IconBGColor;
#* other stuff *#
}
</div>
So the easy thing to figure out was how to get the module as a CmsBlock which I can Render() as is (below), but what I need to do instead is get proper access to the List of Content Items AND their Presentation data (like above, allLinks).
ToSic.Sxc.Dnn.Factory.CmsBlock(606, 3360).Render();
What am I missing? How can I get access to the other module's data like I was doing before? In this case, I do this in 3 different places on the website. So to outline this in English, I have a module that the client manages a few special links that get displayed in MegaMenus, other special nav, and directly on a couple of pages. In each place they render differently. In their "home" module, where they get edited, they just look boring like this:
I realize its something like this:
var allLinks = something1.AsList(something2.Data["Default"]);
I understand that something2 is an app instance, but how do I create it in the context of the other module?
And what is something1 nowadays? And how do instantiate it? Looks like its a new ToSic.Sxc.Code.DynamicCode() but I can't figure out how to construct that in a way that I can use or doesn't just throw errors.
Thanks in advance for any insight!!
Okay, it took a little testing, trial and error. And also I missed that DynamicCode() was a Method of the Factory class. In retrospect it does seem easy now.
So first you get the BlockBuilder
var block = Factory.CmsBlock(606, 3360);
Then you get the DynamicCode instance (Code.DnnDynamicCodeRoot) from that
var dc = Factory.DynamicCode(block);
And then things are normal
var allLinks = AsList(dc.Data["Default"]);
The rest of the code works like it did before; I can foreach through the links with Header (renamed from ListContent) and Presentation (now Content.Presentation) working just as expected.
The above answer works fine if you are inside the C# Razor template of the 2sxc View. But what if you are outside, for example in a Razor template for a DDR Menu?
Same two steps as above (get the block and the dc), but then you do NOT have access to AsList() or the App. Thankfully, you already have DynamicCode, so you could just get all the records in the Bibliography content-type like this:
<ul>
var items = dc.AsList(dc.App.Data["Bibliography"]);
foreach (var item in items)
{
<li>#item.EntityTitle</li>
}
</ul>
So once you've got your dc you've got access to all the usual 2sxc toys.

how can I load a joomla module as a link?

this is my problem...
I have some of images and links that I want to load different joomla modules when user click on them.
mean each hyperlink can load another module|position
thanks all
In case that you just want to call a module's content from a url the following answer will help you.
If you just want to show / hide a module in the same page you could use something similar to my previous answer: Joomla 3 Show different modules on same position depending on toggler
Joomla provides the functionality to call a specific file of the active template by adding the tmpl=FILENAME key/value to the url's query string.
All built-in templates have a component.php file if user wants to load the template with the component only. You could check the following link for more details: Adding print pop-up functionality to a component.
You could do something similar to only show the modules that you want to load.
You could copy the component.php to a new file (I have used custom.php) and added the following php code in the <body> ... </body> part.
<?php
$jinput = JFactory::getApplication()->input;
$selectedPosition = $jinput->getString("position", "");
$selectedModule = $jinput->getString("module", "");
$selectedModuleTitle = $jinput->getString("title");
if($selectedPosition !== "") {
$modules = JModuleHelper::getModules($selectedPosition);
foreach ($modules as $module) {
echo JModuleHelper::renderModule($module);
}
} elseif ($selectedModule !== "") {
$module = JModuleHelper::getModule($selectedModule, $selectedModuleTitle);
echo JModuleHelper::renderModule($module);
}
?>
So with a similar way as loadposition / loadmodule works you could call the new template file using:
index.php?tmpl=custom&position=MODULE_POSITION
or
index.php?tmpl=custom&module=MODULE_TYPE
or
index.php?tmpl=custom&module=MODULE_TYPE&title=MODULE_TITLE
Optionally if you want to load the module with a specific style, you could pass it to the second paramter of the renderModule method like:
echo JModuleHelper::renderModule($module, array("style" => "xhtml"));
Hope this helps

How to reuse Loop ? get_template_part() or?

I want to use the same Loop and Pagination for
index.php , search.php , and archive.php
However, for search.php I want a title "Search Results" to appear before the Loop
and for archive.php I want a title "Archive Page" to appear before the Loop.
Method A
Keep index.php, search.php, and archive.php
And use get_template_part() for navigation and Loop ?
Method B
Just use index.php
but how?
Or is there a simpler method since all I want is to add a title before the Loop?
Simple code for the sake of this example:
index.php
<?php
if ( have_posts() ) : while ( have_posts() ) : the_post();
the_excerpt();
endwhile; endif;
?>
code for Pagination
search.php
<h2>Search Results</h2>
code for The Loop
code for Pagination
archive.php
<h2>Archive Page</h2>
code for The Loop
code for Pagination
I don't know the exact structure of your pages, but I would place the code in header.php. Here is my thought on this
The header is common to all of these templates, and I would suspect that you are going to need these titles between your header stuff and the content area
Target pages with conditional tags . Open your header, and right down at the bottom, add something like this
if(is_search()) {
//your title for search page etc
} elseif(is_archive()) {
//your title for archive page
} else {
//display nothing if you don't need to display any custom title
}
Just add the necessary mark up and style accordingly
EDIT
It seems that you are still very new to php. From your comment
Weird. I put <?php if(is_search()) { <h2>Search Results</h2> } ?> at very bottom of header.php but got White Screen. So instead, I put it in index.php and deleted search.php but still White Screen. I tested it in my theme and Twentytwelve. ---------- Can you help me understand... Does less php files equal to a faster website? Is reducing the amount of php files considered best practice? So if index.php , search.php , archive.php uses the same code except for a title "Search Results" and "Archive Page" - is it best practice to simply have one php file and do conditional statements for titles?
Your problem is switching between php and html elements. Whenever you switch from php to html, you need to close your php tag (?>)before your html element. On the otherhand, you need to open a new php tag (<?php) right after your last html element and before your first php element.
Not doing this correctly will lead to a synatx error, which causes a white screen of death.
So in short, your code will need to look like this for it to work properly. Note the php tags
<?php
if(is_search()) { // this part is php
?> <!-- Close php because whe're switching to html -->
<h2>Search Results</h2> <!-- this part is html -->
<?php // open new php tag as we're switching to php again
} elseif(is_archive()) { //same sequence above applied
?>
<h2>Archive Page</h2>
<?php
} else {
//display nothing if you don't need to display any custom title
}
?>
Less php files does not mean a faster website, speed is determined by content, content type, database queries, amount of queries, etc etc. A one page website can be slower than a 10 page website.
What I've done with this code and why I placed it in the header is just to keep the code together. You can split it up as you wish. There is no best practice. What really counts is readability, accesibility, not repeating code over and over, and keeping a proper file system
You could output the title before you start the loop. The contents of the loop would be called using get_template_part(). For example:
if ( have_posts() ) {
// Output the title.
the_title();
// Begin loop.
while ( have_posts() ) {
the_post();
get_template_part( 'loop', 'index' );
}
}
Update: Using just index.php to display a title conditionally, you would do this:
if ( is_search() ) {
// Display the search page title here.
} else if ( is_category() ) {
// Display the category title here.
}
Ref: http://codex.wordpress.org/Function_Reference/get_template_part

DotNetNuke - Opening and closing trees

I inherited a DNN site and am trying to figure it out. I have a page with a clickable header and then it branches into categories which are also clickable and show a name (it is a directory of people working at this company). The issue is that there is a small + and - to open and close these categories, but only these symbols work. Is there a way to make the symbol and the category title clickable to open or close the branch?
Here is the code from the page I am referring to:
<%# Control language="C#" Inherits="Modules.PeopleNav.PeopleByDept" CodeFile="PeopleByDept.ascx.cs" AutoEventWireup="true"%>
<%# Register TagPrefix="dnn" TagName="Audit" Src="~/controls/ModuleAuditControl.ascx" %>
<asp:TreeView ID="TreeView1" runat="server" DataSourceID="XmlDataSource1"
ExpandDepth="1"
onselectednodechanged="TreeView1_SelectedNodeChanged">
<DataBindings>
<asp:TreeNodeBinding DataMember="Person" ValueField="Value" TextField="Name">
</asp:TreeNodeBinding>
<asp:TreeNodeBinding DataMember="Department" TextField="Name" >
</asp:TreeNodeBinding>
</DataBindings>
</asp:TreeView><br />
<asp:XmlDataSource ID="XmlDataSource1" runat="server" DataFile="~/Portals/0/Docs/Department.xml"></asp:XmlDataSource>
I don't even know where the linking is taking place, as I am both a new programmer and brand new to DotNetNuke. If I need to post more code I will, I just don't want to go overboard with it. Thanks in advance!
Use the TreeView's OnTreeNodeDataBound event to change the selection action.
protected void TreeView1_NodeDataBound(object sender, TreeNodeEventArgs e)
{
e.Node.SelectAction = TreeNodeSelectAction.Expand;
}

How to open a VF page as popup and pass parameters to that VF page?

I have a VF page which has 2 date fields and search button.
On click of search i get some results. i also have another button to print those results which is nothing but a new VF page rendered as pdf.
I want to pass this date values into the printVF page. i also want to have this page come up as popup.
I have the pageref with parameters set. Since i need to open this page as popup i need to find a way to use the pageref in the window.open.
Anybody has ideas on how to accomplish this?
Thanks
Prady
EDIT :What i did was build the url in the controller and use the controller variable in window.open. Something very strange is happening... The first time search results are displayed and i click the print button, the dates dont get populated in the string, they default to todays date.. if i again click the print button the dates are populated correctly on the url from the dateinput.
public Class1(){
System.debug('inside constructor');
fieldContainer=new DummyTable__c(); // it contains date fields for date inputs
date todays=date.today();
If (fieldContainer.Start_Date__c== null)
{
startdate1=todays;
}else
{
startdate1=fieldContainer.Start_Date__c;
}
If (fieldContainer.End_Date__c== null)
{
enddate1=todays;
}
else
{
enddate1=fieldContainer.End_Date__c;
}
}
public void search()
{
startdate1=fieldContainer.Start_Date__c;
system.debug('startdate1'+startdate1);
enddate1=fieldContainer.End_Date__c;
system.debug('enddate1'+enddate1);
system.debug('inside search()....after clicking search button');
system.debug('startdate1'+startdate1);
system.debug('url'+url);
LoadData();
}
public string geturl()
{
url='apex/VF1?Pstartdate='+string.valueof(startdate1)+'&Penddate='+string.valueof(enddate1);
return url;
}
public string geturlRec()
{
urlRec='apex/VF2?Pstartdate='+string.valueof(startdate1)+'&Penddate='+string.valueof(enddate1);
return urlRec;
}
VF Page
<script language="javascript" type="text/javascript">
function printOut()
{
window.open("{!url}");
}
function printIn()
{
window.showModalDialog("{!urlRec}","dialogWidth:800px; dialogHeight:200px; center:yes");
}
</script>
<div style="width:900px;margin:0 auto;" id="pagediv">
<span style="padding-left:30px;padding-right:10px">From </span><apex:inputfield value="{!fieldContainer.Start_Date__c}" id="startdt" style="padding-left:5px;padding-right:20px;"/>
<span style="padding-left:30px;padding-right:10px">To </span><apex:inputfield value="{!fieldContainer.End_Date__c}" id="enddt" style="padding-left:5px;padding-right:20px;"/>
<span style="padding-left:30px;padding-right:10px"><apex:commandButton action="{!search}" value="Search" ReRender="dtshipdep,dtshiprec,shippageblock"> </apex:commandButton></span>
<apex:commandButton action="{!saveDeparted}" value="Update " ReRender="dtshipdep"></apex:commandButton>
<apex:commandButton value="Print " onclick="printOut();"></apex:commandButton>
The salesforce recommended way to generate URLs is through URLFOR() function. Or, alternatively, you can create a PageReference in the extension/controller code.
Though, keep in mind, before any form data can become part of the URL it has to be posted to the server and come back in newly generated pageReference, for that reason you cannot jut click on it in the first run.
One way I used to solve this server side is using this code on VF
<apex:outputBlock rendered="{!openPopup}">
<script>
window.open('{!myTargetUrl}');
<script>
</apex:outputBlock>
openPopup is a bool that control whether this segment gets rendered (transient, you set it to true when you click on open button). myTarget is a PageReference based URL (alternatively you can use URLFOR here to generate URL in VF). If you have any more questions, ask.
Another option is to have your javascript code in VF which will pickup button click event and build the URL client side and open it up. You can use $Component to locate form fields.
You should be able to pass the values you need in the QueryString.
window.open("/apex/YourPage?VariableName=Value&SecondVariableName=SecondValue");
Then once you have the variables send to the new page, you can get them using a PageReference.
String myVariable = PageReference.getParameters().get('VariableName');

Resources