Schnell mal alle laufenden Crawls in der SharePoint-Farm stoppen?
Einfach:
Mittwoch, 9. August 2017
Inhalt des SharePoint SecureStore auflisten
Den Inhalt des SecureStore auflisten ist im Grunde keine gute Idee. Immerhin ist der Inhalt "sicher"..
Manchmal muss aber trotzdem einen Blick darauf werfen - entweder weil keiner die Einstellungen der DEV-VM dokumentiert hat oder weil der Kunde sich gerade nicht sicher ist was denn nun eingestellt ist...
Den Inhalt aufzulisten ist per PowerShell einfach möglich:
Manchmal muss aber trotzdem einen Blick darauf werfen - entweder weil keiner die Einstellungen der DEV-VM dokumentiert hat oder weil der Kunde sich gerade nicht sicher ist was denn nun eingestellt ist...
Den Inhalt aufzulisten ist per PowerShell einfach möglich:
Freitag, 21. Oktober 2016
Auflistung aller e-Mail fähigen Listen in der SharePoint-Farm
Es sollen "mal schnell" alle Listen & Bibliotheken aufgelistet werden, für die ein e-Mail Empfang konfiguriert ist? Nichts leichter als das:
Das Skript kann als Eingabe für Out-GridView oder auch Export-Csv verwendet werden - oder auch nur in der Console betrachtet...
Und so ganz nebenbei prüft das Skript noch ob der e-Mail Empfang in der Farm überhaupt eingerichtet ist..
<#
.SYNOPSIS
Lists all E-Mail enabled lists
If all is fine here you'll need to check
Resolve-DnsName <your-mail-domain-here> -Type MX #make sure the "right" server is the MX
Get-WindowsFeature smtp-server #make sure InstallState is "installed"
Get-Service SMTPSVC #make sure Status is "running"
.EXAMPLE
Get-SPEmailEnabledLists
Gets all e-Mail enabled lists from all webs in all site collections from all WebApplications. This may be a lot to check: You have been warned.
.EXAMPLE
Get-SPEmailEnabledLists -WebApplication (Get-SPWebApplication http://sp.dev/)
Gets all e-Mail enabled lists from all webs in all site collections of the given WebApplication
.EXAMPLE
Get-SPSite | ?{$_.Url - match "my."} | Get-SPEmailEnabledLists
Gets all e-Mail enabled lists from all webs in the given site collections
.EXAMPLE
Get-SPWeb http://sp.dev/sites/simple/sub | Get-SPEmailEnabledLists
Gets all e-Mail enabled lists from the given web
#>
[CmdletBinding()]
param(
[Parameter(
HelpMessage="restrict search to this web",
ValueFromPipeline=$true)]
[Microsoft.SharePoint.SPWeb[]]$Web,
[Parameter(
HelpMessage="restrict search to this site collection",
ValueFromPipeline=$true)]
[Microsoft.SharePoint.SPSite[]]$Site,
[Parameter(
HelpMessage="restrict search to this webApplication",
ValueFromPipeline=$true)]
[Microsoft.SharePoint.Administration.SPWebApplication[]]$WebApplication
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction Inquire | Out-Null
# check incoming mail settings
$serverAddr = "<unconfigured>";
$settings = (Get-SPFarm).Services | ?{ $_.TypeName -match "incoming e-mail" } | select -First 1
if((-not $settings) -or (-not $settings.Enabled)){
$url = "_admin/IncomingEmail.aspx";
$ca = (Get-SPWebApplication -IncludeCentralAdministration) | ?{ $_.IsAdministrationWebApplication } | select -First 1
if($ca) {
$url = $ca.Url + $url;
} else {
$url = "http://<your central admin>/$url";
}
Write-Warning "No incoming email-settings found, or incoming email is deactivated. check $url !"
} else {
$serverAddr = $settings.ServerDisplayAddress;
}
# collect the lists to check
if(-not $Web) {
Write-Verbose "no web given - getting all webs from site";
if(-not $Site) {
Write-Verbose "no site given - getting all sites from webApplication";
if(-not $WebApplication) {
Write-Verbose "no webApplication given - getting all webApplications";
$WebApplication = Get-SPWebApplication;
}
$Site = $WebApplication | % { $_.Sites };
}
$Web = $Site | %{ $_.AllWebs };
}
# check the lists
$lists = $Web | %{ $_.Lists }
Write-Verbose "checking $($lists.Count) lists...";
$lists | %{
if(($_.CanReceiveEmail) -and ($_.EmailAlias)) {
[PSCustomObject]@{
Title = $_.Title;
Url = "$($_.ParentWeb.Url)/$($_.RootFolder.Url)";
EmailAlias = "$($_.EmailAlias)@$serverAddr";
}
}
}
Das Skript kann als Eingabe für Out-GridView oder auch Export-Csv verwendet werden - oder auch nur in der Console betrachtet...
Und so ganz nebenbei prüft das Skript noch ob der e-Mail Empfang in der Farm überhaupt eingerichtet ist..
Dienstag, 17. Mai 2016
SharePoint eine Test-Mail versenden lassen
Auf die spannende Frage "Warum versendet SharePoint keine Mails?" gibt es in der Regel nur wenige Antworten.
Wenn die Einstellungen der ausgehenden Mails ("Configure outgoing e-mail settings") in SharePoint gut aussehen hilft meistens nur testen und das ULS-Log beobachten.
Das folgende PowerShell-Skript kann verwendet werden um schnell Test-Mails aus dem SharePoint versenden zu lassen (Dabei kann man dann das ULS-Log - am besten mittels ULS Viewer - beobachten)
Wenn die Einstellungen der ausgehenden Mails ("Configure outgoing e-mail settings") in SharePoint gut aussehen hilft meistens nur testen und das ULS-Log beobachten.
Das folgende PowerShell-Skript kann verwendet werden um schnell Test-Mails aus dem SharePoint versenden zu lassen (Dabei kann man dann das ULS-Log - am besten mittels ULS Viewer - beobachten)
function Send-SPTestMail {
<#
.SYNOPSIS
Sends a Test-Mail using SharePoint-Standard Tools
returns "TRUE", if the mail was successfully "taken in" with SharePoint (most probably also given to smtp...)
and "FALSE" if there was any failure to do so.
Check your ULS-Logs for further investigation if the result is FALSE, or your smtp-server-logs if the result is TRUE
.PARAMETER To
"TO" field of the mail.
.PARAMETER Web
The Url to the SPWeb to access via the SharePoint e-Mail utilities
.PARAMETER From
"FROM" field of the mail. defaults to "someone@example.com"
.PARAMETER Subject
"SUBJECT" field of the mail. Defaults to "Test" and a Date.
.PARAMETER Body
"BODY" of the mail. Defaults to some nice text.
.EXAMPLE
Send-SPTestMail -Web http://path.to/Web -From me@acme.com
Sends a simple mail using all the nice deafults..
#>
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[string]$Web,
[Parameter(Mandatory=$true)]
[string]$To,
[Parameter(Mandatory=$false)]
[string]$From = "someone@example.com",
[Parameter(Mandatory=$false)]
[string]$Subject = $null,
[Parameter(Mandatory=$false)]
[string]$Body = $null
)
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction Stop
$headers = new-object System.collections.Specialized.StringDictionary
if(!$Subject) {
$Subject = "Test @ $(Get-Date)";
}
$headers.add("to",$To)
$headers.add("from",$From)
$headers.add("Subject",$Subject)
if(!$Body){
$Body = "Auto-Generated body of test-mail <ul><li>Generated at $(Get-Date)</li><li>Headers:<ul>";
$headers | % { $Body += "<li>$($_.Name): $($_.Value)</li>"; }
$Body += "</ul></li><li>Sent via SharePoint-Web at $($Web)</li></ul>";
}
$spweb = $null;
try {
$spweb = Get-SPWeb $Web -ErrorAction Stop
[Microsoft.SharePoint.Utilities.SPUtility]::SendEmail($spweb,$headers,$Body)
} finally {
if($spweb -ne $null) {
$spweb.Dispose();
}
}
}
Donnerstag, 28. April 2016
web.config-transform - "my way"
Ich mag die Web.Config-Transforms. Sehr sogar.
Was mich daran stört ist, dass ich eine Build-Konfiguration für jede Stage/jeden Server benötige. Um das zu umgehen (und ggf. vielleicht auch einmal andere xml-Dateien zu transformieren) kann die Transformation auch manuell über einen MSBuild-Task starten.
Im Regelfall habe ich meine Transformationen im "Configs\"-Verzeichnis mit der Benennung web.[stage].conf - die lasse ich dann automatisiert beim build & publish erstellen. Dafür habe ich das folgende targets-file, das ich einfach im csproj einbinde:
Die Einbindung im projekt-file erfolgt ganz "normal".
In einem aktuellen Projekt bestand die Anforderung die Transformationen in Unterverzeichnissen abzulegen (da es noch mehr spezifische Dateien pro Stage gab...). Dafür habe einfach die ItemGruop wie folgt angepasst:
Was mich daran stört ist, dass ich eine Build-Konfiguration für jede Stage/jeden Server benötige. Um das zu umgehen (und ggf. vielleicht auch einmal andere xml-Dateien zu transformieren) kann die Transformation auch manuell über einen MSBuild-Task starten.
Im Regelfall habe ich meine Transformationen im "Configs\"-Verzeichnis mit der Benennung web.[stage].conf - die lasse ich dann automatisiert beim build & publish erstellen. Dafür habe ich das folgende targets-file, das ich einfach im csproj einbinde:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<SourceWebConfig>$(ProjectDir)\Web.config</SourceWebConfig>
<OutputPath Condition="'$(OutputPath)' == ''">$(ProjectDir)\bin</OutputPath>
<TempWebConfig>$(OutputPath)\Web.Temp.config</TempWebConfig>
<TransformationsBaseDir>$(ProjectDir)\Configs</TransformationsBaseDir>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">11.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets"/>
<ItemGroup>
<WebConfigTransforms Include="$(TransformationsBaseDir)/*.config">
<TransformDest>$(OutputPath)\%(WebConfigTransforms.Filename).config</TransformDest>
</WebConfigTransforms>
</ItemGroup>
<Target Name="TransformAllWebConfigs">
<!-- Does the real transformation of all web-config transforms... -->
<Copy SourceFiles="$(SourceWebConfig)"
DestinationFiles="$(TempWebConfig)" />
<Message Text="transforming %(WebConfigTransforms.Identity) to %(WebConfigTransforms.TransformDest)"
Importance="high"/>
<TransformXml Source="$(TempWebConfig)"
Transform="%(WebConfigTransforms.Identity)"
Destination="%(WebConfigTransforms.TransformDest)"
StackTrace="true" />
<Delete Files="$(TempWebConfig)" />
</Target>
<Target Name="TransformAfterBuild"
AfterTargets="Build">
<!-- after build, build all web.configs, too -->
<CallTarget Targets="TransformAllWebConfigs" />
<Message Text="TransformAllWebConfigs has run after build!"
Importance="high"/>
</Target>
<Target Name="MimicVsTransforms"
AfterTargets="PreTransformWebConfig">
<!-- this should mimic the original VS-behaviour -->
<CallTarget Targets="TransformAllWebConfigs" />
</Target>
<Target Name="CopyTransformedForPublish"
AfterTargets="CopyAllFilesToSingleFolderForPackage">
<!-- "GatherAllFilesToPublish" as AfterTarges seems to work, too. But only when Publish is called from within VS. -->
<Copy SourceFiles="@(WebConfigTransforms->'%(TransformDest)')"
DestinationFolder="$(WPPAllFilesInSingleFolder)" />
</Target>
</Project>
Die Einbindung im projekt-file erfolgt ganz "normal".
<Import Project="$(ProjectDir)\..\TransformWebConfig.targets" Condition="'$(TransformationsBaseDir)' == ''" />
In einem aktuellen Projekt bestand die Anforderung die Transformationen in Unterverzeichnissen abzulegen (da es noch mehr spezifische Dateien pro Stage gab...). Dafür habe einfach die ItemGruop wie folgt angepasst:
<ItemGroup>
<WebConfigTransforms Include="$(TransformationsBaseDir)\**\web.config">
<StageName>$([System.String]::new('%(RecursiveDir)').TrimEnd('\\'))</StageName>
<TransformDest>$(OutputPath)\web.%(StageName).config</TransformDest>
</WebConfigTransforms>
</ItemGroup>
Mittwoch, 9. März 2016
Erstellen einer StringCollection in PowerShell, OutputType und unrolling
Im SharePoint-Kontext benötigt man immer mal wieder eine StringCollection (System.Collections.Specialized.StringCollection). Um diese zu erstellen wollte ich "kurz" eine PowerShell-Funktion dazu erstellen. Drei Punkte habe ich dabei gelernt:
- Der OutputType einer Funktion wird nur für Autovervollständigung z.B. in der ISE benutzt. Der "wirkliche" Rückgabe-Typ entspricht immer der eigentlichen Rückgabe zur Laufzeit.
- Rückgaben, die eine Auflistung sind werden "unrolled". D.h. diese erscheinen in der Rückgabe dann als normales Array.
- "unrolling" kann in der Rückgabe verhindert werden wenn dieser ein Komma vorgestellt wird. (Also "return ,$foo;" - reichlich komisch...)
function Create-StringCollection {
<#
.SYNOPSIS
Creates a StringCollection from a array of strings
.PARAMETER txt
strings to convert
.EXAMPLE
@("foo", "bar") | Create-StringCollection
#>
[CmdletBinding()]
[OutputType([System.Collections.Specialized.StringCollection])]
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$True)]
[string[]]$txt
)
Begin {
$coll = New-Object System.Collections.Specialized.StringCollection;
}
Process {
$coll.Add($txt) | Out-Null;
}
End {
,$coll; # hack to prevent powershell from "unrolling" the enumerable
}
}
Montag, 12. Oktober 2015
SyntaxHighlighter im SharePoint
In diesem Bog verwende ich den Syntax Highlighter von Alex Gorbatchev - ich finde Code sieht dann gut aus.
Im SharePoint habe ich den bisher immer vermisst. Das hat nun ein ende: Ich habe eine Sandbox-Solution erstellt, die die Dateien des Syntax Highlighter im SharePoint (auf SiteCollectioin-Ebene) bereitstellt und zusätzlich ein Feature (auf Web-Ebene) dass jede angezeigte Seite nach Syntax Highlighter-Formatierungen durchsucht und die entsprechenden Dateien dynamisch lädt.
Dafür habe ich das folgende js-File verwendet:
Teile des Skriptes (z.B. die Verfügbaren "brushes") lasse ich dabei auto-generieren mittels eines T4-Templates.
Die Sourcen für das ganze habe ich auf bitbucket.
Im SharePoint habe ich den bisher immer vermisst. Das hat nun ein ende: Ich habe eine Sandbox-Solution erstellt, die die Dateien des Syntax Highlighter im SharePoint (auf SiteCollectioin-Ebene) bereitstellt und zusätzlich ein Feature (auf Web-Ebene) dass jede angezeigte Seite nach Syntax Highlighter-Formatierungen durchsucht und die entsprechenden Dateien dynamisch lädt.
Dafür habe ich das folgende js-File verwendet:
if (!!window.Type) {
//this is 'normal'
Type.registerNamespace('SpSyntaxHighlighter');
} else {
//this happend on i.e. EditBlog.aspx
window.SpSyntaxHighlighter = window.SpSyntaxHighlighter || {};
}
SpSyntaxHighlighter.shAutoConfig = [[ 'applescript' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushAppleScript.js'],
[ 'actionscript3', 'as3' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushAS3.js'],
[ 'bash', 'shell' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushBash.js'],
[ 'coldfusion','cf' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushColdFusion.js'],
[ 'cpp', 'c' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushCpp.js'],
[ 'c#', 'c-sharp', 'csharp' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushCSharp.js'],
[ 'css' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushCss.js'],
[ 'delphi', 'pascal', 'pas' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushDelphi.js'],
[ 'diff', 'patch' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushDiff.js'],
[ 'erl', 'erlang' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushErlang.js'],
[ 'groovy' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushGroovy.js'],
[ 'java' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushJava.js'],
[ 'jfx', 'javafx' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushJavaFX.js'],
[ 'js', 'jscript', 'javascript' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushJScript.js'],
[ 'perl', 'Perl', 'pl' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPerl.js'],
[ 'php' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPhp.js'],
[ 'text', 'plain' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPlain.js'],
[ 'powershell', 'ps' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPowerShell.js'],
[ 'py', 'python' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushPython.js'],
[ 'ruby', 'rails', 'ror', 'rb' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushRuby.js'],
[ 'sass', 'scss' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushSass.js'],
[ 'scala' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushScala.js'],
[ 'sql' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushSql.js'],
[ 'vb', 'vbnet' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushVb.js'],
[ 'xml', 'xhtml', 'xslt', 'html' , '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/shBrushXml.js']];
SpSyntaxHighlighter.canApplySyntaxHighlighter = function () {
/// Check, if SyntaxHighlighter should be applied. I.e. returns false, if something is in edit mode..
/// fals, if loading of SyntaxHighlighter should be disabled
var rteFields = document.getElementsByClassName('ms-rtefield');
// check if page is in edit-mode or edit-form or something..
// do not (!) modify source in an editor - because that will lead to the modification being saved...
if (rteFields.length > 0) {
SP.UI.Notify.addNotification('Edit-Mode detected. SyntaxHighlighter disabled.', false);
return false;
}
return true;
};
SpSyntaxHighlighter.addEvent = function (elm, evt, func) {
if (elm.addEventListener) {
elm.addEventListener(evt, func);
} else if (elm.attachEvent) {
elm.attachEvent('on' + evt, func);
} else {
elm['on' + evt] = func;
}
};
SpSyntaxHighlighter.removeEvent = function (elm, evt, func) {
if (elm.removeEventListener) {
elm.removeEventListener(evt, func);
} else if (elm.detachEvent) {
elm.detachEvent('on' + evt, func);
} else {
elm['on' + evt] = null;
}
};
SpSyntaxHighlighter.loadScript = function (url, successHandler, errorHandler) {
var script = document.createElement('script'),
loaded, error;
script.src = url;
script.type = 'text/javascript';
script.language = 'javascript';
loaded = function () {
SpSyntaxHighlighter.removeEvent(script, 'load', loaded);
SpSyntaxHighlighter.removeEvent(script, 'error', error);
if (successHandler) {
successHandler(script);
}
};
error = function () {
SpSyntaxHighlighter.removeEvent(script, 'load', loaded);
SpSyntaxHighlighter.removeEvent(script, 'error', error);
if (errorHandler) {
errorHandler();
}
};
SpSyntaxHighlighter.addEvent(script, 'load', loaded);
SpSyntaxHighlighter.addEvent(script, 'error', error);
document.body.appendChild(script);
};
SpSyntaxHighlighter.loadCss = function (url) {
var link = document.createElement('link');
link.href = url;
link.type = 'text/css';
link.rel = 'stylesheet';
document.head.appendChild(link);
};
SpSyntaxHighlighter.loadBrushes = function(success) {
// replaces shAutoloader.js - I dont like the way it works...
var oldHighlight = SyntaxHighlighter.highlight,
highlightCalled = false,
elements = SyntaxHighlighter.findElements(),
processes = [{
id: 'loadBrushes',
done: false
}],
chechAllDone = function () {
var done = true,
i;
for (i = 0; i < processes.length; i += 1) {
if (!(processes[i].done)) {
done = false;
break;
}
}
if(done){
// everything is done. finish here...
SyntaxHighlighter.highlight = oldHighlight;
if(highlightCalled !== false) {
SyntaxHighlighter.highlight.call(SyntaxHighlighter, highlightCalled);
}
if (!!success) {
success();
}
}
},
buildBrushes = function(){
var cfg = SpSyntaxHighlighter.shAutoConfig,
brushes = {},
cfgLine,
url,
i,j;
for(i=0; i< cfg.length; i+=1) {
cfgLine = cfg[i];
url = cfgLine[cfgLine.length-1];
for(j=(cfgLine.length-2); j >= 0; j -=1) {
brushes[cfgLine[j]] = url;
}
}
return brushes;
},
brushes = buildBrushes(),
processing = function(id) {
var i;
for(i=0; i < processes.length; i+=1) {
if(id === processes[i].id) {
return processes[i];
}
}
return false;
},
i,
alias,
url;
SyntaxHighlighter.highlight = function (parm) {
// dont call highlight while Im searching
highlightCalled = parm;
};
// now process the elements..
for(i=0; i < elements.length; i+=1) {
alias = elements[i].params.brush;
url = brushes[alias];
if(!url) {
if(console && console.log){
console.log('no brush defined for alias: '+ alias);
}
continue;
}
if(!!processing(url)){
continue;
}
processes.push({
id: url,
done: false
});
if (!!window.SyntaxHighlighter.vars.discoveredBrushes) {
if (!!window.SyntaxHighlighter.vars.discoveredBrushes[alias]) {
// this brush was already loaded & discovered by SyntaxHighlighter. Theres nothing more to do...
processing(url).done = true;
continue;
}
}
(function() {
var urlClosure = url;
SpSyntaxHighlighter.loadScript(urlClosure, function () {
processing(urlClosure).done = true;
chechAllDone();
});
})();
}
// finished..
processing('loadBrushes').done = true;
chechAllDone();
};
SpSyntaxHighlighter.runSyntaxHighlighter = function () {
///
/// Re-Run SyntaxHighlighter, make sure SyntaxHighlighter was loaded before calling.
/// i.e. call loadSyntaxHighlighter first.
/// this functions does nothing, if an RichTextEditor is opened in the page!
///
if (!SpSyntaxHighlighter.canApplySyntaxHighlighter()) return;
SpSyntaxHighlighter.loadBrushes(function () {
SyntaxHighlighter.vars.discoveredBrushes = null; // let SyntaxHighlighter re-run brush-discovery
window.setTimeout(SyntaxHighlighter.highlight.bind(SyntaxHighlighter), 50);
});
};
SpSyntaxHighlighter.loadSyntaxHighlighter = function () {
var csspath = '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/styles/',
scriptpath = '~siteCollection/SiteAssets/SpSyntaxHighlighter/syntaxhighlighter/scripts/',
shTheme = 'shThemeDefault.css', //Possible Themes: shThemeDefault.css, shThemeDjango.css, shThemeEclipse.css, shThemeEmacs.css, shThemeFadeToGrey.css, shThemeMDUltra.css, shThemeMidnight.css, shThemeRDark.css
loadSyntaxHighlighter = function () {
// add SyntaxHighlighter, styles and autoloader, then run autoloader
SpSyntaxHighlighter.loadCss(csspath + 'shCore.css');
SpSyntaxHighlighter.loadCss(csspath + shTheme);
SpSyntaxHighlighter.loadScript(scriptpath + 'shCore.js', function () {
SpSyntaxHighlighter.SyntaxHighlighter = window.SyntaxHighlighter;
SpSyntaxHighlighter.runSyntaxHighlighter();
});
},
siteLoadFialed = function (err) {
if (console && console.log) {
console.log('accessing siteCollecion failed. ');
console.log('err was: ' + err);
console.log('execution aborted. :-(');
}
// this is the end of it. sadly.
},
siteLoadSucceded = function () {
var siteCollectionUrl = siteCollection.get_url(),
i, len, brushCfg, brushPath;
// fix up paths...
csspath = csspath.replace('~siteCollection', siteCollectionUrl);
scriptpath = scriptpath.replace('~siteCollection', siteCollectionUrl);
len = SpSyntaxHighlighter.shAutoConfig.length;
for (i = 0; i < len; i += 1) {
brushCfg = SpSyntaxHighlighter.shAutoConfig[i];
brushPath = brushCfg[brushCfg.length - 1];
brushCfg[brushCfg.length - 1] = brushPath.replace('~siteCollection', siteCollectionUrl);
}
// now start loading SyntaxHighlighter
loadSyntaxHighlighter();
},
siteCollection,
clientContext = SP.ClientContext.get_current(),
highlightable = document.getElementsByTagName('pre');
// check if syntaxHighlighter ist needed
if (highlightable.length < 1) return;
if (!SpSyntaxHighlighter.canApplySyntaxHighlighter()) return;
// load siteCollectionData then continue
siteCollection = clientContext.get_site();
clientContext.load(siteCollection);
clientContext.executeQueryAsync(siteLoadSucceded, siteLoadFialed);
};
SpSyntaxHighlighter.preLoadSyntaxHighlighter = function () {
if (!!SpSyntaxHighlighter.SyntaxHighlighter) {
//weve been here before :-)
window.SyntaxHighlighter = SpSyntaxHighlighter.SyntaxHighlighter;
SpSyntaxHighlighter.runSyntaxHighlighter();
return;
}
// load all from scratch...
SP.SOD.executeFunc('sp.js', 'SP.ClientContext', SpSyntaxHighlighter.loadSyntaxHighlighter);
};
SpSyntaxHighlighter.register = function () {
var thisUrl;
SpSyntaxHighlighter.preLoadSyntaxHighlighter();
if (!!window._spPageContextInfo) {
thisUrl = '~siteCollection/SiteAssets/SpSyntaxHighlighter/ShLoader.js'.replace('~siteCollection/', window._spPageContextInfo.siteServerRelativeUrl);
window.RegisterModuleInit(thisUrl, SpSyntaxHighlighter.preLoadSyntaxHighlighter);
}
};
//Simulate LoadAfterUi=true
window._spBodyOnLoadFunctionNames.push('SpSyntaxHighlighter.register');
Teile des Skriptes (z.B. die Verfügbaren "brushes") lasse ich dabei auto-generieren mittels eines T4-Templates.
Die Sourcen für das ganze habe ich auf bitbucket.
Abonnieren
Kommentare (Atom)