Razor Component vs Razor Page - razor

In the menu of visual studio, there are two options, Razor Component, and Razor Page, If one adds #page directive on the top of the razor component, it has its own address.
So what is the difference between them in practice?

Introduction
When you start a dotnet web app, you can choose between several types of apps, among them, mvc, webapp and Blazor:
dani#localhost ~ $ dotnet new
Templates Short Name Language Tags
-------------------------------------------- ------------------- ------------ ----------------------
Razor Page page [C#] Web/ASP.NET
...
Blazor Server App blazorserver [C#] Web/Blazor
Blazor WebAssembly App blazorwasm [C#] Web/Blazor/WebAssembly
...
ASP.NET Core Web App (Model-View-Controller) mvc [C#], F# Web/MVC
ASP.NET Core Web App webapp [C#] Web/MVC/Razor Pages
...
If you create a webapp you can see razor pages:
dani#localhost pp2 $ tree
.
├── appsettings.Development.json
├── appsettings.json
├── obj
│   ├── ...
├── Pages
│   ├── Error.cshtml <-- Razor Page
│   ├── Error.cshtml.cs <-- Razor Page
│   ├── Index.cshtml
│   ├── Index.cshtml.cs
│   ├── Privacy.cshtml
│   ├── Privacy.cshtml.cs
│   ├── Shared
│   │   ├── _Layout.cshtml
│   │   └── _ValidationScriptsPartial.cshtml
│   ├── _ViewImports.cshtml
│   └── _ViewStart.cshtml
├── ...
Quoting Introduction to Razor Pages in ASP.NET Core:
Razor Pages can make coding page-focused scenarios easier and more productive than using controllers and views.
As you can see on tree structure, a razor page is a cshtml file (template) plus a cs file (behavior). The page is rendered as html and send to navigator.
Exists another kind of apps, blazor. Quoting Introduction to ASP.NET Core Blazor:
Blazor is a framework for building interactive client-side web UI with .NET
Important term "interactive", not only render html, is a language to make page interactive (no just render html on server and send it to client)
Razor Component vs Razor Page
Razor page is typically to generate an html page on server and send to client on a ASP.NET Core Web App
Razor component ("Blazor Component") is a component for a Blazor app (can run in Blazor Server App and also in Blazor WebAssembly App) intended for interactive usage.
Notes
Check Henk's answer below, the term "Razor Component" has no logic, in Henk's opinion (and mine) should be "Blazor Component" because it runs only on Blazor apps.
Razor components vendors named this components as "Blazor Components" : https://www.syncfusion.com/blazor-components , https://www.telerik.com/blazor-ui, ...
Notice that when you add #page directive to a Blazor component it becomes enroutable (like a "blazor page"), but it is still a component.
You can add both Razor Components ("Blazor Components") and Razor pages to a webapp: Using Blazor Components In An Existing MVC Application by Chris Sainty.

Razor Component is the illogical template name for a Blazor Component, in a .razor file.
A Blazor Page is a Blazor Component (.razor) that has a #page "/..." directive.
Note that the icons are correct. Just go for the purple Bl#zor thing.

Related

Why is my image specified by img src not shown on my webpage?

I'm setting up pages on my personal website(hugo academics by wowchemy) and here is the structure of one of the folders I have:
.
├── ABF.md
├── EXE.md
├── Figures
│ ├── sampling.gif
│ └── sampling_compressed.gif
├── HREMD.md
├── MetaD.md
├── REUS.md
├── TREMD.md
├── US.md
├── _index.md
├── alchemical_MetaD.md
├── appendix.md
├── intro.md
└── test.gif
In _index.md, I have the following lines to read in a GIF file:
<center>
<img src="Figures/sampling_compressed.gif">
</center>
In intro.md, which is in the same folder as _index.md, I also have the same lines to read in the same GIF file. However, in localhost, the GIF file is shown in the page made by _index.md, but not the one built by intro.md. How can I solve the problem and why is this happening? Thanks in advance!
Your assumptions about the output structure are wrong. Hugo builds _index.md in the root of you folder, while the intro.md file (when processed with pretty URL's) is built in a subfolder: intro/index.html.
That being said... I tested your setup and an image in a Section directory (which is a directory with an _index.md file) is not processed by default. I would solve this by moving the image to the static directory so you can reference it from any file in the same way (with an absolute path), especially because this image does not belong to just one page.
If it WERE to be used by just one page, you could have turned the intro.md into intro/index.md and make that directory a Page bundle in which you could put your image and reference it by using the resources variable.

How does the browser resolve the relative location of './'?

I am combining many small semi-static, single-page webapps into one larger web site. The backend is a lot of proxies, but the forward facing server basically just make it look like the app was moved from the root filepath to a more specifics one. IE:
/
├── css
│   └── app1.css
├── index.html
└── js
└── app1.js
would be moved to
/apps/app1/
├── css
│   └── app1.css
├── index.html
└── js
└── app1.js
This migration has been relatively painless mainly due to the use of ./ in the apps' html files, such that most apps just load their resources relative to their new location. The problem I am having is that some apps are resolving ./ differently. For these trouble cases, the primary html file gets loaded; however, the ./ in the script and style elements are resolving to a higher file-path (IE: I would expect ./ to resolve to /apps/app1 but am getting /apps). It may be a coincidence, but the troubled apps often have additional, non-index HTML files.
What are the rules for how ./ is resolved?
Determine the base URL
This is usually the URL of the HTML document
It might be overridden by the base element
For CSS it is the URL of the stylesheet
JS is always with respect to the HTML document
Remove everything after the last / in the path section of the URL
e.g. the base URL for https://example.com/example/foo?bar=baz#fragment is https://example.com/example/
Keep in mind that an HTML document might be visible at the path /example and /example/ and you should avoid this by making one path canonical (I prefer the one that ends in a /) and redirecting to it from the other
Strip the ./ from the front of the relative path
Append the result of step 3 to the result of step 2
A common gotcha is to confuse URLs with file paths. While a simple static site will usually have a direct 1:1 mapping between them, many modern sites will use routing code (e.g. for Express for HTML documents and a separate static route for static files like images, js and css.

I cannot deploy static site to Netlify

I am trying to deploy some ui components on Netlify. However, it is not recognizing my index.html files inside the subfolders. Hence nothing is showing up on my deployed site. Also, all 3 index files have links to each other. This is my file structure
├── ui-components
├── blog-cards
│ └── index.html
├── login
│ └── index.html
├── ads-manager
│ └── index.html
Do I have to delete my subfolders and bring out my index files for it to deploy on Netlify or is there any way around it?
Edit:
I made some progress by doing this instead by putting a _redirects file in the root of my app as suggested
/ /blog-cards/index.html 200
/login /login/index.html 200
/ads-manager /ads-manager/index.html 200
It's finding my index.html inside the blog-cards folder however it's not loading my css file now. Full folder structure
├── ui-components
├── blog-cards
│ └── index.html
│ └── style.css
│ └── images
Here's a link to the netlify site
You don't have a main index.html file, which is why nothing is showing up on your deployed site. You should add something there, even just a blank page or a placeholder with links to the other projects.
You probably don't have to though, just browse to <siteurl>/ui-components/blog-cards and that should work.
Update after further comments.
If there is a subfolder you want the site to automatically go to upon landing, then you can use Redirects.
For example, putting the below in a file called _redirects in the root of your app will do what I think you need:
/ /ui-components/blog-cards 200
/login /ui-components/login 200
/ads /ui-components/ads-manager 200
(the 200 status code means that it will be a redirect under-the-hood, which makes the URL stay clean as you have said.)
Update
Yeah, so the forwarding is making the .css files to fail to load.
<link rel="stylesheet" href="style.css"> will look at the current URL and add style.css to it, which is obviously not what you want.
You could change to forwarding it with a 302, which would mean the new (not nice) URL would show up, but then the css path would resolve correctly.
Alternatively, you could add a second stylesheet link that looks for ./blog-cards/style.css.
Or if the css is small enough you could inline it, making it all simpler.

Vue // How to point to assets folder from js method?

I have a vue project generated by vue-cli v3 and I'm trying to provide custom markers for markerclustererplus v3, but it won't work!
I've placed "m" folder containing all m{1-5}.png images and provided imagePath option to MarkerClusterer imagePath: "/assets/m/m" but all I get is icon representing failed image loading. Icons have a path that seems to be correct, http://localhost:8080/assets/m/m2.png
So far I've tried to move "m" folder to public and components folder, but it doesn't work either. It also doesn't help if I open http://localhost:8080/assets/m folder or files in it from the browser address bar. I also do not see any images at the source tab of the browser.
UPDATE:
According to markerclustererplus documentation imagePath property is a string which is:
The full URL of the root name of the group of image files to use for cluster icons. The complete file name is of the form imagePathn.imageExtension where n is the image file number (1, 2, etc.). The default value is MarkerClusterer.IMAGE_PATH.
So I can't just use require('/folder_path/'), because I'm not calling exact .png that is needed for certain Cluster type and I can't pass Array of images to imagePath property, because it's a string.
Here's my src directory tree:
.
├── App.vue
├── api.js
├── assets
│   ├── logo.png
│   └── m
│   ├── m1.png
│   ├── m2.png
│   ├── m3.png
│   ├── m4.png
│   └── m5.png
├── components
│   ├── google-map.vue
│   └── side-bar.vue
├── dummyData.js
└── main.js
I'm passing imagePath: "/assets/m/m" option to MarkerClusterer in google-map.vue file, it results in <img src="/assets/m/m2.png"> element in browser.
To refer file from assets folder use #. Your image path, should look like this:
<img src="#/assets/m/m2.png">
The way that worked for me is to put the images in a folder in the /public directory, then set the imagePath to that folder. So you'd have:
public
map-cluster-images
m1.png
m2.png
m3.png
.....
And then when you initiate the MarkerClusterer:
imagePath: '/map-cluster-images/m'

HTML import: CustomTag not registered

I'm trying to create a custom element from polymer-element, but I cannot make the #CustomTag work. My dart file (my_element.dart) looks like this:
#HtmlImport('my_element.html')
library projects.projectFolder.layout;
import 'package:polymer/polymer.dart';
import 'dart:html';
#CustomTag('my-element')
class MyElement extends PolymerElement {
#published String caption;
MyElement.created() : super.created();
}
My html file (my_element.html) looks like this:
<link rel="import" href="../../../../packages/polymer/polymer.html">
<polymer-element name="my-element">
<template>
<link rel="stylesheet" href="my_element.css">
<core-toolbar>
<h1>{{ caption }}</h1>
</core-toolbar>
</template>
<script type="application/dart" src="../my_element.dart"></script>
</polymer-element>
The thing is that the Chrome console keeps on printing the following error:
No elements registered in a while, but still waiting on 1 elements to be registered. Check that you have a class with an #CustomTag annotation for each of the following tags: 'my-element'.
It's curious, because I have declared the custom tag as it should be. It looks like it hasn't read the .dart file when it reaches the .html.
The .html file is called from another parent .html file. I think that the order in which the files are called could be the problem, but then again if Dart is compiled before running, it shouldn't care.
I have tried several solutions but none of them have worked. The only one that worked is pretty dirty one, which is importing the my_element.dart file straight from the main my_app.dart file. I guess it shouldn't be done that way because that would mean to import every single my_element.dart file in the same main my_app.dart.
EDIT (add index.html, pubspec.yml)
My index.html file looks like following:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<title>My app</title>
</head>
<body unresolved fullbleed>
<my-app></my-app>
<script type="application/dart">
import 'package:polymer/polymer.dart';
import 'package:project/my_app.dart';
main() => initPolymer();
</script>
</body>
</html>
my_app is another custom element, which is the main element where all the others go. In other words, it is like the main controller for the app. This element has a .dart and .html file as well, which will call other elements like my-element.
As you can see, my main() function is very simple, since it only init Polymer (see index.html).
My pubspec.yml looks like following:
name: project
version: 0.0.1
description: Some project.
author: Tomas
homepage: https://github.com/*******
environment:
sdk: '>=1.10.0 <2.0.0'
dependencies:
polymer: '^0.16.0'
core_elements: '^0.7.1'
paper_elements: '^0.7.1'
route_hierarchical: "^0.6.1"
transformers:
- polymer:
entry_points: web/index.html
- $dart2js:
$include: "**/*.polymer.bootstrap.dart"
My directory looks like this (I just show a fraction of it, the important one I hope):
.
├── README.md
├── build
│   └── web
│   ├── index.html
│   ├── index.html.polymer.bootstrap.dart.js
│   └── packages
├── lib
│   ├── my_app.dart
│   └── src
│   ├── elements
│   ├── layout
│   │   ├── my_element.css
│   │   ├── my_element.dart
│   │   └── my_element.html
│   ├── my_app.css
│   ├── my_app.html
│   └── modules
│   └── module.dart
│   ├── my_app.css
├── pubspec.lock
├── pubspec.yaml
└── web
│ ├── index.html
│ └── packages -> ../packages
│   ├── my_app.html
│   └── modules
│   └── module.dart
I hope that this edit doesn't confuse more than it should. I'm just looking to know which is the correct folder structure and import form of a Dart app.
In short terms: how should the tree look like when programming a big application in dart, and where should I do the imports? I have look at every documentation I could, including some tutorials, but all of them talk about very simple examples where the big part of the code is in the web folder, which I wouldn't want.
EDIT (summarize and rephrase, add my_app.html and my_app.dart)
In fewer words:
I've a custom element defined by my_element.html and my_element.dart (defined above in this answer) and I want to import it into another my_app element using only the html. I.e. not by importing my_element.dart in my_app.dart, but by only importing my_element.html using a link tag in my_app.html:
<link rel="import" href="../../../packages/polymer/polymer.html">
<link rel="import" href="layout/my_element.html">
<polymer-element name="my-app">
<template>
<core-scaffold id="scaffold">
<my-element tool flex></my-element>
<main fit></main>
</core-scaffold>
</template>
<script type="application/dart" src="../my_app.dart"></script>
</polymer-element>
my_app.dart:
#HtmlImport('src/my_app.html')
import 'package:polymer/polymer.dart';
import 'package:core_elements/core_scaffold.dart';
#CustomTag('my-app')
class MyApp extends PolymerElement {
MyApp.created() : super.created();
}
Shouldn't the <script type="application/dart" src="../my_element.dart"></script> be enough to tell the compiler to load that dart file for registering the element tag by following the transitive dependence defined by the html import?
You need to import all your custom component Dart classes in your my_app.dart. Typically you'd create a single Dart file to import, which would export each entry so that your my_app.dart stays clean.