I own a small website that display to the users an html template (with css). Each user can change the template (customizable).
By default i have a template i copy everytime to a new user or if i get nice template (high rates) users can choose it.
instead of copying the template over and over, is there an easy way for me to create 1 template and then when the page load, it shows on the user page and then he can interact (ajax calls, href links etc...)
for example:
new user logged for the first time, the "user license agreement" shows then he click accept and his page shows up. this "home" page has forms, links, images etc... using a default template. that is the one i want to load dynamically instead of copying this template to each users.
why: i found HTML error in the page and now i need to copy this template to 127 users ... which is a pain.
i am using LAMP
thanks
yes using jQuery!
$('#divID').load('pathToHTMLTemplate') is your answer as long as you have the html file stored on same domain :)
This will fetch the html template using ajax and append its content to the div you want. It can also be 'body'.
Here is the documentation which should tell you everything you need to.
Once the template is loaded you can load the user specific data using ajax or any app server you are using. .load function provides a callback:
$('#divID').load('pathToHTMLTemplate', function(){
// now the template is loaded and you can maniupulate it further or load user specific data
});
It sounds to me (just going off of your post) that you have a directory somewhere with a bunch of files "user1.html", "user2.html" or something similar. All of these are either the same or similar, since they're basically the same template.
My recommendation:
Have a database table (or a flat file, but I recommend a database table) that maps a user ID (or name, however you have them arranged) to a template. For example, if user1 and user2 use template_default.html, but user3 uses template_popular.html, you would have the following in your database:
name|template
user1|template_default.html
user2|template_default.html
user3|template_popular.html
Then in whatever code is currently deciding which page to show the user, change it to pull the user's chosen template out of the database and display that instead. So then you only have 1 or 2 pages instead of 127.
If the user is allowed to make edits to their template, that could be stored as metadata in the table as well, then you could use substitution parameters to add it into the template.
Example:
MySQL table:
CREATE TABLE user_templates (
`user` varchar(100),
template varchar(100)
);
Upon receiving a new user:
INSERT INTO user_templates(`user`,template) VALUES("<username>","default_template.html");
Upon user choosing a new template:
UPDATE user_templates set template = "<new template>" WHERE `user` = "<username>";
Upon user loading the user's page (this done in php):
$template = "default_template.html";
$query = "SELECT template FROM user_templates WHERE `user` = \"" . mysql_real_escape_string($username) . "\"";
$result = mysql_query($query,$databaseHandle);
if ($result && mysql_num_rows($result) > 0) {
$template = mysql_result($result,0,"template");
}
// 1st way to do it
$pageToLoad = "http://www.someserver.com/templates/$template";
header("Location: $pageToLoad");
// 2nd way, if you want it embedded in a page somewhere
$directory = "/var/www/site/templates/$template";
$pageContents = file_get_contents($directory);
print "<div id=\"userPage\">$pageContents</div>";
I assume you mean that you have an HTML file that is customized for each user (look, feel, etc):
User1-theme.html
User2-theme.html
User3-theme.html
User4-theme.html
User4-theme.html
Then you would have a file that has all of your ajax calls, links, etc that you want for each user:
User-Controls.html
What you need to do is
Ensure jQuery is downloaded and included on each of your User Theme Pages.
Add this code snipplet to each of your User Theme Pages:
$("#myDiv").load("User-Controls.html")
(where #myDiv is the div ID on the template page that you want to load the controls into
and User-Controls.html is the path to the html file containing the controls you want to load
Related
I have some information related to different vendors in my database and I want to allow each registered vendor (representative person) to view slices/dashboards which contains only data related to them.
One possible solution could be to create separate views for each vendor as well as separate roles for each vendor. But it feels like a bad idea if you have 100+ vendors (as is my case); and it's not a flexible or scalable solution.
Is there some way to automatically filter a given view for each user? For example, we have a "general profit by product" bar chart, and user X can see only products of vendor X
What you're looking for is multi-tenancy support, and this is not currently supported out-of-the-box in Superset.
There is however an open PR for one possible solution: https://github.com/apache/incubator-superset/pull/3729
One option could be to re-use and/or adapt that code for your use-case.
Another option might be to look into JINJA_CONTEXT_ADDONS [https://github.com/apache/incubator-superset/blob/master/docs/installation.rst#sql-lab] and see whether you might be able to pass additional context to your query (e.g. your vendor_id) and restrict the scope of your query using that parameter.
Superset config has the below two configurations(DB_CONNECTION_MUTATOR, SQL_QUERY_MUTATOR), which can allow for multi-tenancy to an extent.
A callable that allows altering the database conneciton URL and params
on the fly, at runtime. This allows for things like impersonation or
arbitrary logic. For instance you can wire different users to
use different connection parameters, or pass their email address as the
username. The function receives the connection uri object, connection
params, the username, and returns the mutated uri and params objects.
Example:
def DB_CONNECTION_MUTATOR(uri, params, username, security_manager, source):
user = security_manager.find_user(username=username)
if user and user.email:
uri.username = user.email
return uri, params
Note that the returned uri and params are passed directly to sqlalchemy's
as such create_engine(url, **params)
DB_CONNECTION_MUTATOR = None
A function that intercepts the SQL to be executed and can alter it.
The use case is can be around adding some sort of comment header
with information such as the username and worker node information
def SQL_QUERY_MUTATOR(sql, username, security_manager):
dttm = datetime.now().isoformat()
return f"-- [SQL LAB] {username} {dttm}\n{sql}"
SQL_QUERY_MUTATOR = None
One easy way of solving this problem is by using pre-defined JINJA parameters.
Two parameters that can be used are '{{current_username() }}' and {{current_user_id() }}
First you need to ensure that you can use JINJA templates -
In superset_config.py add the following
FEATURE_FLAGS = {
"ENABLE_TEMPLATE_PROCESSING": True,
}
Restart
Now if you go to the SQL LAB and type the following -
SELECT '{{ current_username() }}',{{ current_user_id() }};
You should get an output
?column?
?column?__1
PayalC
5
Now all you have to do is append one of the two following sql snippet in all your queries.
select ........ from ...... where ...... vendorid={{ current_user_id() }}
select ........ from ...... where ...... vendorname='{{ current_username() }}'
vendorid={{ current_user_id() }} and/or
vendorname='{{ current_username() }}' will restrict the user to view only her data.
You could also make it more flexible by creating a table which has a mapping of user to vendorid. That table can be your added to all the queries and you could map multiple vendors to a single user or even all vendors to a single user for a super admin.
I have a sharepoint 2013 site that uses a managed metadata term set for navigation. Documents can be tagged with the managed metadata so they appear in whatever category or categories is appropriate for the document. I need to allow documents to be saved as favorites. I created a custom list that saves the file name and path but I can't get the managed metadata settings to save correctly. I am using spservices.UpdateListItems via javascript and pass the ids and terms in the valuepairs property of the call like so ;#. Although the method saves the record, it either does not save the term or it saves one completely unrelated. Does anyone have any further advice on how to do this?
$().SPServices({
operation: "UpdateListItems",
async: true,
batchCmd: "New",
listName: "UserFavorites",
valuepairs: [["Title", title], ["DocumentId", itemid],["AssetCategory", assetCategoriesString]],
completefunc: function (xData, Status) {
alert(Status + " -- " + xData.responseText);
}
});
Example of the assetCategoriesString variable contents:
"fc8d083a-fc5e-4525-8fef-04ba982d1633;#Print Publications"
In TYPO3 6.x, what is an easy way to quickly create custom content elements?
A typical example (Maybe for a collection of testimonials):
In the backend (with adequate labels):
An image
An input field
A textarea
When rendering:
Image resized to xy
input wrapped in h2
textarea passed through parseFunc and wrapped in more markup
Ideally, these would be available in the page module as cType, but at least in the list module.
And use fluid templates.
My questions:
From another CMS I am used to content item templates being applied to the BE and the FE at the same time (you write the template for what it should do, and then there's a backend item just for that type of content element) - but that's not how fluid works - or can it be done?
Is there an extension that would handle such custom content elements (other than Templavoila)?
Or do I have to create a custom extbase/fluid extension for each such field type?
And, by the way: is there a recommendable tutorial for the new extbase kickstarter? I got scared away by all that domain modelling stuff.
That scaring domain modeling stuff is probably best option for you :)
Create an extension with FE plugin which holds and displays data as you want, so you can place it as a "Insert plugin". It's possible to add this plugin as a custom CType and I will find a sample for you, but little bit later.
Note, you don't need to create additional models as you can store required data ie. in FlexForm.
From FE plugin to CType
Let's consider that you have an extension with key hello which contains News controller with list and single actions in it.
In your ext_tables.php you have registered a FE plugin:
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin($_EXTKEY, 'News', 'Scared Hello News');
When it's working fine you can add it to the list of content types (available in TCA) just by adding fifth param to the configurePlugin method in your ext_localconf.php:
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'TYPO3.' . $_EXTKEY,
'News',
array('News' => 'list, show'),
array('News' => ''),
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::PLUGIN_TYPE_CONTENT_ELEMENT // <- this one
);
Next part (basing on this site) is adding your plugin to the New Content Element Wizard as noticed in TYPO3 Wiki since TYPO3 ver. 6.0.0 changed a little, so easiest way is adding something like this into your ext_tables.php:
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('<INCLUDE_TYPOSCRIPT: source="FILE:EXT:hello/Configuration/TypoScript/pageTsConfig.ts">');
and in /typo3conf/ext/hello/Configuration/TypoScript/pageTsConfig.ts file write add this:
mod.wizards.newContentElement.wizardItems.plugins.elements.tx_hello_news {
icon = gfx/c_wiz/regular_text.gif
title = Scared Hello News
description = Displays Scared News
tt_content_defValues.CType = hello_news
}
# Below the same for TemplaVoila
templavoila.wizards.newContentElement.wizardItems.plugins.elements.tx_hello_news {
icon = gfx/c_wiz/regular_text.gif
title = Scared Hello News
description = Displays Scared News
tt_content_defValues.CType = hello_news
}
Note that proper key tx_hello_news should be combination of lowercased tx_, $_EXTKEY and plugin name - used in registerPlugin method.
You can stop here if you are bored ;)
Bring tt_content's fields back into your CType
Above steps will cause that no typical fields will be available in the TCA for your element, so you need to copy something or create own. To see how it works just see some sample, in the backend in left menu choose ADMIN TOOLS > Configuration > TCA > tt_content > types
There you'll find all types in the system, choose the most required and copy its [showitem] node into your own. Again in ext_tables.php add this PHP array:
$TCA['tt_content']['types']['hello_news']['showitem'] = $TCA['tt_content']['types']['textpic']['showitem'];
Again: hello_news is combination of lowercased $_EXTKEY and FE plugin name...
Of course if it's required you can compose quite own set of fields, one by one by custom string:
$TCA['tt_content']['types']['hello_news']['showitem'] = '--palette--;LLL:EXT:cms/locallang_ttc.xml:palette.general;general, --palette--;LLL:EXT:cms/locallang_ttc.xml:palette.header;header';
Access the fields in Extbase Controller:
Fortunately is easiest part as you can just access it as an Array:
$currentTtContent = $this->configurationManager->getContentObject()->data;
$header = $currentTtContent['header'];
debug($currentTtContent);
debug($header);
I think http://typo3.org/extensions/repository/view/dce will do exactly what I was looking for
I dynamically create campaign from my website using mailsnake in django framework. Want to add the data and images directly into campaign for that i add the html data into the sections like postcard_heading00, postcard_image, std_content00.
Write the code as below:
mailsnake = MailSnake('apikey')
template_option = {'list_id':xxxx, 'subject':'testing', 'from_email':'xxxxx', 'from_name':'Test', 'to_name':'', 'template_id':54457, 'inline_css':True, 'generate_text': True, 'title':'testing' }
template_content = {"html_postcard_heading00":"<h1>Testing</h1>","html_std_content00":"<h1>Testing</h1>","html_postcard_image":"<img src='image_path'>"}
and pass this content to
campaignCreate(type='regular',options = template_option,content=template_content)
method.
Campaigns creates properly, but the content still not added into the campaign.
Can please anybody tell me why this happens?
Problem is because of Repeatable section. Repeatable section having different way to add data.
Change the template content as below.
template_content = {'html_repeat_1:0:postcard_heading00':postcard_heading[0],
'html_repeat_1:0:postcard_image': postcard_img,
'html_repeat_1:0:std_content00': std_content[0]}
I done this way and problem gets solved.
Currently, templates\wffm\forms folder has Insert Options like "Form Folder" & "Form" object. This is great for people that use the base "Form" template. In my case, I've got people who'd like to use a base payment form with hidden fields and other actions I've created.
I'd like to add my custom form "MyPaymentForm" to the Insert Options so it will be on display for all form users to select as their base form. The problem is that this is a form with fields and not a template so Insert Options will not let me add it.
I'd like my payment form with base fields to be a template for each group that uses it. For example, all will use the base fields but will also have custom fields in relation to their department.
Can you recommend a way I can serve up "MyPaymentForm" to users so that it is reusable for different groups?
Thanks,
Chris
I would recommend using a Command Template to accomplish what you're asking. A Command Template is essentially a bit of custom logic that can be assigned to Insert Options.
In your case, you could create a Command Template named 'MyPaymentForm' (or whatever you come up with) and then assign that Command Template to the Insert Options field of any template/item you wish. When a user right clicks to 'Insert->' and your Command Template is available, the user can click your 'MyPaymentForm' command template and your custom code will be executed.
The action behind your command template could be as simple as creating a copy of your base form and inserting it in the content tree where the user executed the command template.
Here is an example of command template code that could accomplish what you'd like. This is completely untested, but the concept is there.
namespace MyNameSpace
{
public class CopyPaymentFormCommand : Sitecore.Shell.Framework.Commands.Command
{
public override void Execute(Sitecore.Shell.Framework.Commands.CommandContext context)
{
if (context.Items.Length == 0)
return;
Sitecore.Data.Items.Item destinationItem = context.Items[0];
if (destinationItem == null)
return;
//retrieve the base MyPaymentForm item
Sitecore.Data.Items.Item myPaymentForm = destinationItem.Database.GetItem("MyPaymentForm GUID");
if (myPaymentForm == null)
return; // instead of just exiting here, you may want to log an error first
//copy the MyPaymentForm item to the location in the content tree from which the command template was triggered
Sitecore.Data.Items.Item copyOfMyPaymentForm = myPaymentForm.CopyTo(destinationItem, "MyPaymentForm");
//perform any necessary post-processing of your newly copied item
}
}
}
After creating your custom code, you'll need to wire up Sitecore to recognize and use your command.
1. Add a "command" element to the file /App_Config/Commands.config, like so:
<command name="mycustomcommands:forms:copypaymentform" type="MyNamespace.CopyPaymentFormCommand, MyAssemblyName" />
2. Next, create a Command Template item in your /sitecore/Templates section. You can do so by right-clicking the relevant folder under /sitecore/Templates and using Insert->Insert From Template, then select the "/sitecore/Templates/System/Branches/Command Template" data template.
3. Next, in your newly created Command Template item, populate the Command field (contained in the Data section) with this text:
mycustomcommands:forms:copypaymentform(id=$ParentID)
note: the command name matches the command name defined in the Commands.config file
4. You now have a Command Template that can be assigned as an Insert Option. To do so, simply edit the __Standard Values item of any template you choose and select Assign Insert Options. In the Insert Options dialog, browse to the Command Template item you created and add it to the 'Selected' list of insert options.
Now, when a user attempts to insert a new item underneath an item with the template containing your command template insert option, they will have the option to click on your command template. Doing so will trigger your command template code, which will in turn create a copy of your payment form in the location from which the user executed the command.
For more information on command templates, see this document on the SDN (specifically, Chapter 4): http://sdn.sitecore.net/upload/sitecore6/datadefinitioncookbook-usletter.pdf
Hope this helps!