Best option to edit CSS file on-the-fly under MVC2 - asp.net-mvc-2

I have an application that in the admin area there is options such as
Background image: [ File Upload ]
Top Illustration: [ File Upload ]
and in the front end I want to easily attach this info to the CSS, maybe teh simply way should be
.background {
background: url(<%: Model.BackgroundUrl %>);
...
}
I currently have my Css files unde ~/Content/Css
shall I have a View with this and change the content type so I can use the Model part?
What other techniques are available or this situation?
Thank you.

You cannot use the model in a static CSS file. If you want to achieve this you will need to generate it dynamically using a controller action. As an alternative you could directly use an img tag:
<img src="<%: Model.BackgroundUrl %>" alt="" />

I ended up doing a new View and set all up as:
in the Master Template
<link href="<%= Url.Content(
String.Format("~/{0}/Css/CustomCss.aspx",
ViewData["CalendarUrl"])) %>"
rel="stylesheet" type="text/css" />
in the Routes
routes.MapRoute(
"CustomCss", // Route name
"{calurl}/Css/CustomCss.aspx", // URL with parameters
new { calurl = "none", controller = "Content", action = "CustomCss", id = UrlParameter.Optional } // Parameter defaults
);
in the Controller: Content, Action: CustomCss
// GET: /Css/CustomCss
public ActionResult CustomCss(string calurl)
{
return View();
}
in my View (placed in Shared):
<%# Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>"
ContentType="text/css" %>
<%
string company_logo = ViewData["CompanyLogo"] as string;
string company_bkg = ViewData["CompanyBackground"] as string;
%>
.background {
<%if (!String.IsNullOrWhiteSpace(company_bkg))
{ %>background-image:url('<%: company_bkg %>');<%} %>
}
#header-content{
<%if (!String.IsNullOrWhiteSpace(company_logo ))
{ %>background-image:url('<%: company_logo %>');<%} %>
}

Related

vue-chartjs and custom legend using generateLegend()

The generateLegend() wrapper does call the legendCallback defined in my Vue code but I'm lost to how to render the custom HTML in vue-chartjs. What do I do with htmlLegend as described in the vue-chartjs api docs like here.
Here is the line chart component I'm trying to render with a custom HTML object.
import { Line, mixins } from 'vue-chartjs'
const { reactiveProp } = mixins
export default {
extends: Line,
mixins: [reactiveProp],
props: ['chartData','options'],
data: () => ({
htmlLegend: null
}),
mounted () {
this.renderChart(this.chartData, this.options);
this.htmlLegend = this.generateLegend();
}
}
Here is my vue template
<template>
<div class="col-8">
<line-chart :chart-data="datacollection" :options="chartOptions"></line-chart>
</div>
</template>
Well, htmlLegend holds the markup of the generated legend... so you can just put it into your tag via v-html
<template>
<div class="col-8">
<div class="your-legend" v-html="htmlLegend" />
<line-chart :chart-data="datacollection" :options="chartOptions"></line-chart>
</div>
</template>
mounted() {
this.renderChart( this.chartData , this.options );
var legend = this.generateLegend();
this.$emit('sendLegend', legend)
}
and then in the vue file add a new div to show the legend and also listen to the event to get the legend data
<div class="line-legend" v-html="chartLegend"></div>
<line-chart #sendLegend="setLegend" :chart-data="datacollection" :options="chartOptions"></line-chart>
and also add this to the data
chartLegend: null,
and you also need a method
setLegend (html) {
this.chartLegend = html
},

How to include and use tinymce in a svelte component?

I want to include an external rtf component in my svelte app.
I tried adding tinymce using the cdn in template.htm and then creating the following svelte component. The editor renders, however I can't get data into or out of the editor.
<script>
import { onMount, tick } from 'svelte'
export let label = ''
export let value = ''
$: console.log('value', value)
onMount(() => {
tinymce.init({
selector: '#tiny',
})
})
</script>
<p>
<label class="w3-text-grey">{label}</label>
<textarea id="tiny" bind:value />
</p>
Super old but encountered this today and found a solution.
Solution:
<svelte:head>
<script src="https://cdn.tiny..."></script>
</svelte:head>
<script>
import {onMount} from 'svelte';
let getHTML;
let myHTML;
onMount(() => {
tinymce.init({
selector: '#tiny'
})
getHTML = () => {
myHTML = tinymce.get('tiny').getContent();
}
})
</script>
<textarea id="tiny" bind:value />
<!-- click to get html from the editor -->
<button on:click={getHTML}>Get HTML from TinyMCE</button>
<!-- html is printed here -->
{myHTML}
Explanation:
My initial thought was to bind per normal with
<textarea bind:value></textarea>
but that doesn't work I think because tinyMCE is doing complicated stuff in the background. Instead of adding the cdn reference in template.htm I used <svelte:head> so it only is loaded for this component. The function tinymce.get('...').getContent() must be called to get the contents of the editor, but it requires tinyMCE, so it must be called within the onMount. So I define a function getHTML within onMount. Now getHTML can be used anywhere to assign the contents of the editor to myHTML.
step one:
run this command on in your terminal
npm install #tinymce/tinymce-svelte
(reference for installation : https://www.tiny.cloud/docs/integrations/svelte/)
step two :
<script>
import { onMount } from 'svelte';
let myComponent;
let summary='';
onMount(async()=>{
const module=await import ('#tinymce/tinymce-svelte');
myComponent=module.default;
})
</script>
step three :
<svelte:component this={myComponent} bind:value={summary}/>
{#html summary}

web.py markdown global name 'markdown' is not defined

Im trying to use markdown together with Templetor in web.py but I can't figure out what Im missing
Documentation is here http://webpy.org/docs/0.3/templetor#builtins
import markdown
t_globals = {
'datestr': web.datestr,
'markdown': markdown.markdown
}
render = web.template.render(globals=t_globals)
class Blog:
def GET(self, post_slug):
""" Render single post """
post = BlogPost.get(BlogPost.slug == post_slug)
render = web.template.render(base="layout")
return render.post({
"blogpost_title": post.title,
"blogpost_content": post.content,
"blogpost_teaser": post.teaser
})
here is how I try to use markdown inside the post.html template
$def with (values)
$var title: $values['blogpost_title']
<article class="post">
<div class="post-meta">
<h1 class="post-title">$values['blogpost_title']</h1>
</div>
<section class="post-content">
<a name="topofpage"></a>
$:markdown(values['blogpost_content'])
</section>
But Im getting this exception
type 'exceptions.NameError' at
/blog/he-ll-want-to-use-your-yacht-and-i-don-t-want-this-thing-smelling-like-fish/
global name 'markdown' is not defined
You're re-initializing render, once in global scope setting globals and once within Blog.GET setting base. Do it only once!

The requested view was not found in TYPO3

I have my controller in the folder controllers with the name AdController
and my action name is
/**
* action ajaxValue
*
* #param string $argument
* #return void
*/
public function ajaxValueAction($argument = NULL) {
}
and my template file is on location Resources/Private/Templates/Ad/ajaxValue.html
with the name ajaxValue.html
{namespace t=Helhum\TyposcriptRendering\ViewHelpers}
<f:layout name="Default" />
This Template is responsible for creating a table of domain objects.
If you modify this template, do not forget to change the overwrite settings
in /Configuration/ExtensionBuilder/settings.yaml:
Resources:
Private:
Templates:
List.html: keep
Otherwise your changes will be overwritten the next time you save the extension in the extension builder
<f:section name="main">
<f:debug title="Results of customers query">{ads}</f:debug>
<f:flashMessages />
<!-- Category selection box -->
<!-- This is basically called a ajax request which is based on some other file take from the following link http://ajax.helmut-hummel.de/
-->
<div id="dataJson" data-url="{t:uri.ajaxAction(action: 'ajaxValue', format: 'json', controller: 'Ad', pluginName: 'Txcasmarketing') -> f:format.htmlentities()}"></div>
<div class="container">
<div class="btn-group">
<a class="btn btn-primary dropdown-toggle" data-toggle="dropdown" href="#">Select Category<span class="caret"></span></a>
<ul class="dropdown-menu">
<f:for each="{categories}" as="category">
<li>
<a data-catUid="{category.uid}" href="#">{category.name}</a>
</li>
</f:for>
</ul>
</div>
</div>
I am getting the following error
<p><strong>Sorry, the requested view was not found.</strong></p> <p>The technical reason is: <em>No template was found. View could not be resolved for action "ajaxValue" in class "CASmarketing\Casmarketing\Controller\AdController"</em>.</p>
The defaults templates which has been created by extension builder is accessible. the structure of my ex_localconf.php is
\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
'CASmarketing.Casmarketing',
'Txcasmarketing', [
'State' => 'list, show, new, create, edit, update, delete',
'Category' => 'list, show, new, create, edit, update, delete',
'Ad' => 'list, ajaxValue, show, new, create, edit, update, delete'
],
// non-cacheable actions
[
'State' => 'create, update, delete',
'Category' => 'create, update, delete',
'Ad' => 'create, update, delete'
]
);
}, $_EXTKEY
);
and my template file is on location Resources/Templates/Ad/ajaxValue.html
with the name ajaxValue.html
and my step.ts file sitting is
plugin.tx_casmarketing_txcasmarketing {
view {
templateRootPaths.0 = EXT:casmarketing/Resources/Private/Templates/
templateRootPaths.1 = {
$plugin.tx_casmarketing_txcasmarketing.view.templateRootPath}
partialRootPaths.0 = EXT:casmarketing/Resources/Private/Partials/
partialRootPaths.1 = {
$plugin.tx_casmarketing_txcasmarketing.view.partialRootPath}
layoutRootPaths.0 = EXT:casmarketing/Resources/Private/Layouts/
layoutRootPaths.1 = {
$plugin.tx_casmarketing_txcasmarketing.view.layoutRootPath}
}
persistence {
storagePid = {
$plugin.tx_casmarketing_txcasmarketing.persistence.storagePid}
#recursive = 1
}
features {
#skipDefaultArguments = 1
}
mvc {
#callDefaultActionIfActionCantBeResolved = 1
}
}
my script file which is basically called the ajax request which is define in the pageLayout.js
$(".dropdown-menu li a").click(function () {
var jsonUrl = $('#dataJson').attr('data-url')
var selectedCatUid = $(this).attr('data-catUid');
$.ajax({
type: 'POST',
url: jsonUrl,
data: {
'tx_casmarketing_txcasmarketing[catId]': selectedCatUid
},
success: function (response) {
alert(response);
},
});
Your template should not be in Resources/Templates/Ad/ajaxValue.html but in Resources/Private/Templates/Ad/AjaxValue.html. Mind the Private sub folder. Also it has to be UpperCase.
Didn't know that it does matter but the filename usually is uppercase. You also should make sure that the typoscript settings are configured to this directory.
Your typoscript should correctly look like this:
plugin.tx_casmarketing_txcasmarketing {
view {
templateRootPaths.0 = EXT:casmarketing/Resources/Private/Templates/
templateRootPaths.1 = {$plugin.tx_casmarketing_txcasmarketing.view.templateRootPath}
partialRootPaths.0 = EXT:casmarketing/Resources/Private/Partials/
partialRootPaths.1 = {$plugin.tx_casmarketing_txcasmarketing.view.partialRootPath}
layoutRootPaths.0 = EXT:casmarketing/Resources/Private/Layouts/
layoutRootPaths.1 = {$plugin.tx_casmarketing_txcasmarketing.view.layoutRootPath}
}
persistence {
storagePid = {$plugin.tx_casmarketing_txcasmarketing.persistence.storagePid}
#recursive = 1
}
features {
#skipDefaultArguments = 1
}
mvc {
#callDefaultActionIfActionCantBeResolved = 1
}
}
If you change this in your setup.txt of the extension this is hardly cached and you have to clear the cache in the install tool. After making sure your typoscript is correctly loaded place your new Views template inside the ext-directory template path first to try it out.
If this does not help please give us the content of your HTML Template.

How can I generate pages in Assemble based on an different json files?

So I have a folder rules that that looks like this:
rule-001.json
rule-002.json
rule-003.json
Each *.json file is of a unified format:
{ name: 'AAA', descriptions: 'BBB' }
How can I generate a pages based on these files in Assemble?
The short answer is that you need to load your JSON data in your Gruntfile and use it to replace the Assemble pages object.
I have written a blog post about generating pages from data, based on the Assemble Blog Theme sample. In both cases, the pages data was stored in a single JSON file.
In your case, you need to load the data from all of JSON files in your Gruntfile, and transform the data into the pages format. You can do this any number of ways, but one simple way would be to write a function in your Gruntfile that does this:
function loadDataPages (jsonFileSpec) {
var path = require("path");
var jsonPaths = grunt.file.expand(jsonFileSpec);
var jsonPages = jsonPaths.map(function (jsonPath) {
var jsonData = grunt.file.readJSON(jsonPath);
var outputFileName = path.basename(jsonPath, path.extname(jsonPath)) + ".html";
var jsonPage = {
"data": jsonData,
"content": "This is the body content for page " + outputFileName,
"filename": outputFileName
};
return jsonPage;
});
return jsonPages;
}
and then you need to load this data object in your Grunt config and pass it to Assemble's pages option:
grunt.initConfig({
assemble: {
data: {
options: {
flatten: true,
layout: "source/templates/layouts/custom-data-layout.hbs",
pages: loadDataPages("source/custom-data/*.json")
},
files: {
"output/custom-data-pages/": ["source/custom-data/index.hbs"]
}
}
}
// ...
});
Here is what the layouts might look like:
custom-data-layout.hbs
<!DOCTYPE html>
<html>
<head>
<title>Custom Data - {{name}}</title>
</head>
<body>
<h1>Custom Data - {{name}}</h1>
<p>{{ description }}</p>
{{> body }}
</body>
</html>
index.hbs
---
layout: false
title: Custom Data Index
---
<!DOCTYPE html>
<html>
<head>
<title>{{title}}</title>
</head>
<body>
<h1>{{title}}</h1>
<ul>
{{#each pages }}
<li>{{basename}}</li>
{{/each}}
</ul>
</body>
</html>
Something like this should work for you. You just create separate Assemble tasks and call the main Assemble task with grunt.
https://gist.github.com/davidwickman/a0bf961e3099ea6b9c35