B4J Tutorial [BANano] Creating the PhotoNinja Website with UOE

Ola

Get Up and Running with UOE
PhotoNinja B4J Source Code

A couple of weeks ago I bumped into a You-tube Channel ran by The Net Ninja
Whilst the internet is so full of stuff, this was one of those joys, a multitude of videos on how to learn about stuff.

I found a course on the Materialize framework, bookmarked it and enjoyed watching what it all contained. Fortunately, as an inclusion of the course outline a website for the Photo Ninja was also included. So I said I will fire UOE one day and perhaps re-create the website. UOE after-all was birthed due to a client needing a materialize based website. I'm glad that I did it because where one needs a more complex webapp, I can just fire up UOEBANano and code with my eyes closed. Either way, this can be done in exactly the same fashion as our UOEBanano library, with a little modifications.

The contents of UOE based websites are static and not dynamic. Where one needs dynamic content, I would suggest one to use UOEBanano. If you are new to UOE, there is a link above named Get Up and Running with UOE to get you started.


Credits:
melodyloops - background music
ActivePresentor - desktop video recording
The Net Ninja - materialize course & content
B4J - Anywhere Software

PS: The source code for the website is herein attached including V115 of UOE.

Enjoy. Ta!
 
Last edited:

Mashiane

Expert
Licensed User
Longtime User
My pgIndex...

The initialize method just sets up a few things about the page. We want all the content to fit the page, this turning off CenterOnPage ensures that the page content is not a 'container'

B4X:
'initialize the page
Public Sub Initialize(pApp As UOEApp) As pgIndex
    'define the app the page belongs to
    App = pApp
    'the page name, this should be unique for every page
    PageName = "index"
    'the title on the top nav bar
    NavBarTitle = "Photo Ninja"
    'the page title
    PageTitle = "Photo Ninja"
    'the position of the logo
    NavBarLogoPosition = App.EnumLogoPosition.Center
    'if true the navbar does not move
    NavBarFixed = True
    'content will be padded to the center of the page
    CenterPageContent = False
    'if true the side bar will be fixed on the left and visible always
    FixSideBar = False
    'if true the page will show a loader
    HasLoader = False
    'set the NavBarTheme, we want a transparent background
    NavBarTheme = "none.transparent"
    'initialize the page
    Page.Initialize(App,PageName,NavBarTitle,NavBarLogoPosition,NavBarFixed,NavBarTheme,CenterPageContent,FixSideBar,HasLoader,"")
    'add animations in sequence of animation if necessary, you can comment this out
    'Page.AddAnimation("hello","bounceInDown")
    'make the page to self refernce
    Page.AddResources
    Return Me
End Sub

we give the page a title, set the navbar to be centered on the page, we want the navbar to have a transparent background, then we indicate so and then addresources to the page. AddResources ensures that only the needed css and javascript files are loaded to the page.
 

Mashiane

Expert
Licensed User
Longtime User
On Page create...

we have some resources that we have sitting in File.DirAssets, we need to copy these to the output folder, also add some of the themes we will use in the app.

B4X:
'copy dirassets to ouput folder
    Page.AddImageFile(File.DirAssets,"city.jpg")
    Page.AddImageFile(File.DirAssets,"man.jpg")
    Page.AddImageFile(File.DirAssets,"nature.jpg")
    Page.AddImageFile(File.DirAssets,"portrait.jpg")
    Page.AddImageFile(File.DirAssets,"stars.jpg")
    Page.AddImageFile(File.DirAssets,"street.jpg")
    
    '***** THEMES
    'add a theme for the headings
    App.AddTheme("indigo.darken4", App.EnumColor.INDIGO,App.EnumIntensity.DARKEN4,"","")
    App.AddTheme("indigo.darken4back", "","",App.EnumColor.INDIGO,App.EnumIntensity.DARKEN4)
    App.AddTheme("grey.darken3", "","",App.EnumColor.GREY, App.EnumIntensity.DARKEN3)
    App.AddTheme("grey.darken4", "","",App.EnumColor.GREY, App.EnumIntensity.DARKEN4)
    App.AddTheme("grey.lighten3",App.EnumColor.GREY,App.EnumIntensity.LIGHTEN3,"","")
    App.AddTheme("white.indigo",App.EnumColor.white,"",App.EnumColor.indigo,"")
    
    
    '***** CSS
    Page.InjectCSS("@media screen and (max-width: 670px) { header { min-height: 500px !important;} }")
    Page.InjectCSS(".tabs .indicator { background-color: #1a237e; }")
    Page.InjectCSS(".section { padding-top: 4vw; padding-bottom: 4vw; }")

We inject some css to the page because we need.
1. The background of the header should be sized properly on small devices i.e. shrink.
2. The tabs indicator is usually reddish, let's fix that to be indigo.
3. For all our sections, lets put some padding for the top and bottom so that there is some space inbetween the sections and other content...
 

Mashiane

Expert
Licensed User
Longtime User
Still creating the page...

We want the header of the page to have a background image, lets add the image... we will use some css to do so. We can also use .AddStyleAttribute method in UOE to do so too for inline CSS.

B4X:
'lets set the image of the header to fit page
    'lets create a header class
    Dim hcss As UOECSS
    hcss.Initialize
    hcss.BackGround.Image = "../images/man.jpg"
    hcss.BackGround.size = "cover"
    hcss.BackGround.position = "center"
    hcss.Height.minheight = "1000px"
    hcss.Important = False
    Page.AddCSS(".hdr",hcss)
    
    '***** HEADER
    'lets add the header class to the header
    Page.Header.AddClass("hdr")   
    'ensure that image resizes on small devices

On the navbar we have some buttons on the right side and also have a side bar with some buttons. The sidebar only appears when the device is small including the menu bar. The contents of the navbar should be inside a container too thus CenterInPage = true.

B4X:
'**** TOP NAV BUTTONS
    'enclose inside a container
    Page.NavBar.CenterInPage = True
    Page.NavBar.ShowMenuOnLarge = False
    'hide right buttons on medium and down devices
    Page.NavBar.RightMenuVisibility = App.EnumVisibility.HideOnMedAndDown
    'add buttons to right of navbar
    Page.NavBar.AddItemRight("tn_photo","#photos","Photos","",False,"")
    Page.NavBar.AddItemRight("tn_services","#services","Services","",False,"")
    Page.NavBar.AddItemRight("tn_contact","#contact","Contact","",False,"")
    
    Page.AddToolTip1("tn_instagram", "Instagram")
    Page.AddToolTip1("tn_facebook", "Facebook")
    Page.AddToolTip1("tn_twitter", "Twitter")
    
    Page.NavBar.AddFloatingButtonRight("tn_instagram", "fab fa-instagram", "#","indigo.darken4back","",False,"")
    Page.NavBar.AddFloatingButtonRight("tn_facebook", "fab fa-facebook", "#", "indigo.darken4back","",False,"")
    Page.NavBar.AddFloatingButtonRight("tn_twitter", "fab fa-twitter", "#", "indigo.darken4back", "",False,"")
    '*****  SIDE BAR
    'add a sidebar / drawer, specify the with
    'add the userview
    'Page.NavBar.Drawer.AddUserView("My Company.","[email protected]","images/tgif.png","images/background.png")
    Page.Navbar.Drawer.AddItem("sb_photo","","Photos","#photos",True,"","",False,"")
    Page.Navbar.Drawer.AddItem("sb_services","","Services","#services",True,"","",False,"")
    Page.Navbar.Drawer.AddItem("sb_contact","","Contact","#contact",True,"","",False,"")

We also want the right navigation buttons to be hidden on medium and small devices, we also set that. The buttons on the right need to have tooltips, we also add those. Each top nav button and side button is linked to the sections of the page via the links, e.g. "#photos", thus there are not any added event listeners for the website.
 

Mashiane

Expert
Licensed User
Longtime User
The Photos Section

The photos section has some photos and content using LeromIpsum. I borrowed some inspiration from the Cuppy Framework's data and strings modules I must say. As I wanted to be as close to The Net Ninja's code, he uses some column push and pull functionality, I added some functions to UOE to do this.

B4X:
#Region Photos
Sub PhotosSection
    'lets create a container, center in page makes it a container
    Dim Photos As UOEContainer
    Photos.Initialize(Page, "photos", True,"")
    'make it a section tag
    Photos.Section = True
    'scroll to the container when url is clicked
    Photos.Scrollspy = True
    Photos.AddClass("section")
    'add row
    'add a single row with 2 columns.
    'first column to be 12 for small and medium and 4 for large
    'second column to be 12 for small and medium and 6 for large with an offset of 1 on large
    'R1
    Photos.AddRows(1,"","")
    'R1C1
    Photos.AddColumns(1,12,4,4,"","")
    Photos.AddImage1(1,1,"","images/portrait.jpg","",False,"",True,False,True,True,"","","","")
    'R1C2
    Photos.AddColumnsOS(1,0,0,2,12,8,6,"","").PushColumn(1,2,1,1,1)
    Photos.AddH2(1,2,"","Portraits","indigo.darken4","")
    Photos.AddParagraph(1,2,"",Page.LoremIpsumRandom(4),"","")
    'add another row
    'R2
    Photos.AddRows(1,"","")
    'R2C1
    Photos.AddColumnsOS(1,0,0,1,12,12,4,"","").PushColumn(2,1,0,0,7)
    Photos.AddImage1(2,1,"","images/city.jpg","",False,"",True,False,True,True,"","","","")
    'R2C2
    Photos.AddColumnsOS(1,0,0,1,12,12,6,"","").PullColumn(2,2,0,0,5).RightAlignColumn(2,2)
    Photos.AddH2(2,2,"","Cityscapes","indigo.darken4","")
    Photos.AddParagraph(2,2,"",Page.LoremIpsumRandom(4),"","")
    'R3
    Photos.AddRows(1,"","")
    'R3C1
    Photos.AddColumns(1,12,6,4,"","")
    Photos.AddImage1(3,1,"","images/nature.jpg","",False,"",True,False,True,True,"","","","")
    'R3C2
    Photos.AddColumnsOS(1,0,0,2,12,6,6,"","").PushColumn(3,2,1,1,1)
    Photos.AddH2(3,2,"","Nature","indigo.darken4","")
    Photos.AddParagraph(3,2,"",Page.LoremIpsumRandom(4),"","")
    'add the container to the page content outside the page grid
    Page.Content.AddContainer(0,0,Photos)
End Sub
#End Region

I have found out that working with Containers is rather very easy to do and manageable, as long as one breaks the tasks into small chunks. The images are responsive and materializeboxed (on click fill the screen). The container has scrollspy turned on so that when called, the website scrolls to the content. we add some rows to the container grid, add some headings, images and paragraphs. For the images there are some instances where the RCs are pulled and some pushed.

I made a choice to break the code as much as possible because everything is built when Page.Create is called. This means I can make the code as readable as I need. As we are not using a grid on the age itself, all the content is added to R0C0 of the page i.e. directly to the page existing content in sequence.
 

Mashiane

Expert
Licensed User
Longtime User
The Parallax Sections...

There are two sections within the page that showcase parallaxes. There wasnt much to do there except add the parallax to the page content..

B4X:
#Region Street
Sub StreetSection
    Page.Content.AddParallax1(0,0,"streetx","images/street.jpg",True,"")
End Sub
#End Region

B4X:
#Region Stars
Sub StarsSection
    Page.Content.AddParallax1(0,0,"stars","images/stars.jpg",True,"")
End Sub
#End Region
 

Mashiane

Expert
Licensed User
Longtime User
The Services Section

B4X:
#Region Services
Sub ServicesSection
    Dim serv As UOEContainer
    serv.Initialize(Page,"services",True,"")
    serv.Section = True
    serv.Scrollspy = True
    serv.AddClass("section")
    'R1
    serv.AddRows(1,"","")
    'R1C1
    serv.AddColumns(1,12,12,4,"","")
    serv.Addh2(1,1,"","What I Do..","indigo.darken4","")
    serv.AddParagraph(1,1,"", Page.LoremIpsumRandom(4),"","")
    'R1C2
    serv.AddColumnsOS(1,0,0,2,12,12,6,"","")
    'create a tab
    Dim servicetabs As UOETabs
    servicetabs.Initialize(Page,"servicetabs",False,True,"","")
    servicetabs.AddTab("photography","Photography",True,False,6,6,6,Photography,"indigo.darken4")
    servicetabs.AddTab("editing","Editing",False,False,6,6,6,Editing,"indigo.darken4")
    serv.AddTabs(1,2,servicetabs)
    Page.Content.AddContainer(0,0,serv)
End Sub
#End Region

The services section of the site is split into two. One section talks about "What I Do..." and the other section is about Photography and Editing tabs. Whilst the one section is simple, the other is rather complex. We have a Tab with two sections. The easiest way to add content to any tab is using a container. So for the photography and editing sections, we create containers that are injected.

B4X:
#Region Photography
Sub Photography As UOEContainer
    Dim pc As UOEContainer
    pc.Initialize(Page,"",False,"")
    pc.AddParagraph(0,0,"","Photography","indigo.darken4", "flow-text")
    pc.AddParagraph(0,0,"", Page.LoremIpsumRandom(4),"","")
    Return pc
End Sub
#End Region

#Region Editing
Sub Editing As UOEContainer
    Dim ec As UOEContainer
    ec.Initialize(Page,"",False,"")
    ec.AddParagraph(0,0,"","Editing","indigo.darken4", "flow-text")
    ec.AddParagraph(0,0,"", Page.LoremIpsumRandom(4),"","")
    Return ec
End Sub
#End Region

Also within these containers, we add content directly to the container without creating a grid inside at R0C0.
 

Mashiane

Expert
Licensed User
Longtime User
Doing the footer.

The footer has its own section and also a copyrights section in it. We apply a theme to the footer and also add some RCs to place content. The footer is split into two sections, one to show About Me and the other to show social links.

B4X:
#Region Footer
Sub FooterSection
    'apply the theme
    Page.Footer.Theme = "grey.darken3"
    Page.Footer.CenterInPage = True
    'R1
    Page.Footer.AddRows(1,"","")
    'R1C1
    Page.Footer.AddColumns(1,12,12,6,"","")
    Page.Footer.AddH5(1,1,"","About Me","","")
    Page.Footer.AddParagraph(1,1,"", Page.LoremIpsumRandom(4),"","")
    
    'add another column
    'R1C2
    Page.Footer.addcolumnsos(1,0,0,0,12,12,5,"","").PushColumn(1,2,0,0,1)
    Page.Footer.AddH5(1,2,"","Connect","","white-text")
    
    Dim lst As UOEList
    lst.Initialize(Page,"",False,False)
    lst.AddLink("","Facebook","#","grey.lighten3",False,"")
    lst.AddLink("","Twitter","#","grey.lighten3",False,"")
    lst.AddLink("","Linked In","#","grey.lighten3",False,"")
    lst.AddLink("","Instragram","#","grey.lighten3",False,"")
    Page.Footer.AddList(1,2,lst)
    
    Page.CopyRights.Theme = "grey.darken4"
    Page.CopyRights.AddClass("center-align")
End Sub
#End Region

You might have noted that within this code, you didnt see anything about the content of the copyrights. This is because, this content seldom changes and thus is taken to the App.Initialization section of the website in the Main Module. Let's take a look..

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    '***** WEBSITE PROPERTIES
    App.Initialize("photoninja","com.mashy.photoninja","1","http://www.website.com","")
    App.Email = "[email protected]"
    App.Copyrights = "2018, All Rights Reserved, powered by UOE"
    App.Description = "photo ninja website created with UOE"
    App.AppShortName = "photoninja"
    App.Author = "Anele Mbanga"
    App.BackgroundColor = App.EnumCOLOR.WHITE
    App.ThemeColor = "aliceblue"
    App.Display = App.EnumDisplayType.fullscreen
    App.Language = "en-US"
    App.Orientation = App.EnumOrientation.portrait_primary
    'your twitter has tag, optional
    App.TwitterHashTag = "@anelembanga"
    'do not cache pages using cache.manifest
    App.Cache = False
    'do not prefetch the pages
    App.UsePrefetch = False
    App.DisclaimerURL = ""
    App.FaceBookAppID = ""
    App.TermsAndConditionsURL = ""
    App.PrivacyPolicyURL = ""
    
    'specify the leaflet key
    App.MapBoxAccessToken = "LEAFLET"
    App.GoogleMapsKey = "GOOGLEMAPSKEY"
    
    '***** ADD PAGES
    'add the index page
    Dim pIndex As pgIndex
    pIndex.Initialize(App).Create
    
    
    'add other pages here
    
    '***** CREATE WEBSITE
    'build the app, the output will be written on a folder with the app name
    'in the objects folder
    App.Create

    '***** PUBLISH WEBSITE
    'publish the website to any folder of your choice
    wait for (App.Publish("C:\xampp\htdocs")) Complete (result As Boolean)
    
    '***** OPEN WEBSITE
    'if you have XAMPP installed, will open browser to 127.0.0.1/APPNAme
    App.Open
    'close the app as it has built the website
    ExitApplication
End Sub

From here, the website specs is being defined and also the only page we have pgIndex is initialized and added. One can create multiple pages and then initialize and add them to the complete project here. After all the pages are added, App.Create is executed and then the content is copied to a xamp folder. You can publish to any path you want. App.Open opens the xamp website folder. You can use App.OpenLocal to open the Objects folder content saved. Publishing to Xamp is again optional however for me its easy to test most things about the website in a real server environment.

The contents of the website will sit on your projects folder Objects\photoninja in this case.

That's all folks.
 
Top