### Vue Script Setup Equivalent Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue-in-markdown Provides an equivalent example using Vue's ` ``` -------------------------------- ### Setup Typesense and Scraper in GitHub Action Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/typesense Shell commands to prepare the GitHub Actions workspace, copy configuration files, set up environment variables, start a Typesense server in Docker, and run the Typesense scraper. This prepares the data for inclusion in a Docker image. ```sh mkdir -p ${GITHUB_WORKSPACE}/typesense-data cp ./search-server/typesense-server/Dockerfile ${GITHUB_WORKSPACE}/typesense-data/Dockerfile cp ./search-server/typesense-scraper/typesense-scraper-config.json typesense-scraper-config.json envsubst < "./search-server/typesense-scraper/typesense-scraper.env" > "typesense-scraper-updated.env" docker run -d -p 8108:8108 -v ${GITHUB_WORKSPACE}/typesense-data/data:/data \ typesense/typesense:0.21.0 --data-dir /data --api-key=${TYPESENSE_API_KEY} --enable-cors & # wait for typesense initialization sleep 5 docker run -i --env-file typesense-scraper-updated.env \ -e "CONFIG=$(cat typesense-scraper-config.json | jq -r tostring)" typesense/docsearch-scraper ``` -------------------------------- ### Install @servicestack/vue via npm Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install Installs the @servicestack/vue package using npm. This command also automatically installs its dependencies, vue and @servicestack/client. ```bash $ npm install @servicestack/vue ``` -------------------------------- ### PreviewFormat: Link Display Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a URL as a clickable hyperlink using Formats.link. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### Use Formatters: Import and Usage Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Imports formatting functions from '@servicestack/vue' and demonstrates their availability. Includes formatters for currency, bytes, links, icons, dates, and more. ```javascript import { useFormatters } from '@servicestack/vue' const { Formats, formatValue, currency, bytes, link, linkTel, linkMailTo, icon, iconRounded, attachment, hidden, time, relativeTime, relativeTimeFromMs, formatDate, formatNumber, } = useFormatters() ``` -------------------------------- ### JavaScript Setup for Fetching Property Options Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/use-metadata This JavaScript code demonstrates the frontend setup using a `useMetadata` hook to retrieve property options. It shows how to obtain options for a specific property, like 'Color' from 'CreateContact', and pass them to UI components. ```javascript const Edit = { //... setup(props) { const { property, propertyOptions, enumOptions } = useMetadata() const colorOptions = propertyOptions(property('CreateContact','Color')) return { enumOptions, colorOptions } //.. } } ``` -------------------------------- ### Vue Tabs Component Setup Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/navigation Demonstrates the setup for the Vue Tabs component. It involves importing individual Vue components and creating a dictionary to map them for tab content. ```html ``` -------------------------------- ### PreviewFormat: Bytes Formatting Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a numeric value in human-readable disk size format using Formats.bytes. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### PreviewFormat: Attachment Display (Image) Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders an image URL as an attachment using Formats.attachment. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### PreviewFormat: Icon Display Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Displays an image URL as an icon using Formats.icon. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### Configure importmap for CDN usage Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install Sets up an HTML importmap to load ESM builds of vue, @servicestack/client, and @servicestack/vue directly from CDNs. This allows using the libraries without local installation. ```html ``` -------------------------------- ### Serving Prerendered Site Command Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/ssg Command to start a local HTTP server to preview the prerendered static site. The site is typically served from the 'dist' directory. ```bash npm run serve ``` -------------------------------- ### Run Local Typesense Server Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/typesense Command to start a local Typesense server using Docker, mapping the necessary port and volume, and enabling CORS. Replace '' with your desired API key. ```sh mkdir /tmp/typesense-data docker run -p 8108:8108 -v/tmp/data:/data typesense/typesense:0.21.0 \ --data-dir /data --api-key= --enable-cors ``` -------------------------------- ### PreviewFormat: Attachment Display (Document) Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a document URL as an attachment using Formats.attachment. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### Basic TextLink Example Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/navigation Demonstrates the basic usage of the TextLink component for creating standard hyperlinks with custom classes and content. ```html docs.servicestack.net/vue ``` -------------------------------- ### PreviewFormat: Currency Formatting Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a numeric value as currency using the Formats.currency option. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### Register @servicestack/vue with Vue app Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install Registers the @servicestack/vue component library with a Vue application. It also provides an example of creating and providing a JsonApiClient instance for API calls. ```javascript import { JsonApiClient } from "@servicestack/client" import ServiceStackVue from "@servicestack/vue" const client = JsonApiClient.create() const app = createApp(component, props) app.provide('client', client) app.use(ServiceStackVue) //... app.mount('#app') ``` -------------------------------- ### Markdown GitHub-Style Table Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/syntax Provides an example of a GitHub-Flavored Markdown table, showcasing column alignment and data entry. ```markdown | Tables | Are | Cool | | ------------- | :-----------: | ----: | | col 3 is | right-aligned | $1600 | | col 2 is | centered | $12 | | zebra stripes | are neat | $1 | ``` -------------------------------- ### PreviewFormat: Link with Custom Class Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a URL as a clickable hyperlink with custom CSS classes applied using Formats.link. Requires the PreviewFormat component, value, and class props. ```vue ``` -------------------------------- ### Todo Store Example with API Interaction Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/use-client Provides a JavaScript example of a Vue store (`store`) that interacts with API calls using `client.api`. It demonstrates refreshing todos, adding new todos, and handling API errors by updating the `store.error` property. ```javascript let store = { /** @type {Todo[]} */ todos: [], newTodo:'', error:null, async refreshTodos(errorStatus) { this.error = errorStatus let api = await client.api(new QueryTodos()) if (api.succeeded) this.todos = api.response.results }, async addTodo() { this.todos.push(new Todo({ text:this.newTodo })) let api = await client.api(new CreateTodo({ text:this.newTodo })) if (api.succeeded) this.newTodo = '' return this.refreshTodos(api.error) }, //... ``` -------------------------------- ### Manual API Call Example Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/use-client Shows a traditional way to instantiate `JsonServiceClient` and make an API call, requiring manual unwrapping of `ref` values for request parameters. ```javascript let client = new JsonServiceClient() let api = await client.api(new Hello({ name:name.value })) ``` -------------------------------- ### PreviewFormat: Attachment with Custom Classes Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a document URL as an attachment with custom text and icon classes using Formats.attachment. Requires PreviewFormat, value, class, and icon-class props. ```vue ``` -------------------------------- ### PreviewFormat: Icon with Custom Classes Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Displays an image URL as an icon with custom CSS classes applied using Formats.icon. Requires the PreviewFormat component, value, and class props. ```vue ``` -------------------------------- ### PreviewFormat: Email Link Display Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders an email address as a clickable mailto: link using Formats.linkMailTo. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### PreviewFormat: Phone Link Display Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a phone number as a clickable tel: link using Formats.linkTel. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### PreviewFormat: Rounded Icon Display Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Displays an image URL as a rounded icon using Formats.iconRounded. Requires the PreviewFormat component and a value prop. ```vue ``` -------------------------------- ### Update JavaScript Dependencies Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/what-is-razor-press Instructions for updating JavaScript dependencies and Markdown extensions using npm. In this template, running 'npm install' is an alias for 'node postinstall.js' as there are no direct npm dependencies. ```sh npm install ``` -------------------------------- ### Apply Format Attribute in C# DTO Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/use-formatters Shows how to decorate C# DTO properties with the `[Format]` attribute to apply custom formatting, referencing the `qrcode` formatter as an example. ```csharp [Format("qrcode")] public string Code { get; set; } ``` -------------------------------- ### Use Formatters: Rendering HTML Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Shows how to render formatted values that may contain rich HTML markup using Vue's v-html directive with the formatValue function. ```html ``` -------------------------------- ### HtmlFormat: Single Model Rendering Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders a single serializable object into a human-friendly HTML format using the HtmlFormat component. Requires the HtmlFormat component and a value prop. ```vue ``` -------------------------------- ### Razor Pages importmap integration Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install Integrates import maps into Razor Pages or MVC applications using the Html.ImportMap helper. It allows specifying local debug builds and production CDN hosted minified builds. ```csharp @Html.ImportMap(new() { ["vue"] = ("/lib/mjs/vue.mjs", "https://unpkg.com/vue@3/dist/vue.esm-browser.prod.js"), ["@servicestack/client"] = ("/lib/mjs/servicestack-client.mjs", "https://unpkg.com/@servicestack/client@2/dist/servicestack-client.min.mjs"), ["@servicestack/vue"] = ("/lib/mjs/servicestack-vue.mjs", "https://unpkg.com/@servicestack/vue@3/dist/servicestack-vue.min.mjs") }) ``` -------------------------------- ### Syntax Highlighting C# Code Block Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/syntax An example of a C# code block within Markdown, demonstrating how Razor Press uses highlight.js for syntax highlighting, following GitHub Code Blocks syntax. ```csharp class A { public string? B { get; set; } } ``` -------------------------------- ### Polyfill import maps for Safari Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install Includes a script tag to polyfill import map support for Safari browsers, which may not have native support or are in technical preview. It uses the pre-configured ES Module Shims. ```html @if (Context.Request.Headers.UserAgent.Any(x => x.Contains("Safari") && !x.Contains("Chrome"))) { } ``` -------------------------------- ### Use JsonServiceClient for older .NET or disabled /api route Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install Provides an alternative client instantiation for ServiceStack Apps not running on .NET 6+ or when the /api route is disabled. It uses JsonServiceClient instead of JsonApiClient. ```javascript const client = new JsonServiceClient() ``` -------------------------------- ### Scraper Configuration (.json) Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/typesense Defines the scraping parameters for the typesense-docsearch-scraper, including the index name, allowed domains, starting URLs, and CSS selectors for extracting content. This configuration dictates what data is scraped and how it's structured for indexing. ```json { "index_name": "typesense_docs", "allowed_domains": ["docs.servicestack.net"], "start_urls": [ { "url": "https://docs.servicestack.net/" } ], "selectors": { "default": { "lvl0": "h1", "lvl1": ".content h2", "lvl2": ".content h3", "lvl3": ".content h4", "lvl4": ".content h5", "text": ".content p, .content ul li, .content table tbody tr" } }, "scrape_start_urls": false, "strip_chars": " .,;:#" } ``` -------------------------------- ### Render Complex Data with HtmlFormat Component Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Demonstrates the basic usage of the HtmlFormat component to render a 'players' data structure. This component is designed for displaying complex data types within web templates, simplifying data visualization. ```html ``` -------------------------------- ### Configure importmap for local file usage Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install Configures an HTML importmap to load ESM builds of vue, @servicestack/client, and @servicestack/vue from local file paths. This is useful for intranet web apps needing offline access. ```html ``` -------------------------------- ### Register RouterLink for non-SPA Vue Apps Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/install For non-SPA Vue Apps not using Vue Router, this registers a replacement component that utilizes the browser's native navigation. This ensures proper routing in simpler Vue setups. ```javascript app.component('RouterLink', ServiceStackVue.component('RouterLink')) ``` -------------------------------- ### Preview Static Site Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/ssg Command to preview the generated static site. It launches a local HTTP server from the /dist folder, typically using npx http-server. ```shell npm run serve ``` -------------------------------- ### Running the Scraper with Docker Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/typesense Executes the typesense-docsearch-scraper Docker image, passing the environment file and the JSON configuration as an environment variable. This command initiates the scraping process, connecting to the Typesense server using the provided credentials. ```sh docker run -it --env-file typesense-scraper.env \ -e "CONFIG=$(cat typesense-scraper-config.json | jq -r tostring)" \ typesense/docsearch-scraper ``` -------------------------------- ### Build Static Site Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/ssg Command to build the static site. This process scans Razor Pages and prerenders them into static HTML files. ```shell npm run prerender ``` -------------------------------- ### Prerendering Site Command Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/ssg Command to execute the prerendering task for the static site. This command initiates the process that generates all static HTML files. ```bash npm run prerender ``` -------------------------------- ### Update JavaScript Dependencies Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/structure Command to update all JavaScript dependencies used in the project by running `npm install` in the `postinstall.js` script. ```sh npm install ``` -------------------------------- ### Markdown Input for YouTube Container Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/containers Example of how to use the custom YouTube inline container syntax within Markdown documents. ```markdown ::YouTube MRQMBrXi5Sc:: ``` -------------------------------- ### Initialize Markdown Features in Razor Press Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/structure Configures ASP.NET Core services and initializes markdown features like pages, whatsnew, videos, and meta by loading them from specified directories using the Virtual Files provider. ```C# public class ConfigureSsg : IHostingStartup { public void Configure(IWebHostBuilder builder) => builder .ConfigureServices(services => { context.Configuration.GetSection(nameof(AppConfig)).Bind(AppConfig.Instance); services.AddSingleton(AppConfig.Instance); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); }) .ConfigureAppHost(afterPluginsLoaded: appHost => { MarkdigConfig.Set(new MarkdigConfig { ConfigurePipeline = pipeline => { // Extend Markdig Pipeline }, ConfigureContainers = config => { config.AddBuiltInContainers(); // Add Custom Block or Inline containers } }); var pages = appHost.Resolve(); var whatsNew = appHost.Resolve(); var videos = appHost.Resolve(); var meta = appHost.Resolve(); meta.Features = new() { pages, whatsNew, videos }; meta.Features.ForEach(x => x.VirtualFiles = appHost.VirtualFiles); pages.LoadFrom("_pages"); whatsNew.LoadFrom("_whatsnew"); videos.LoadFrom("_videos"); }); }); //... } ``` -------------------------------- ### HtmlFormat: Item Collections Rendering Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/formats Renders an array of serializable objects into a human-friendly HTML format using the HtmlFormat component. Requires the HtmlFormat component and a value prop. ```vue ``` -------------------------------- ### What's New Feature Structure Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/structure Illustrates the file structure for the 'What's New' feature, which organizes releases by date and project name. It references the C# Markdown processor and Razor page renderer. ```files /_whatsnew /2023-03-08_Animaginary feature1.md /2023-03-18_OpenShuttle feature1.md /2023-03-28_Planetaria feature1.md ``` ```csharp // Markdown.WhatsNew.cs // Processes Markdown content for the 'What's New' feature. ``` ```razor // Pages/WhatsNew.cshtml // Renders the 'What's New' feature using Razor Pages. ``` -------------------------------- ### Search Content with curl and Typesense Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/typesense Demonstrates how to query a Typesense index using `curl`. Requires a Typesense server, an API key, collection name, and query parameters like `q` and `query_by`. ```sh curl -H 'x-typesense-api-key: ' \ 'http://localhost:8108/collections/typesense_docs/documents/search?q=test&query_by=content' ``` -------------------------------- ### Vue NavList Component Example Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/navigation Demonstrates the Vue NavList component for rendering vertical navigation menus. It includes a title and NavListItems, each with a title, href, and an optional SVG icon. ```html DataGrid Component Examples for rendering tabular data Instant customizable UIs for calling AutoQuery CRUD APIs ``` -------------------------------- ### Prerendering Dynamic Routes with IRenderStatic Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/ssg Implements dynamic route prerendering by defining a GetStaticProps method that returns a list of models. This follows Next.js getStaticProps convention for generating pages from data. ```csharp @page "/{slug}" @model MyApp.Page @implements IRenderStatic @functions { public List GetStaticProps(RenderContext ctx) { var markdown = ctx.Resolve(); return markdown.GetVisiblePages().Map(page => new Page { Slug = page.Slug! }); } } ``` -------------------------------- ### Configure Custom Domain with CNAME File Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/deployments Specifies the custom domain for GitHub Pages by saving the domain name in a CNAME file within the wwwroot directory. This file is automatically read by GitHub Pages to serve the site under the specified custom domain. ```text www.mydomain.org ``` -------------------------------- ### Registering Prerender AppTask Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/ssg Registers a custom 'prerender' AppTask within the ServiceStack application host. This task handles the static site generation process, including cleaning the output directory, copying assets, generating redirects, and prerendering Razor pages. ```csharp .ConfigureAppHost(afterAppHostInit: appHost => { // prerender with: `$ npm run prerender` AppTasks.Register("prerender", args => { appHost.Resolve().RenderToAsync( metaDir: appHost.ContentRootDirectory.RealPath.CombineWith("wwwroot/meta"), baseUrl: HtmlHelpers.ToAbsoluteContentUrl("")).GetAwaiter().GetResult(); var distDir = appHost.ContentRootDirectory.RealPath.CombineWith("dist"); if (Directory.Exists(distDir)) FileSystemVirtualFiles.DeleteDirectory(distDir); FileSystemVirtualFiles.CopyAll( new DirectoryInfo(appHost.ContentRootDirectory.RealPath.CombineWith("wwwroot")), new DirectoryInfo(distDir)); // Render .html redirect files RazorSsg.PrerenderRedirectsAsync(appHost.ContentRootDirectory.GetFile("redirects.json"), distDir) .GetAwaiter().GetResult(); var razorFiles = appHost.VirtualFiles.GetAllMatchingFiles("*.cshtml"); RazorSsg.PrerenderAsync(appHost, razorFiles, distDir).GetAwaiter().GetResult(); }); }); //... ``` -------------------------------- ### Vue Breadcrumbs Component Example Source: https://raw.githubusercontent.com/NetCoreTemplates/razor-press/refs/heads/main/MyApp/_pages/vue/navigation Illustrates the usage of the Vue Breadcrumbs component to display navigation paths. It supports a home link and nested breadcrumb items with optional href attributes. ```html gallery Navigation Examples ```